jQuery для обычного отображения Javascript - PullRequest
3 голосов
/ 08 августа 2011

Мне бы просто хотелось сопоставить некоторые методы jQuery с их обычными методами DOM Javascript;

например.

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

Было бы здорово, если бы вы могли обеспечить отображение jQuery / Javascript на аналогичные методы манипуляции DOM.

Ответы [ 3 ]

4 голосов
/ 08 августа 2011

Ни один из этих методов jQuery не имеет точного 1-к-1 аналога в простом JS на основе DOM.Если бы они это сделали, 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 - not первый LI.Вместо этого предыдущий брат - пустой пробел между двумя тегами LI.Это было сделано для того, чтобы вы могли манипулировать любым текстовым узлом в документе в дополнение к фактическим элементам HTML.Свойство nextSibling работает идентично.

Это хорошо в теории, но это более или менее болезненно при фактическом использовании, потому что вам редко или никогда не понадобится манипулировать пробелами в документе,Чтобы обойти, переберите братьев и сестер, проверяя nodeType.Если nodeType равен 1, то это текстовый узел, поэтому переходите к следующему, пока не найдете тот, у которого nodeType не равен 1.

Вы можете найти сообщение в блоге Поиск элементов HTML с помощью Javascript nextSiblingа предыдущий брат полезен.Просто избегайте технику расширения Object.prototype, которую он использует - очень просто разбить for/in петли на объекты, делая это.

Что касается 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);
}

Это вставит его в ваш документ прямо перед тем тегом, у которого есть идентификатор "a-tag-someplace".Даже это своего рода обман, так как innerHTML не является частью официального стандарта JS.Если вы делаете это правильно, вам нужно будет создать текстовый узел и добавить его в только что созданный DIV.

Итак, вкратце: jQuery делает жизнь намного проще.Не изобретайте велосипед без уважительной причины.

3 голосов
/ 08 августа 2011
prev() - previousSibling, its a property
next() - nextSibling, its a property
before() - insertBefore,
after() - There is no insertAfter method but we implement it using insertBefore
0 голосов
/ 08 августа 2011

Ниже приведена реализация JavaScript TreeWalker (поиграйте с ним на 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">&nbsp;</p>
                <p id="span01p02">&nbsp;</p>
            </span>
            <span id="span02"></span>
            <span id="span03">
                <p id="span02p01">&nbsp;</p>
            </span>
            <span id="span04"></span>
            <span id="span05"></span>
        </div>
    </div>
</body>

...