我只想將一些jQuery方法映射到其正常的Javascript DOM方法;將jQuery轉換爲常規Javascript映射
例如
prev()
next()
before()
after()
如果您可以將jQuery/Javascript映射到類似的DOM操作方法,那將會非常好。
我只想將一些jQuery方法映射到其正常的Javascript DOM方法;將jQuery轉換爲常規Javascript映射
例如
prev()
next()
before()
after()
如果您可以將jQuery/Javascript映射到類似的DOM操作方法,那將會非常好。
這些jQuery方法都沒有在基於純DOM的JS中精確的1對1模擬。如果他們這樣做了,那麼jQuery就不需要實現自己的方法來完成這些任務。
您可以使用elem.previousSibling
和elem.nextSibling
獲取元素的上一個和下一個兄弟。例如,與此HTML結構:
<ul>
<li>First</li>
<li id="second">Second</li>
</ul>
你會使用這個JS:
var elem = document.getElementById("second");
var p = elem.previousSibling;
alert(p.nodeType);
在這種情況下,第二LI的前一個兄弟是不第一LI。相反,前面的兄弟是兩個LI標籤之間的空白空間。這樣做的目的是,除了實際的HTML元素外,您還可以操作文檔中的任何文本節點。 nextSibling
屬性的工作原理完全相同。
這在理論上很好,但在實際使用中它或多或少是一種痛苦,因爲你很少或從不真正需要操縱文檔中的空白。要解決問題,請通過檢查nodeType
的兄弟進行迭代。如果nodeType爲1,那麼它是一個文本節點,因此跳到下一個,直到找到其nodeType不是1的節點。
您可能會發現博客文章Finding HTML elements using Javascript nextSibling and previousSibling有幫助。只需避免使用擴展Object.prototype的技術 - 通過這樣做很容易打破對象上的對象循環。
至於before()
和after()
,DOM相當於insertBefore()
和insertBefore()
在您想要的目標之後的兄弟上運行。但是,您不能只是將一些HTML添加到這些內容中,並期望它能夠正常工作。相反,您必須手動創建每個元素,屬性和值作爲DOM節點,然後插入它們。例如:
var welcomingDiv;
function sayHi(){
welcomingDiv = document.createElement("div");
welcomingDiv.innerHTML = "Welcome, and be amazed!";
target = document.getElementById("a-tag-someplace");
document.body.insertBefore(welcomingDiv, target);
}
這會在任何標籤的ID爲「a-tag-someplace」之前將其插入到您的文檔中。即使這是一種欺騙,因爲innerHTML不是官方JS標準的一部分。如果你做得很好,你必須創建一個文本節點並將它附加到你新創建的DIV中。
簡而言之:jQuery讓生活變得更簡單。沒有一個很好的理由,不要重新發明輪子。
很好的答案。 +1 – Matt
prev() - previousSibling, its a property
next() - nextSibling, its a property
before() - insertBefore,
after() - There is no insertAfter method but we implement it using insertBefore
我相信它們實際上是$(node.previousSibling)et。人。是? – cwallenpoole
+1請注意,「之後」可以通過使用「insertBefore」(如上所述)或者在父元素上使用「appendChild」來實現,以便在最後一個同級之後添加內容。 – maerics
@cwallenpoole - 那是正確的。 – ShankarSangoli
以下是TreeWalker(play with it at jsbin.com)的JavaScript實現。
<html>
<head></head>
<body>
<script>
var NodeFilter = {
FILTER_ACCEPT: 1,
FILTER_REJECT: 2,
FILTER_SKIP: 3,
SHOW_ALL: -1,
SHOW_ELEMENT: 1,
SHOW_ATTRIBUTE: 2,
SHOW_TEXT: 4,
SHOW_CDATA_SECTION: 8,
SHOW_ENTITY_REFERENCE: 16,
SHOW_ENTITY: 32,
SHOW_PROCESSING_INSTRUCTIONS: 64,
SHOW_COMMENT: 128,
SHOW_DOCUMENT: 256,
SHOW_DOCUMENT_TYPE: 512,
SHOW_DOCUMENT_FRAGMENT: 1024,
SHOW_NOTATION: 2048
};
var TreeWalker = function (root, whatToShow, filter, expandEntityReferences) {
this.root = root;
this.whatToShow = whatToShow;
this.filter = filter;
this.expandEntityReferences = expandEntityReferences;
this.currentNode = root;
this.NodeFilter = NodeFilter;
};
TreeWalker.prototype.parentNode = function() {
var testNode = this.currentNode;
do {
if (
testNode !== this.root &&
testNode.parentNode &&
testNode.parentNode !== this.root
) {
testNode = testNode.parentNode;
} else {
return null;
}
} while (this._getFilteredStatus(testNode) !== this.NodeFilter.FILTER_ACCEPT);
(testNode) && (this.currentNode = testNode);
return testNode;
};
TreeWalker.prototype.firstChild = function() {
var testNode = this.currentNode.firstChild;
while(testNode) {
if(this._getFilteredStatus(testNode) === this.NodeFilter.FILTER_ACCEPT) {
break;
}
testNode = testNode.nextSibling;
}
(testNode) && (this.currentNode = testNode);
return testNode;
};
TreeWalker.prototype.lastChild = function() {
var testNode = this.currentNode.lastChild;
while (testNode) {
if(this._getFilteredStatus(testNode) === this.NodeFilter.FILTER_ACCEPT) {
break;
}
testNode = testNode.previousSibling;
}
(testNode) && (this.currentNode = testNode);
return testNode;
};
TreeWalker.prototype.nextNode = function() {
var testNode = this.currentNode;
while (testNode) {
if (testNode.childNodes.length !== 0) {
testNode = testNode.firstChild;
} else if (testNode.nextSibling) {
testNode = testNode.nextSibling;
} else {
while (testNode) {
if (testNode.parentNode && testNode.parentNode !== this.root) {
if (testNode.parentNode.nextSibling) {
testNode = testNode.parentNode.nextSibling;
break;
} else {
testNode = testNode.parentNode;
}
}
else return null;
}
}
if (testNode && this._getFilteredStatus(testNode) === this.NodeFilter.FILTER_ACCEPT) {
break;
}
}
(testNode) && (this.currentNode = testNode);
return testNode;
};
TreeWalker.prototype.previousNode = function() {
var testNode = this.currentNode;
while (testNode) {
if (testNode.previousSibling) {
testNode = testNode.previousSibling;
while (testNode.lastChild) {
testNode = testNode.lastChild;
}
}
else {
if (testNode.parentNode && testNode.parentNode !== this.root) {
testNode = testNode.parentNode;
}
else testNode = null;
}
if (testNode && this._getFilteredStatus(testNode) === this.NodeFilter.FILTER_ACCEPT) {
break;
}
}
(testNode) && (this.currentNode = testNode);
return testNode;
};
TreeWalker.prototype.nextSibling = function() {
var testNode = this.currentNode;
while(testNode) {
(testNode.nextSibling) && (testNode = testNode.nextSibling);
if(this._getFilteredStatus(testNode) === this.NodeFilter.FILTER_ACCEPT) {
break;
}
}
(testNode) && (this.currentNode = testNode);
return testNode;
};
TreeWalker.prototype.previousSibling = function() {
var testNode = this.currentNode;
while(testNode) {
(testNode.previousSibling) && (testNode = testNode.previousSibling);
if(this._getFilteredStatus(testNode) == this.NodeFilter.FILTER_ACCEPT) {
break;
}
}
(testNode) && (this.currentNode = testNode);
return testNode;
};
TreeWalker.prototype._getFilteredStatus = function (node) {
var mask = ({
/* ELEMENT_NODE */ 1: this.NodeFilter.SHOW_ELEMENT,
/* ATTRIBUTE_NODE */ 2: this.NodeFilter.SHOW_ATTRIBUTE,
/* TEXT_NODE */ 3: this.NodeFilter.SHOW_TEXT,
/* CDATA_SECTION_NODE */ 4: this.NodeFilter.SHOW_CDATA_SECTION,
/* ENTITY_REFERENCE_NODE */ 5: this.NodeFilter.SHOW_ENTITY_REFERENCE,
/* ENTITY_NODE */ 6: this.NodeFilter.SHOW_PROCESSING_INSTRUCTION,
/* PROCESSING_INSTRUCTION_NODE */ 7: this.NodeFilter.SHOW_PROCESSING_INSTRUCTION,
/* COMMENT_NODE */ 8: this.NodeFilter.SHOW_COMMENT,
/* DOCUMENT_NODE */ 9: this.NodeFilter.SHOW_DOCUMENT,
/* DOCUMENT_TYPE_NODE */ 10: this.NodeFilter.SHOW_DOCUMENT_TYPE,
/* DOCUMENT_FRAGMENT_NODE */ 11: this.NodeFilter.SHOW_DOCUMENT_FRAGMENT,
/* NOTATION_NODE */ 12: this.NodeFilter.SHOW_NOTATION
})[node.nodeType];
return (
(mask && (this.whatToShow & mask) == 0) ?
this.NodeFilter.FILTER_REJECT :
(this.filter && this.filter.acceptNode) ?
this.filter.acceptNode(node) :
this.NodeFilter.FILTER_ACCEPT
);
};
if (!document.createTreeWalker) {
document.createTreeWalker = function (root, whatToShow, filter, expandEntityReferences) {
return new TreeWalker(root, whatToShow, filter, expandEntityReferences);
};
}
window.onload = function() {
var walker = document.createTreeWalker(document.getElementById('rootNodeDiv'), NodeFilter.SHOW_ELEMENT, null, false);
alert('currentNode: ' + walker.currentNode.id + ': firstChild: ' + walker.firstChild().id);
alert('currentNode: ' + walker.currentNode.id + ': nextNode: ' + walker.nextNode().id);
alert('currentNode: ' + walker.currentNode.id + ': lastChild: ' + walker.lastChild().id);
alert('currentNode: ' + walker.currentNode.id + ': parentNode: ' + walker.parentNode().id);
alert('currentNode: ' + walker.currentNode.id + ': previousNode: ' + walker.previousNode().id);
alert('currentNode: ' + walker.currentNode.id + ': nextSibling: ' + walker.nextSibling().id);
alert('currentNode: ' + walker.currentNode.id + ': previousSibling: ' + walker.previousSibling().id);
};
</script>
<div id="parentNodeDiv">
<div id="rootNodeDiv">
<span id="previousNodeDiv"></span>
<span id="span01">
<p id="span01p01"> </p>
<p id="span01p02"> </p>
</span>
<span id="span02"></span>
<span id="span03">
<p id="span02p01"> </p>
</span>
<span id="span04"></span>
<span id="span05"></span>
</div>
</div>
</body>
你爲什麼不只是看jQuery的來源? – jondavidjohn
(其來源是https://github.com/jquery/jquery/blob/master/src/transing。js,但是它的確是一個大腦彎曲者,並且其聲明仍然堅定地「jQuery」,通過本地DOM方法)。 – Matt
完整功能中的方法?例如。 'prev'和'next'帶選擇器... –