2010-01-19 4 views
21

Diese SSCCE sagt alles:Ändern Namen attr geklonter Eingabeelement in jQuery funktioniert nicht in IE6/7

<!doctype html> 
<html lang="en"> 
    <head> 
     <title>Test</title> 
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
     <script type="text/javascript"> 
      $(document).ready(function() { 
       $('#add').click(function() { 
        var ul = $('#ul'); 
        var liclone = ul.find('li:last').clone(true); 
        var input = liclone.find('input'); 
        input.attr('name', input.attr('name').replace(/(foo\[)(\d+)(\])/, function(f, p1, p2, p3) { 
         return p1 + (parseInt(p2) + 1) + p3; 
        })); 
        liclone.appendTo(ul); 
        $('#showsource').text(ul.html()); 
       }); 
      }); 
     </script> 
    </head> 
    <body> 
     <ul id="ul"> 
      <li><input type="text" name="foo[0]"></li> 
     </ul> 
     <button id="add">Add</button> 
     <pre id="showsource"></pre> 
    </body> 
</html> 

Copy'n'paste'n'run es, klicken Sie auf die Add mehrmals Taste . Auf jedem Klick sollten Sie den HTML-Code der <ul> zu zeigen, bis in den <pre id="showsource"> und der erwarteten Code sollte etwa sein sehen:

<li><input name="foo[0]" type="text"></li> 
<li><input name="foo[1]" type="text"></li> 
<li><input name="foo[2]" type="text"></li> 
<li><input name="foo[3]" type="text"></li> 

Dies funktioniert wie in FF, Chrome, Safari, Opera und IE8 erwartet.

jedoch IE6/7 versagt bei der Veränderung der name Attribut und produziert wie:

<li><input name="foo[0]" type="text"> 
<li><input name="foo[0]" type="text"> 
<li><input name="foo[0]" type="text"> 
<li><input name="foo[0]" type="text"></li> 

ich googled ein wenig und fand this very similar problem, fixiert er es und veröffentlicht ein Code-Schnipsel, wie es aussehen sollte. Leider habe ich das schon gemacht, also vermute ich, dass er nur im IE8 getestet hat, nicht im IE6/7. Abgesehen von diesem speziellen Thema hat Google nicht viel verraten.

Irgendwelche Einsichten? Oder muss ich wirklich zurück zu document.createElement greifen?

Hinweis: Ich weiß, dass ich nur den gleichen Namen für jedes Eingabeelement verwenden und sie als ein Array abrufen kann, aber das obige ist nur ein einfaches Beispiel, in Wirklichkeit muss ich das Namensattribut ändern, weil Es enthält nicht nur den Index, sondern auch weitere Informationen wie Parentindex, Sortierung usw. Es wurde verwendet, um (Unter-) Menüpunkte hinzuzufügen/neu anzuordnen/zu entfernen.

Edit: dies this bug verwandt ist, die jQuery (Ich bin mit 1.3.2) scheint somit nicht Eingänge zu schaffen, die Art und Weise? Die folgende funktioniert einfach:

$('#add').click(function() { 
    var ul = $('#ul'); 
    var liclone = ul.find('li:last').clone(true); 
    var oldinput = liclone.find('input'); 
    var name = oldinput.attr('name').replace(/(foo\[)(\d+)(\])/, function(f, p1, p2, p3) { 
     return p1 + (parseInt(p2) + 1) + p3; 
    }); 
    var newinput = $('<input name="' + name + '">'); 
    oldinput.replaceWith(newinput); 
    liclone.appendTo(ul); 
    $('#showsource').text(ul.html()); 
}); 

Aber ich kann mir nicht vorstellen, dass ich der einzige bin, die dieses Problem mit jQuery begegnet. Selbst eine einfache $('<input>').attr('name', 'foo') funktioniert nicht in IE6/7. Ist jQuery nicht als eine Crossbrowser-Bibliothek gedacht, die dieses spezielle Thema unter den Hauben behandeln soll?

+1

Ich stieß auf das gleiche Problem und konnte eine Lösung finden: http://stackoverflow.com/questions/2773308/jquery-clone-problem – jantimon

Antwort

2

keine Antwort, ist eine Analyse auf die Frage gestellt:

<!doctype html> 
<html lang="en"> 
    <head> 
     <title>Test</title> 
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
     <script type="text/javascript"> 
      $(document).ready(function() { 
       $('#add').click(function() { 
        var ul = $('#ul'); 

        var liclone1 = ul.find('li:last').clone(true); 
        var liclone2 = ul.find('li:last')[0].cloneNode(true); 
        var liclone3 = $(ul.find('li:last')[0].cloneNode(true)); 
        var liclone4 = $('<li><input type="text" name="foo[88]"></li>'); 

        var linew = document.createElement("li"); 
        linew.innerHTML = '<input type="text" name="foo[99]">'; 

        $('#showsource').text(""); 
        $('#showsource').text($('#showsource').text() + $(liclone1)[0].outerHTML); 
        $('#showsource').text($('#showsource').text() + $(liclone2)[0].outerHTML); 
        $('#showsource').text($('#showsource').text() + $(liclone3)[0].outerHTML); 
        $('#showsource').text($('#showsource').text() + $(liclone4)[0].outerHTML); 
        $('#showsource').text($('#showsource').text() + $(linew)[0].outerHTML); 
        $('#showsource').text($('#showsource').text() + $(ul)[0].outerHTML); 
        $('#showsource').text($('#showsource').text() + $(ul)[0].innerHTML); 

       }); 
      }); 
     </script> 
    </head> 
    <body> 
     <ul id="ul"> 
      <li><input type="text" name="foo[0]"></li> 
      <li><input type="text" name="foo[1]"></li> 
     </ul> 
     <button id="add">Add</button> 
     <pre id="showsource"></pre> 
    </body> 
