
Originally Posted by
shachi
Object.prototype.pSib = function(){
while(this.previousSibling.nodeType == 3){
var node = this.previousSibling;
}
return node;
}
You don't actually attempt to walk the document tree. You just make the same comparison over and over again. Text nodes aren't necessarily the only non-Element node that might encounter.
If you're looking for Element nodes, look for them explicitly. Below is a set of traversal methods. The second argument to methods like getFirstChild and getPreviousSibling is a function object reference. This function is called to examine the node (the first, and only, argument to that function) and return a boolean indicating whether it's acceptable.
Code:
var Tools = function () {
return {
createElementCallback: function (tagName) {
return function (node) {
return isElement(node, tagName);
};
},
getFirstChild: function (parent, test) {
var node = parent.firstChild;
if (node) return test(node) ? node : this.getNextSibling(node, test);
return null;
},
getLastChild: function (parent, test) {
var node = parent.lastChild;
if (node) return test(node) ? node : this.getPreviousSibling(node, test);
return null;
},
getNextSibling: function (node, test) {
while ((node = node.nextSibling))
if (test(node)) return node;
return null;
},
getPreviousSibling: function (node, test) {
while ((node = node.previousSibling))
if (test(node)) return node;
return null;
},
isElement: isElement
};
function isElement(node, tagName) {
return (node.nodeType == 1)
&& (tagName ? (node.nodeName == tagName) : (node.nodeName != '!'));
}
}();
For example,
Code:
Tools.getFirstChild(parent, function (node) {
return (Tools.isElement(node) &&
((node.nodeName == 'UL') || (node.nodeName == 'OL')));
});
will return the first list (ordered or unordered) element, skipping any other nodes (including uninteresting elements). If there is no such element, the return value will be null.
The createElementCallback method simplifies looking for a particular "type" of element. For example,
Code:
var isAnchor = Tools.createElementCallback('A');
Tools.getNextSibling(element, isAnchor);
will return the first anchor (a) element that follows element, or null.
Note that the tag names are case-sensitive (and will be upper-case in HTML/pseudo-XHTML).

Originally Posted by
DimX
It goes into an infinite loop, because you don't remove the text node, so it runs on the same text node all the time.
Removing the text node is a possible approach, but only if removing the text node is sensible. It might not always be, so it cannot be a general solution.

Originally Posted by
Twey
Ouch. Never modify the Object, man.
Never? If it solves a particular problem properly, then do it. However, it's surely inappropriate, here.

Originally Posted by
shachi
I didn't get it, how could a method truly belong to a class?
If a method can apply to all instances of a "class" (there are no classes as such in ECMAScript) then one can consider it to "belong". However, it doesn't, here: a RegExp object doesn't have a nextSibling property, does it?
Are you trying to modify the prototype object of DOM nodes? That's not going to work in all browsers. Not all of them even have prototype objects for host objects.
Mike
Bookmarks