дубликаты идентификаторов клонов jQuery - PullRequest
50 голосов
/ 06 января 2009

У меня есть элемент HTML с большой коллекцией неупорядоченных списков, содержащихся в нем. Мне нужно клонировать этот элемент для размещения в другом месте на странице с различными добавленными стилями (это достаточно просто с помощью jQuery).

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

Однако проблема в том, что все списки и связанные с ними элементы списка имеют идентификаторы, а clone дублирует их. Есть ли простой способ заменить все эти дубликаты ID с помощью jQuery перед добавлением?

Ответы [ 9 ]

38 голосов
/ 06 января 2009

Если вам нужен способ ссылки на элементы списка после того, как вы их клонировали, вы должны использовать классы, а не идентификаторы. Измените все id = "..." на class = "..."

Если вы имеете дело с устаревшим кодом или чем-то еще и не можете изменить идентификаторы на классы, вы должны удалить атрибуты идентификаторов перед добавлением.

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

Просто помните, что у вас больше нет возможности ссылаться на отдельные элементы.

18 голосов
/ 14 июня 2011

Поскольку ОП запросил способ заменить все дублирующиеся идентификаторы перед добавлением их, возможно, что-то подобное сработает. Предполагая, что вы хотите клонировать MainConfig_1 в HTML-блок, например:

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

Код может выглядеть примерно так, чтобы найти все дочерние элементы (и потомки) клонированного блока и изменить их идентификаторы с помощью счетчика:

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"));

Чтобы создать новый HTML, как это:

<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>
14 голосов
/ 06 января 2009
$("#MainConfig")
    .clone(false)
    .find("ul,li")
    .removeAttr("id")
    .appendTo($("#smallConfig"));

Попробуйте это для размера. :)

[Редактировать] Исправлено для комментария красного квадрата.

5 голосов
/ 20 августа 2009

Я использую что-то вроде этого: ... $ ( "#") Подробно клон () атр ( 'ID', 'details_clone') после того, как ( "h1") шоу ();.

3 голосов
/ 26 октября 2011

Это основано на ответе Рассела, но немного более эстетично и функционально для форм. 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 );

    });
});

Разметка:

<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 голосов
/ 05 февраля 2012

FWIW, я использовал функцию Дарио, но мне нужно было ловить и метки форм.

Добавьте еще одно выражение if, чтобы сделать это:

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 голосов
/ 10 мая 2019

Вот решение с идентификатором.

var clone = $("#MainConfig").clone();
clone.find('[id]').each(function () { this.id = 'new_'+this.id });
$('#smallConfig').append(clone);

если вы хотите динамически установить идентификатор, вы можете использовать счетчик вместо 'new _'.

0 голосов
/ 14 декабря 2015

Я считаю, что это лучший способ

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.
0 голосов
/ 06 января 2009

Если у вас будет несколько похожих элементов на странице, лучше использовать классы, а не идентификаторы. Таким образом, вы можете применять стили к ULS внутри различных идентификаторов контейнеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...