2009-01-06 20 views
50

Ho un elemento HTML con una grande raccolta di liste non ordinate contenute al suo interno. Ho bisogno di clonare questo elemento per posizionarlo altrove sulla pagina con diversi stili aggiunti (questo è abbastanza semplice usando jQuery).jQuery duplicati ID duplicati

$("#MainConfig").clone(false).appendTo($("#smallConfig")); 

Il problema, tuttavia, è che tutte le liste e le loro voci di elenco associati dispongono di ID e clone loro duplicati. C'è un modo semplice per sostituire tutti questi ID duplicati usando jQuery prima di aggiungerli?

+4

@ Adamo Naylor Essere smarmy non è utile. –

risposta

38

Se avete bisogno di un modo per fare riferimento alle voci di elenco dopo averli clonato, è necessario utilizzare le classi, non gli ID. Cambia tutto id = "..." in class = "..."

Se si ha a che fare con codice legacy o qualcosa del genere e non è possibile modificare gli ID in classi, è necessario rimuovere gli attributi id prima di accodare.

$("#MainConfig").clone(false).find("*").removeAttr("id").appendTo($("#smallConfig")); 

Basta essere consapevoli che non si dispone di un modo per fare riferimento a più singoli elementi.

+1

Qualcosa di simile non può essere ottenuto ma sostituire gli id? – Sheff

+1

Quindi è necessario tenere traccia di come sono stati modificati gli ID (ad es. Prefisso, suffisso) e utilizzare la concatenazione di stringhe per ricostruire gli id ​​corretti quando si fa riferimento agli elementi clonati. Fastidioso. Usa solo le classi. –

+0

Clona e cambia ID: "http://stackoverflow.com/questions/10126395/how-to-jquery-clone-and-change-id" –

14
$("#MainConfig") 
    .clone(false) 
    .find("ul,li") 
    .removeAttr("id") 
    .appendTo($("#smallConfig")); 

Provalo per la taglia. :)

[Modifica] Risolto per il commento di redsquare.

+0

Rimuoverei l'id prima di eseguire l'append altrimenti la tua duplicazione degli id ​​nel dom ancora che potrebbe avere effetti sgradevoli – redsquare

+0

Questo è essenzialmente ciò che Salty sta facendo nel suo esempio, penso. Lo farò, ma preferirei usare una ricerca globale per tutti i bambini nel caso in cui il markup cambi e altri elementi all'interno del genitore vengano ingannati – Sheff

+0

Nessun problema. Grazie per aver capito il mio errore =] – Salty

0

Se avrete diverse oggetti simili su una pagina, è meglio utilizzare le classi, non IDS. In questo modo puoi applicare gli stili a uls all'interno di diversi id contenitore.

5

Io uso qualcosa del genere: $ ("# dettagli"). Clone() .attr ('id', 'details_clone'). After ("h1"). Show();

+3

Oh anche più breve: 'var i = $ ('# itemBase') ; i.clone (true) .attr ('id', 'item' + nextItemId ++) .removeClass ('hidden'). addClass ('item'). insertAfter (i); ' – dlamblin

18

Dal momento che l'OP ha chiesto un modo per sostituire tutti i id duplicati di prima di loro aggiungendo, forse qualcosa di simile potrebbe funzionare. Supponendo che si voleva clonare MainConfig_1 in un blocco HTML come questo:

<div id="smallConfig"> 
    <div id="MainConfig_1"> 
     <ul> 
      <li id="red_1">red</li> 
      <li id="blue_1">blue</li> 
     </ul> 
    </div> 
</div> 

Il codice potrebbe essere qualcosa di simile a quanto segue, per trovare tutti gli elementi figli (discendenti) del blocco clonato, e modificare il proprio ID di utilizzare un contatore:

var cur_num = 1; // Counter used previously. 
//... 
var cloned = $("#MainConfig_" + cur_num).clone(true, true).get(0); 
++cur_num; 
cloned.id = "MainConfig_" + cur_num;     // Change the div itself. 
$(cloned).find("*").each(function(index, element) { // And all inner elements. 
    if(element.id) 
    { 
     var matches = element.id.match(/(.+)_\d+/); 
     if(matches && matches.length >= 2)   // Captures start at [1]. 
      element.id = matches[1] + "_" + cur_num; 
    } 
}); 
$(cloned).appendTo($("#smallConfig")); 

di creare nuovi HTML come questo:

<div id="smallConfig"> 
    <div id="MainConfig_1"> 
     <ul> 
      <li id="red_1">red</li> 
      <li id="blue_1">blue</li> 
     </ul> 
    </div> 
    <div id="MainConfig_2"> 
     <ul> 
      <li id="red_2">red</li> 
      <li id="blue_2">blue</li> 
     </ul> 
    </div> 
</div> 
3

questo si basa sulla risposta di Russell, ma un po 'più estetico e funzionale per le forme. jQuery:

$(document).ready(function(){ 
    var cur_num = 1; // Counter 

    $('#btnClone').click(function(){ 

      var whatToClone = $("#MainConfig"); 
      var whereToPutIt = $("#smallConfig"); 

      var cloned = whatToClone.clone(true, true).get(0); 
      ++cur_num; 
      cloned.id = whatToClone.attr('id') + "_" + cur_num;     // Change the div itself. 

     $(cloned).find("*").each(function(index, element) { // And all inner elements. 
      if(element.id) 
      { 
       var matches = element.id.match(/(.+)_\d+/); 
       if(matches && matches.length >= 2)   // Captures start at [1]. 
        element.id = matches[1] + "_" + cur_num; 
      } 
      if(element.name) 
      { 
       var matches = element.name.match(/(.+)_\d+/); 
       if(matches && matches.length >= 2)   // Captures start at [1]. 
        element.name = matches[1] + "_" + cur_num; 
      } 

     }); 

     $(cloned).appendTo(whereToPutIt); 

    }); 
}); 

Il Markup:

<div id="smallConfig"> 
    <div id="MainConfig"> 
     <ul> 
      <li id="red_1">red</li> 
      <li id="blue_1">blue</li> 
     </ul> 
     <input id="purple" type="text" value="I'm a text box" name="textboxIsaid_1" /> 
    </div> 
</div> 
2

FWIW, ho usato la funzione di Dario, ma aveva bisogno di prendere le etichette di forma pure.

Aggiungi un altro se dichiarazione come questa per farlo:

if(element.htmlFor){ 
var matches = element.htmlFor.match(/(.+)_\d+/); 
if(matches && matches.length >= 2)   // Captures start at [1]. 
    element.htmlFor = matches[1] + "_" + cur_num; 
} 
0

Credo che questo sia il modo migliore

var $clone = $("#MainConfig").clone(false); 
$clone.removeAttr('id'); // remove id="MainConfig" 
$clone.find('[id]').removeAttr('id'); // remove all other id attributes 
$clone.appendTo($("#smallConfig")); // add to DOM.