Подтвердить что ты не робот

JQuery html() в Firefox (использует .innerHTML) игнорирует изменения DOM

Я действительно удивлен, что раньше не сталкивался с этой проблемой, но кажется, что вызов функции jQueries.html() для элемента игнорирует изменения в DOM, то есть возвращает HTML в исходном источнике. IE не делает этого. jQueries.html() просто использует свойство innerHTML внутри.

Это должно произойти? Я на Firefox 3.5.2. У меня есть образец ниже, где независимо от того, что вы меняете значение текстового поля, innerHTML элемента "container" только когда-либо возвращает значение, определенное в разметке HTML. Образец не использует jQuery только для упрощения (результат тот же, что и при использовании jQuery).

Есть ли у кого-нибудь работа, где я могу получить html контейнера в его текущем состоянии, то есть включая любые сценарии изменений в DOM?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <script type="text/javascript">
            <!--
            function BodyLoad(){                
                document.getElementById("textbox").value = "initial UPDATE";
                DisplayTextBoxValue();
            }

            function DisplayTextBoxValue(){
                alert(document.getElementById("container").innerHTML);             
                return false;
            }
            //-->
        </script>
    </head>
    <body onload="BodyLoad();">
        <div id="container">
            <input type="text" id="textbox" value="initial" />
        </div>
        <input type="button" id="button" value="Test me" onclick="return DisplayTextBoxValue();" />
    </body>
</html>
4b9b3361

Ответ 1

Firefox не обновляет атрибут value объекта DOM на основе пользовательского ввода, просто его свойство value - существует довольно быстрая работа.

DOM:

function DisplayTextBoxValue(){
  var element = document.getElementById('textbox');
  // set the attribute on the DOM Element by hand - will update the innerHTML
  element.setAttribute('value', element.value);
  alert(document.getElementById("container").innerHTML);             
  return false;
}

Плагин jQuery, который делает .formhtml() автоматически:

(function($) {
  var oldHTML = $.fn.html;

  $.fn.formhtml = function() {
    if (arguments.length) return oldHTML.apply(this,arguments);
    $("input,button", this).each(function() {
      this.setAttribute('value',this.value);
    });
    $("textarea", this).each(function() {
      // updated - thanks Raja & Dr. Fred!
      $(this).text(this.value);
    });
    $("input:radio,input:checkbox", this).each(function() {
      // im not really even sure you need to do this for "checked"
      // but what the heck, better safe than sorry
      if (this.checked) this.setAttribute('checked', 'checked');
      else this.removeAttribute('checked');
    });
    $("option", this).each(function() {
      // also not sure, but, better safe...
      if (this.selected) this.setAttribute('selected', 'selected');
      else this.removeAttribute('selected');
    });
    return oldHTML.apply(this);
  };

  //optional to override real .html() if you want
  // $.fn.html = $.fn.formhtml;
})(jQuery);

Ответ 2

Это известная проблема в Firefox. Спецификации для innerHTML не совсем понятны, поэтому разные разработчики браузеров реализуют это по-другому.

Обсуждение этой темы можно найти здесь:

http://forums.mozillazine.org/viewtopic.php?t=317838#1744233

Ответ 3

Спасибо за ваш плагин formhtml. Чтобы использовать его с textarea, мне пришлось его обновить:

$("textarea", this).each(function() { 
  $(this).text($(this).val()); 
});

Ответ 4

Я знаю, что ваш вопрос относится к innerHTML, но если это всего лишь значение textbox внутри container, которое вам нужно, тогда

$('#textbox').val()

даст правильное (обновленное) значение текстового поля.

Ответ 5

Также другой подход DOM должен установить defaultValue для конкретного элемента - заимствования того же кода из проголосовавшего ответа.

function DisplayTextBoxValue(){
  var element = document.getElementById('textbox');
  element.defaultValue = element.value;    
  alert(document.getElementById("container").innerHTML);             
  return false;
}

Это должно печатать обновленный innerHTML.

Решение jQuery лучше, поскольку оно прикрепляется ко всем входным элементам, а не к определенному элементу. Это может быть сделано с помощью только "DOM only", будет включать итерацию DOM для обнаружения всех входных элементов и добавления вызовов метода onChange для всех входных элементов. Если вы не знаете полей, которые будут на странице hte.

Ответ 6

Эта функция обновления работала только по полям ввода, которые не были изменены вручную. Добавлена ​​указанная строка для обновления видимого текста ввода:

  // set text input value from the associated sel dropdown and reset dropdown
  function set_input_value(eid, sel) {
      var el = document.getElementById(eid);
      el.setAttribute("value", sel.options[sel.selectedIndex].text);

      // added this line to solve the issue:
      el.value = el.getAttribute('value');

      sel.selectedIndex=0;
  }