Почему проблемы с .innerHTML не являются проблемой при использовании jQuery().html()?

#javascript #jquery #wordpress #innerhtml

#javascript #jquery #wordpress #innerhtml

Вопрос:

Я разработал любой отдельный экземпляр document.getElementById("MyID").innerHTML = "A value" в этом руководстве по Javascript World Clock, из-за которого администратор WordPress не загружается полностью и нарушает работу различных областей интерфейса администратора WordPress.

Я решил это, заменив каждый экземпляр на jQuery("#MyID").html("A value")) , который, похоже, работает нормально. Что вызывает .innerHTML с треском провал, но не JQuery().html() ?

Комментарии:

1. Я не думаю, что это так, если я правильно помню, они оба сбрасывают DOM.

Ответ №1:

На мой взгляд, я бы заподозрил, что либо что-то специфичное для браузера, либо document.getElementById("MyID") возвращает null, вызывая исключение.

Комментарии:

1. Если document.getElementByID("MyID") возвращает null, то jQuery("#MyID") должен быть возвращен пустой объект jQuery, поэтому .html() вызов ничего не сделает.

2. @justkt бездействие отличается от выдачи исключения, если после вызова что-то произошло.

3. верно, но вопрос, похоже, указывает на то, что DOM изменен .html() .

4. @justkt «решил это, заменив каждый экземпляр» подразумевает, что один или несколько из них, возможно, были сломаны, хотя это и не ясно.

5. Нет, я не видел никаких ошибок в исходном .innerHTML коде. На самом деле у меня есть всего три тактовых сигнала с идентичным синтаксисом, не считая значений, которые я передал функциям. Ошибки были устранены только тогда, когда я закомментировал все ссылки на innerHTML .

Ответ №2:

Вероятно, это соответствующая часть исходного кода jQuery:

 try {
    for ( var i = 0, l = this.length; i < l; i   ) {
        // Remove element nodes and prevent memory leaks
        if ( this[i].nodeType === 1 ) {
            jQuery.cleanData( this[i].getElementsByTagName("*") );
            this[i].innerHTML = value;
        }
    }

    // If using innerHTML throws an exception, use the fallback method
} catch(e) {
    this.empty().append( value );
}
  

Обратите внимание, что он обрабатывает возникающие исключения.

Убедитесь в этом сами в 1.5.2.

Комментарии:

1. Я отмечаю это как мой принятый ответ. Это не значит, что я точно знаю, почему это работает, но его clear jQuery выполняет более тщательную работу по проверке ошибок.

Ответ №3:

Вот как jQuery это делает:

 html: function( value ) {
    if ( value === undefined ) {
        return this[0] amp;amp; this[0].nodeType === 1 ?
            this[0].innerHTML.replace(rinlinejQuery, "") :
            null;

    // See if we can take a shortcut and just use innerHTML
    } else if ( typeof value === "string" amp;amp; !rnocache.test( value ) amp;amp;
        (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) amp;amp;
        !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {

        value = value.replace(rxhtmlTag, "<$1></$2>");

        try {
            for ( var i = 0, l = this.length; i < l; i   ) {
                // Remove element nodes and prevent memory leaks
                if ( this[i].nodeType === 1 ) {
                    jQuery.cleanData( this[i].getElementsByTagName("*") );
                    this[i].innerHTML = value;
                }
            }

        // If using innerHTML throws an exception, use the fallback method
        } catch(e) {
            this.empty().append( value );
        }

    } else if ( jQuery.isFunction( value ) ) {
        this.each(function(i){
            var self = jQuery( this );

            self.html( value.call(this, i, self.html()) );
        });

    } else {
        this.empty().append( value );
    }

    return this;
},
  

Комментарии:

1. И как сброс исходного кода для html() метода отвечает на вопрос?

2. Извините, но я согласен с @BoltClock, это просто указывает мне на то, что я уже использую. Вам пришлось бы объяснить, почему это работает, чтобы ответить на мой вопрос.

3.@edwinbradford: Я не понимаю, как это не может быть полезным. Вам интересно, почему html() работает, а innerHTML="" почему нет. То, что я опубликовал выше, — это именно то, как jQuery выполняет свой html метод. Если вы не можете понять, почему это работает так, как оно работает, вам также не следовало отмечать другое сообщение, которое показывает (только часть), что делает метод.

4. Я думаю, это потому, что в другом ответе отмечается, как jQuery перехватывает исключения, и если да, то использует запасной вариант. Он также показывает только часть кода, относящуюся к объяснению.

5. Спасибо, Джон, ответ Джона очень хорошо резюмирует мои рассуждения. Также спасибо вам @Shaz за отправку ответа.

Ответ №4:

Пожалуй, единственное различие между тем, что вы пробовали, и тем, что мог бы делать html-метод jQuery, заключается в удалении содержимого элемента перед вставкой нового содержимого. Поэтому попробуйте сначала удалить содержимое, и если вы вставляете только обычный текст, создайте и вставьте текстовый узел вместо установки innerHTML.

Итак:

 function replaceContent(id, s) {
  var el = document.getElementById(id);
  if (el) {
    while (el.firstChild) {
      el.removeChild(el.firstChild);
    }
    el.appendChild(document.createTextNode(s));
  }
}
  

Комментарии:

1. Да, я задавался вопросом об этом. Элемент, на который ссылались, был пуст, я попытался изменить его с a <div> на a <span> , а также попробовал <p> на случай, если он предпочитает текстовые элементы, но это не имело никакого значения.