Recommendations for Working Around IE9 Treewalker Filter Bug
Background Info
A bug exists currently in IE9 where it thinks that the NodeFilter
property of the createTreeWalker
method is a callback function instead of an object containing a callback function.
In a call like this:
document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, filter, false);
filter
is defined as "an object that contains a method acceptNode
," in Webkit and Gecko; however, in IE9, there's no mention of acceptNode at all--it expects a "callback method," without that object wrapping.
Actual Question
So, what's the best way to work around this issue without doing explicit browser detection? In some instances I need filter
to be a method, and in others I need it to be an object containing the method. Is there a clean way to accomplish this? All of these browsers claim to support DOM 2.0, so I can't test on that...
Documents - Proof of Bug
Here's a开发者_如何学JAVA comparison of the documentation for each:
- W3C Spec
- Gecko
- Webkit
- Microsoft ("The NodeFilter is a callback function..." - WRONG)
Well, I came up with one thing that works. Open to better alternatives:
var filter = { acceptNode: function() {
//do filtering...
} };
// Hackzilla. A true W3C-compliant nodeFilter object isn't passed, and instead a "safe" one _based_ off of the real one.
var safeFilter = filter.acceptNode;
safeFilter.acceptNode = filter.acceptNode;
document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, safeFilter, false);
This works as nice browsers will call .acceptNode
on the filter object, where bad ones will try and execute it immediately.
Alternatives?
Actually IE 9 does follow the spec. Read the ECMAScript bindings section of the DOM spec:
Object NodeFilter
This is an ECMAScript function reference. This method returns a Number. The parameter is a Node object.
Therefore conforming browsers (which includes current versions of all the major ones) will all accept a function as the filter
parameter.
精彩评论