2010-01-19 13 views
21

Este SSCCE lo dice todo:nombre Cambio de attr elemento de entrada clonado en jQuery no funciona en 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, haga clic en el botón varias veces Add . En cada clic que debe ver el código HTML de la <ul> a aparecer en el <pre id="showsource"> y el código esperado debería ser aproximadamente:

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

Esto funciona como se esperaba en FF, Chrome, Safari, Opera y IE8.

Sin embargo, Internet Explorer 6/7 fracasa en cambiar el atributo name y produce productos similares:

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

I googled un poco y encontró this very similar problem, lo arregló y publicó un fragmento de código como debe tener apariencia similares. Desafortunadamente esto es exactamente lo que ya hice, así que sospecho que solo estaba probando en IE8, no en IE6/7. Aparte de ese tema en particular, Google no reveló mucho.

¿Algún conocimiento? ¿O realmente tengo que volver al document.createElement?

Nota: Sé que puedo usar el mismo nombre para cada elemento de entrada y recuperarlos como una matriz, pero lo anterior es solo un ejemplo básico, en realidad necesito cambiar el nombre del atributo, porque no solo contiene el índice, sino también otra información como parentindex, pedidos, etc. Se ha usado para agregar/reorganizar/eliminar elementos (sub) del menú.

Editar: esto está relacionado con this bug, no parece lo tanto, el jQuery (estoy usando 1.3.2) para crear entradas de esa manera? El siguiente no sólo el trabajo:

$('#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()); 
}); 

Pero no puedo imaginar que yo soy el único que se encontró con este problema con jQuery. Incluso un simple $('<input>').attr('name', 'foo') no funciona en IE6/7. ¿No se supone que jQuery es una biblioteca de navegador cruzado que cubre este tema en particular bajo los capós?

+1

Me encontré con el mismo problema y pude encontrar una solución: http://stackoverflow.com/questions/2773308/jquery-clone-problem – jantimon

Respuesta

2
no

una respuesta, es un análisis a la pregunta:

<!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> 

Resultado:

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

así que puede analizarlo, la única manera es hacer una nueva li con createElement o crear el objeto con $ (...)

3

Me pregunto si se está ejecutando en this bug in IE (incluso con jQuery)?

Básicamente en IE no puede cambiar el atributo de nombre de los elementos (regular o clonado) (y luego volver a acceder a ellos mediante javascript por nombre) aunque puede enviarlos (por ejemplo, elementos de entrada) y enviarlos correctamente.

+1

Gracias por el enlace (+1). Tienes razón de que se enviaron, pero mi primer SSCCE enviaba los parámetros como 'foo [0]', 'foo [1]', 'foo [1]', 'foo [1]', ... Así , solo uno de '0' y múltiplo de' 1' (para clones de clones). Sin embargo, puedo reescribir el código para que solo clone el original, pero también ** necesito ** para poder volver a acceder a ellos después de agregarlos, ya que pueden estar involucrados en otras acciones de jQuery posteriormente (como reorganizar y clasificar). – BalusC

4

creé una solución parcial a este problema, que describo aquí: http://www.danconnor.com/dynamic-name-input-attributes-with-ie-and-jquery-clones.html

Básicamente:

$(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); 
}); 

Definitivamente chupa pero definitivamente las obras.

+0

Después de usar esta solución por un tiempo, he encontrado que no es confiable en diferentes versiones de IE. En cambio, recomiendo usar el truco mergeAttributes; ver mi respuesta a continuación. – phatmann

1

sé que esto es viejo, pero ya casi no lo encuentro nada que trabajó para mí hice una solución bastante simple, sin embargo, uno feo: html

convertir en texto usando jQuery, luego usar js cuerdas funciones para hacer lo que quiera con él e inserte la cadena como html usando jquery.

sólo para cualquiera que todavía se encuentra con esto, como yo :)

9

Aquí es una función que va a establecer el nombre de un elemento en todos los navegadores, incluso IE6 y IE7. Está adaptado del código en http://matts411.com/post/setting_the_name_attribute_in_ie_dom.

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

Encontré que el uso de replaceElement y outerHTML no era confiable en las diferentes versiones de IE. ¡Pero el truco mergeAttributes arriba funciona a la perfección!

+0

Esto funcionó para mí. – Omar

+0

Esto funcionó para mí también, en una función que convierte un campo de texto en una matriz de campos de texto concatenando una cadena envuelta entre corchetes, como esta: Antes: Después: En un contexto similar, necesito cambiar el atributo de id de los campos ¿Funcionará de esta manera? –

+0

No sé si cambiar la identificación tiene los mismos problemas o no. ¡Por favor déjanos saber! – phatmann

Cuestiones relacionadas