jQuery 到传统 Javascript 的映射

发布于 2024-11-28 20:57:47 字数 176 浏览 5 评论 0原文

我只想将一些 jQuery 方法映射到它们的普通 Javascript DOM 方法;

例如

prev()
next()
before()
after()

,如果您可以提供 jQuery/Javascript 到类似 DOM 操作方法的映射,那就太好了。

I would just like a mapping of some of the jQuery methods to their normal Javascript DOM methods;

e.g.

prev()
next()
before()
after()

It would be really great if you could provide mapping of jQuery/Javascript to similar DOM manipulation methods.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只有影子陪我不离不弃 2024-12-05 20:57:47

这些 jQuery 方法在基于 DOM 的 JS 中都没有精确的一对一模拟。如果他们这样做了,那么 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的节点。

您可以找到博客文章使用 Javascript nextSibling 和查找 HTML 元素previousSibling 有帮助。只要避免他使用的扩展 Object.prototype 的技术即可——这样做很容易打破对象的 for/in 循环。

至于 before()after(),DOM 等效项是 insertBefore()insertBefore() run在您想要的目标之后的兄弟姐妹上。但是,您不能只是将一些 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 让生活变得更加简单。没有充分的理由,不要重新发明轮子。

None of these jQuery methods have an exact 1-to-1 analogue in plain DOM-based JS. If they did, there would be no need for jQuery to implement its own methods to accomplish these tasks.

You can get previous and next siblings for an element using elem.previousSibling and elem.nextSibling. For example, with this HTML structure:

<ul>
    <li>First</li>
    <li id="second">Second</li>
</ul>

You'd use this JS:

var elem = document.getElementById("second");
var p = elem.previousSibling;
alert(p.nodeType);

In this case, the previous sibling of the second LI is not the first LI. Instead, the previous sibling is the empty white space between the two LI tags. This was done so that you can manipulate any text node in the document in addition to actual HTML elements. The nextSibling property works identically.

That's nice in theory, but it's more or less a pain in the neck in actual usage, because you rarely or never are actually going to need to manipulate the whitespace in a document. To work around, iterate through the siblings checking the nodeType. If the nodeType is 1, then it's a text node, so skip to the next one till you find one whose nodeType isn't 1.

You may find the blog post Finding HTML elements using Javascript nextSibling and previousSibling helpful. Just avoid the technique of extending Object.prototype he uses -- it's very easy to break for/in loops over objects by doing that.

As for before() and after(), the DOM equivalent is insertBefore() and insertBefore() run on the sibling AFTER the target you want. However, you can't just throw some HTML into those and expect it to work. Instead you have to manually create each element, attribute, and value as DOM nodes, and then insert them. For example:

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);
}

That will insert it into your document right before whatever tag has the ID "a-tag-someplace". Even this is kind of a cheat though, since innerHTML is not part of the official JS standard. IF you were doing it properly, you'd have to create a text node and append it to your newly created DIV.

So, in short: jQuery makes life a lot simpler. Don't reinvent the wheel without a really good reason.

眼趣 2024-12-05 20:57:47
prev() - previousSibling, its a property
next() - nextSibling, its a property
before() - insertBefore,
after() - There is no insertAfter method but we implement it using insertBefore
prev() - previousSibling, its a property
next() - nextSibling, its a property
before() - insertBefore,
after() - There is no insertAfter method but we implement it using insertBefore
红焚 2024-12-05 20:57:47

以下是 TreeWalker TreeWalker 的 JavaScript 实现com/abuqey/" rel="nofollow">(在 jsbin.com 上玩)。

<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>

The following is a JavaScript implementation of TreeWalker (play with it at jsbin.com).

<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>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文