Как обработать Firefox, вставляющий текстовые элементы между тегами

Я пытаюсь написать javascript для поиска элементов страницы относительно данного элемента, используя parentNode, firstChild, nextSibling, childNodes [] и так далее. Firefox портит это, вставляя текстовые узлы между каждым элементом html. Я читал, что могу победить это, удалив все пробелы между элементами, но я пробовал это, и это не работает. Есть ли способ написать код, который работает во всех современных браузерах?

Например:

<div id = "parent"><p id = "child">Hello world</p></div>

В IE parent.firstChild является дочерним элементом, но в Firefix - это фантомный текстовый элемент.

Я тестирую его на своем firefox 3.0.5 с firebug 1.2.1, и этого не происходит. какую версию вы используете?

Jader Dias 30.12.2008 01:11

но если я вставлю текст между тегами, то это произойдет

Jader Dias 30.12.2008 01:12

Я видел это раньше, но не могу вспомнить марку / версию браузера.

Ady 30.12.2008 01:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
1 841
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

вы можете использовать tagName, чтобы проверить имя тега. Если не определено, то это ваш «фантомный» текстовый узел.

например

function getFirstTag(node) {
  return ((node.firstChild.tagName) ? node.firstChild : node.firstChild.nextSibling);
}

Ответ принят как подходящий

У меня есть обходной путь. Вы можете вставить два метода ниже:

Element.prototype.fChild = function(){
    var firstChild = this.firstChild;
    while(firstChild != null && firstChild.nodeType === 3){
        firstChild = firstChild.nextSibling;
    }
    return firstChild;
 }
 Element.prototype.nSibling = function(){
    var nextSibling = this.nextSibling;
    while(nextSibling != null && nextSibling.nodeType === 3){
        nextSibling = nextSibling.nextSibling;
    }
    return nextSibling;
 }

и теперь вы можете использовать:

document.getElementById("parent").fChild();
document.getElementById("parent").nSibling();

вместо:

 document.getElementById("parent").firstChild;
 document.getElementById("parent").nextSibling;

К сожалению, в IE это развалится, разрушив всякую надежду на кроссплатформенное решение. Конечно, методы можно использовать как автономные функции.

Shog9 30.12.2008 02:04

Приложив немного усилий, мы можем заставить эти функции работать в любом браузере.

Jader Dias 30.12.2008 04:32

Тип узла должен быть 1, а не 3. 1 - для элемента, 2 или undefined - для атрибута, а 3 - для текстового узла.

David Brockman 30.12.2008 16:19

@David Brockman - Вы правы насчет значений чисел, но код правильный, потому что он избегает нежелательного nodeType (3).

Jader Dias 07.01.2009 22:30

Проверьте Ссылка на ядро ​​DOM уровня 2, чтобы увидеть различные возможные типы узлов, чтобы вы могли отфильтровать нежелательные с помощью простого фрагмента JavaScript. Одним из решений является исправление объекта обезьяной (см. Ответ Вернихта) или, если вам не нравится исправление обезьяны, вы можете добавить эти методы в свою собственную библиотеку, или еще лучшим решением может быть использование причудливой библиотеки, такой как jQuery или опытный образец.

Вы должны проверить, что nodeType == 1.

if (el.nodeType === 1) {
    return el;
}

Я написал для тебя небольшой класс обхода DOM (в основном скопированный с MooTools). Скачать здесь: http://gist.github.com/41440

DOM = function () {

    function get(id) {
        if (id && typeof id === 'string') {
            id = document.getElementById(id);
        }
        return id || null;
    }

    function walk(element, tag, walk, start, all) {
        var el = get(element)[start || walk], elements = all ? [] : null;
        while (el) {
            if (el.nodeType === 1 && (!tag || el.tagName.toLowerCase() === tag)) {
                if (!all) {
                    return el;
                }
                elements.push(el);
            }
            el = el[walk];
        }
        return elements;
    }

    return {

        // Get the element by its id
        get: get,

        walk: walk,

        // Returns the previousSibling of the Element (excluding text nodes).
        getPrevious: function (el, tag) {
            return walk(el, tag, 'previousSibling');
        },

        // Like getPrevious, but returns a collection of all the matched previousSiblings.
        getAllPrevious: function (el, tag) {
            return walk(el, tag, 'previousSibling', null, true);
        },

        // As getPrevious, but tries to find the nextSibling (excluding text nodes).
        getNext: function (el, tag) {
            return walk(el, tag, 'nextSibling');
        },

        // Like getNext, but returns a collection of all the matched nextSiblings.
        getAllNext: function (el, tag) {
            return walk(el, tag, 'nextSibling', null, true);
        },

        // Works as getPrevious, but tries to find the firstChild (excluding text nodes).
        getFirst: function (el, tag) {
            return walk(el, tag, 'nextSibling', 'firstChild');
        },

        // Works as getPrevious, but tries to find the lastChild.
        getLast: function (el, tag) {
            return walk(el, tag, 'previousSibling', 'lastChild');
        },

        // Works as getPrevious, but tries to find the parentNode.
        getParent: function (el, tag) {
            return walk(el, tag, 'parentNode');
        },

        // Like getParent, but returns a collection of all the matched parentNodes up the tree.
        getParents: function (el, tag) {
            return walk(el, tag, 'parentNode', null, true);
        },

        // Returns all the Element's children (excluding text nodes).
        getChildren: function (el, tag) {
            return walk(el, tag, 'nextSibling', 'firstChild', true);
        },

        // Removes the Element from the DOM.
        dispose: function (el) {
            el = get(el);
            return (el.parentNode) ? el.parentNode.removeChild(el) : el;
        }

    };
}();



// Now you can do:
DOM.getFirst("parent") // first child
// or
DOM.getFirst("parent", "p") // first p tag child
// or
var el = DOM.get("parent") // get element by id
DOM.getFirst(el) // first child

Другие вопросы по теме