</html> 

Ergebnis:

<LI><INPUT name=foo[1]> 
<LI><INPUT name=foo[1]> 
<LI><INPUT name=foo[1]> 
<LI><INPUT name=foo[88]></LI> 
<LI><INPUT name=foo[99]></LI> 
<UL id=ul><LI><INPUT name=foo[0]> 

<LI><INPUT name=foo[1]> </LI></UL><LI><INPUT name=foo[0]> 
<LI><INPUT name=foo[1]> </LI> 

so kann ich es analysieren, der einzige Weg ist, einen neu li mit create zu machen oder Erstelle das Objekt mit $ (...)

3

Ich frage mich, ob Sie in this bug in IE laufen (sogar mit jQuery)?

Im Wesentlichen können Sie das Namensattribut von Elementen (regulär oder geklont) nicht ändern (und dann wieder über JavaScript per Name zugreifen), obwohl Sie sie (z. B. Eingabeelemente) übermitteln und sie erfolgreich übermitteln können.

+1

Danke für den Link (+1). Du hast Recht, dass sie eingereicht werden, aber mein erster SSCCE würde die Parameter als 'foo [0]', 'foo [1]', 'foo [1]', 'foo [1]', ... senden , nur eines von "0" und ein Vielfaches von "1" (für Klone von Klonen). Ich kann jedoch den Code so umschreiben, dass er nur das Original klont, aber ich brauche ** auch, um nach dem Hinzufügen wieder auf sie zugreifen zu können, da sie danach möglicherweise in andere jQuery-Aktionen involviert sind (wie Neuanordnen und Sortieren). – BalusC

4

habe ich eine Teillösung für dieses Problem, die ich hier beschreiben: http://www.danconnor.com/dynamic-name-input-attributes-with-ie-and-jquery-clones.html

Grundsätzlich gilt:

$(some_cloned_element).each(function(i, elem){ 
    var newName = "yay_i_love_my_new_name"; 
    if ($.browser.msie === true){ // evil browser sniffing *cries* 
     $(elem).replaceWith(document.createElement(
      this.outerHTML.replace(/name=\w+/ig, 'name='+newName+'_'+i) 
     )); 
    } else { 
     $(elem).attr('name',newName+'_'+i); 
    } 
    $("body").append(some_cloned_element); 
}); 

saugt jeden Fall aber auf jeden Fall funktioniert.

+0

Nachdem ich diese Lösung für eine Weile benutzt habe, habe ich festgestellt, dass sie in verschiedenen IE-Versionen unzuverlässig ist. Stattdessen empfehle ich, den mergeAttributes-Trick zu verwenden. Siehe meine Antwort unten. – phatmann

1

Ich weiß, das ist alt, aber da ich wirklich nichts finden didnt die für mich gearbeitet Ich habe eine ziemlich einfache Lösung, aber eine hässliche ein:

convert html in Text jquery verwenden, dann js Zeichenfolge verwenden Funktionen zu tun, wie Sie wollen mit ihm und fügen Sie die Zeichenfolge als HTML mit jquery.

nur für jeden, der nach wie vor über das kommt, wie ich :)

9

Hier ist eine Funktion, die den Namen eines Elements in allen Browsern, auch IE6 und IE7 eingestellt werden. Es ist aus dem Code unter http://matts411.com/post/setting_the_name_attribute_in_ie_dom angepasst.

function setElementName(elems, name) { 
    if ($.browser.msie === true){ 
    $(elems).each(function() { 
     this.mergeAttributes(document.createElement("<input name='" + name + "'/>"), false); 
    }); 
    } else { 
    $(elems).attr('name', name); 
    } 
} 

Ich fand, dass die Verwendung von replaceElement und outerHTML in verschiedenen IE-Versionen nicht zuverlässig war. Aber der mergeAttributes-Trick oben funktioniert perfekt!

+0

Das hat für mich funktioniert. – Omar

+0

Das funktionierte auch für mich bei einer Funktion, die ein Textfeld in ein Array von Textfeldern konvertiert, indem eine mit eckigen Klammern umschlossene Zeichenkette wie folgt verkettet wird: Vorher: Nachher: ​​ In einem ähnlichen Kontext muss ich die ändern ID-Attribut der Felder. Wird es so funktionieren? –

+0

Ich weiß nicht, ob die Änderung der ID die gleichen Probleme hat oder nicht. Informieren Sie uns bitte! – phatmann

Verwandte Themen