2009-09-07 10 views
21

Jestem naprawdę zaskoczony, że wcześniej nie wpadłem na ten problem, ale wydaje się, że wywołanie funkcji jQueries .html() na elemencie ignoruje zmiany w DOM, tzn. Zwraca kod HTML z oryginalnego źródła. IE tego nie robi. jQueries. html() po prostu wewnętrznie korzysta z właściwości innerHTML.jQuery html() w Firefoksie (używa .innerHTML) ignoruje zmiany DOM

Czy to ma się stać? Jestem w Firefoksie 3.5.2. Mam próbkę poniżej, gdzie bez względu na to, co zmienisz wartość pola tekstowego, innerHTML elementu "container" zawsze zwraca wartość zdefiniowaną w znacznikach HTML. Próbka nie używa jQuery tylko po to, aby była prostsza (wynik jest taki sam przy użyciu jQuery).

Czy ktoś ma pracę, w której można uzyskać html kontenera w jego bieżącym stanie, tj. W tym wszelkie zmiany skryptu w 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> 

Odpowiedz

36

Firefox nie aktualizuje valueatrybut obiektu DOM na podstawie danych wprowadzonych przez użytkownika, tylko jego valuewłasności - ładna szybka praca wokół istnieje.

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 plugin, który sprawia .formhtml() automatycznie to zrobić:

(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); 
+0

Twój plugin działa dobrze dla wszystkich kontroli, ale to nie działa w FF textarea sam: - (.... Czy coś zmienić, aby to działało ? już dodano 1, ponieważ to bardzo mi pomogło :-) – Raja

+1

prostu musiałem zrobić subtelna zmiana $ ("textarea", this) .each (function() { \t \t this.innerHTML = this.value; \t }); a teraz działa. Dzięki za twoje rozwiązanie :-) – Raja

+0

@Raja - Dzięki za informację zwrotną - zaktualizowałeś kod! – gnarf

1

Znam twoje pytanie dotyczy innerHTML, ale jeśli to było tylko wartość textbox wewnątrz container że potrzebne, a następnie

poda poprawną (zaktualizowaną) wartość pola tekstowego.

2

Dzięki za wtyczkę formhtml. W celu wykorzystania go textarea, musiałem go aktualizować:

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

Użyłem odpowiedzi @ gnarf z tą regulacją, aby zachować wszystkie spacje w textarea (lub wystarczająco blisko ... $ this.text (this.value)) –

+0

Dzięki, Wish you'd zasugerowałbym edycję tutaj! Zmieniłem swoją odpowiedź, aby to uwzględnić. – gnarf

0

także inne podejście DOM jest ustawienie defaultValue od konkretnego elementu - zapożyczając ten sam kod z głosowało odpowiedź.

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

To powinno wydrukować zaktualizowany innerHTML.

Rozwiązanie jQuery jest lepsze, ponieważ dołącza się do wszystkich elementów wejściowych zamiast do konkretnego elementu. Można to zrobić również za pomocą "DOM only", będzie to wymagało iteracji DOM w celu wykrycia wszystkich elementów wejściowych i dodania wywołań metod do wszystkich elementów wejściowych. Jeśli nie znasz pól, które byłyby na stronie HTE.

0

Ta funkcja aktualizacji działa tylko w polach wejściowych, które nie zostały zmienione ręcznie. Dodany wskazana linia zaktualizować widocznego tekstu:

// 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; 
    } 
Powiązane problemy