2009-09-07 8 views
21

Je suis vraiment surpris que je n'ai pas rencontré ce problème auparavant, mais il semble que l'appel de la fonction jQueries .html() sur un élément ignore les changements dans le DOM, c'est-à-dire qu'il renvoie le code HTML dans la source d'origine. IE ne le fait pas. jQueries .html() utilise simplement la propriété innerHTML en interne.jQuery html() dans Firefox (utilise .innerHTML) ignore les changements DOM

Est-ce que cela est censé se produire? Je suis sur Firefox 3.5.2. J'ai un exemple ci-dessous, où peu importe ce que vous modifiez la valeur de la zone de texte, le innerHTML de l'élément "container" ne renvoie jamais que la valeur définie dans le balisage HTML. L'exemple n'utilise pas jQuery juste pour le rendre plus simple (le résultat est le même en utilisant jQuery).

Est-ce que quelqu'un a un travail autour de l'endroit où je peux obtenir le html d'un conteneur dans son état actuel, c'est-à-dire y compris les modifications scriptées au 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> 

Répondre

36

Firefox ne met pas à jour le valueattribut d'un objet DOM basé sur l'entrée d'utilisateur, juste son valuepropriété - jolie un travail rapide existe.

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; 
} 

plugin jQuery qui fait .formhtml() font automatiquement ceci:

(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

votre plugin fonctionne très bien pour tous les contrôles, mais il ne fonctionne pas pour Textarea seul FF: - (.... Avez-vous changé quoi que ce soit pour le faire fonctionner ? Ont déjà ajouté 1 puisque cela m'a beaucoup aidé :-) – Raja

+1

Juste eu à faire un changement subtil $ ("textarea", this) .each (function() { \t \t this.innerHTML = this.valeur; \t }); et maintenant ça marche. Merci pour votre solution :-) – Raja

+0

@Raja - Merci pour les commentaires - mis à jour le code! – gnarf

1

Je sais que votre question a trait à innerHTML, mais si elle était juste la valeur de textbox à l'intérieur container que vous nécessaire, puis

$('#textbox').val() 

donnera la bonne valeur (mise à jour) de la zone de texte.

2

Merci pour votre plugin formhtml. Pour l'utiliser avec textarea, je devais le mettre à jour:

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

J'ai utilisé la réponse de @ gnarf avec cet ajustement pour conserver tous les espaces dans textarea (ou assez proche ... $ this.text (this.value)) –

+0

Merci, vous auriez suggéré une modification ici! J'ai changé ma réponse pour l'incorporer. – gnarf

0

également une autre approche DOM est de mettre l'defaultValue sur l'élément spécifique - empruntant le même code de la réponse voté.

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

Cela devrait imprimer la mise à jour innerHTML.

La solution de jQuery est meilleure car elle s'attache à tous les éléments d'entrée au lieu d'un élément spécifique. Cela peut être fait en utilisant "DOM only" aussi, impliquera l'itération du DOM pour détecter tous les éléments d'entrée et en ajoutant les appels de méthode onChange sur tous les éléments d'entrée. Dans le cas où vous ne connaissez pas les champs qui seraient sur la page.

0

Cette fonction de mise à jour fonctionnait uniquement sur les champs de saisie qui n'avaient pas été modifiés à la main. Ajout de la ligne indiquée pour mettre à jour le texte d'entrée visible:

// 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; 
    } 
Questions connexes