JQuery для переключения динамически создаваемых элементов

У меня есть что-то вроде этого, но это не работает:

<!-- ... code .. -->

var id = 0;        

data.forEach(function(item, i) {
      id = id+1;

$( ".button-" + id ).click(function() {
$( ".button-" + id ).toggle();

});

<!-- ... code .. -->

Что я хочу: Есть несколько DIV, таких как кнопка-1, кнопка-2 ... и так далее. Я сделал переключение и хотел автоматизировать его с помощью этого цикла, потому что контент генерируется динамически. Но это, кажется, неправильный путь... В этом цикле это не работает.

Так как сделать переключатели динамически для кнопки-1, кнопки-2, ...??

Это как раз об этом, что кажется неправильным:

$( ".button-" + id ).click(function() {
$( ".button-" + id ).toggle();

РЕДАКТИРОВАТЬ

Ну, может, мой вопрос был немного беспорядочным. Спасибо всем за ваши ответы, я действительно ценю это! Но для меня не было правильного ответа... Итак, еще раз, а теперь более конкретно:

У меня есть несколько кнопок с иконками материалов, которые должны менять свое состояние при нажатии.

<a href="" class="likebutton-1"><i class="material-icons">favorite</i></a>
<a href="" class="likebutton-1" style="display:none;"><i class="material-icons">favorite_border</i></a>

Содержимое HTML генерируется динамически, поэтому есть кнопка вроде 1, кнопка около 2...

Тогда есть еще один DIV, который показывает количество лайков:

<div class="likes-1">99 likes</div>
<div class="likes-1" style="display:none;">100 likes</div>

DIVs оба внутри внешнего контейнера.

И вот мой код jQuery для этого:

$( ".likebutton-1" ).click(function() {
$( ".likebutton-1" ).toggle();
$( ".likes-1" ).toggle();
});      

Ну, этот код работает для меня. Значок переключается с избранного на любимый_бордер, а переключатель лайков переключается с 99 на 100... (это просто демонстрационное приложение, поэтому не нужно действительно считать количество лайков)

Но я хочу динамически генерировать этот код jQuery, и это то, что не работает... сейчас я должен вручную установить переключатели для likebutton-1, likebutton-2...

5 ответов

Решение

На основании вашего последнего обновления я бы предложил некоторые структурные изменения в вашей HTML-разметке.

Вместо того, чтобы использовать:

<a href="" class="likebutton-1"><i class="material-icons">favorite</i></a>
<a href="" class="likebutton-1" style="display:none;"><i class="material-icons">favorite_border</i></a>

Я предлагаю использовать только один элемент - это может предотвратить проблемы со стилем. Кроме того, удалите -1 или же -X суффикс, если вы генерируете эти сегменты динамически, иначе вам нужно много (динамически создаваемых) слушателей событий.

Сделай это так:

<a href="#" class="likebutton"><i class="material-icons icon-fav">favorite</i></a> 

Я добавил класс icon-fav к вашему элементу, чтобы получить к нему более легкий заранее.

Теперь мы делаем то же самое для вашего раздела "Нравится" и улучшаем структуру кода. Отделите количество слов (так число) от текста. Таким образом, мы можем легко увеличить или уменьшить это число.

<div class="likes"><span class="likes-count">99</span> likes</div>

Поскольку вы упомянули, что вы генерируете эти сегменты автоматически, я предполагаю, что у вас есть или что-то похожее вокруг этих элементов, например:

<div class="parent-container">
  <a href="#" class="likebutton"><i class="material-icons icon-fav">favorite</i></a>  
  <div class="likes"><span class="likes-count">99</span> likes</div>
</div>

Теперь мы заботимся об остальном - JavaScript.

Нам нужен обход дерева из-за удаленного -x суффикс ваших классов - в противном случае мы изменили бы все ваши элементы сразу при нажатии на один из них. Вы можете найти больше информации о jQuery Tree Traversal здесь.

$(".likebutton").click(function() {
    var $parent = $(this).closest(".parent-container");
    var likes = parseInt($parent.find(".likes-count").text());

    if($parent.find(".icon-fav").text() == "favorite") {
        $parent.find(".icon-fav").text("favorite_border");
        $parent.find(".likes-count").text(++likes);
    }
    else {
        $parent.find(".icon-fav").text("favorite");
        $parent.find(".likes-count").text(--likes);
    }
});   

Этот слушатель события находит свой родительский контейнер с .closest() метод, который заставляет этот код работать, даже если ваш код еще более вложенный. это $parent Переменная является своего рода поисковой базой для всех последующих запросов. я использую .find() пройти весь путь - если это необходимо - потому что у вас, вероятно, более вложенная структура.

Вот рабочий jsfiddle! Попробуйте.

Я думаю, это то, что вы имеете в виду: D

https://jsfiddle.net/1eo4b33m/1/

$("[class*=button-]").click(function(){
    $(this).toggle()
})

Дайте этому шанс, вместо этого!:)

$("[class*='button-']").click(function(){
    $(this).toggle();
});

Вы должны использовать закрытие здесь,

var id = 0;   

data.forEach(function(item, i) {
      id = id+1;
      var bindEvents = function theOutterFunction() {     
        return function() {
        $( ".button-" + id ).click(function() {
        $( ".button-" + id ).toggle();
       }
      }();
      bindEvents();
});

У вас есть хорошие ответы. но похоже, что вам не хватает, насколько это просто. То, что вам нужно использовать, это JQuery's.on метод. Вы можете посмотреть в этом SO Q&A немного больше информации о настройке динамических событий.

Однако, в итоге, это означает: "назначение событий для динамических элементов статическому родителю". Читайте здесь для получения дополнительной информации о том, что является динамическим и статическим. Короче говоря, динамические средства создаются после загрузки страницы.

Таким образом, по сути, вы можете использовать ответ Jamie PhanВам просто нужно понять, как это реализовать.

Все, что вам действительно нужно, это " статический родитель". Это элемент, который уже существует в HTML при загрузке страницы. Довольно часто я лично использую объект DOM, однако лучше иметь близкого родителя с идентификатором. Например, если ваш HTML выглядел так:

<div>
    <h1>Dynamic buttons added below</h1>
    <ul id="divDyno"><!-- Buttons will be added here --></ul>
</div>

Тогда ваш статический родитель будет<div id="divDyno"...который может быть выбран с помощью строки'#divDyno', Итак, ваш код будет выглядеть так:

$('#ulDyno').on('click', '[class*=button-]', function(e) {
    $(this).toggle();
})

Ниже приведен быстрый пример того, как легко реализовать эти методы. Я добавил несколько вещей, чтобы вы могли видеть, как это работает полностью, но я постараюсь объяснить все подробно.

Модифицировано, чтобы просто переключать классы (или изменять состояние) кнопок

/** This will be the event fired when clicking on a "dynamically" created button **/
function button_click_event() {
 // only need use "this", no need for ID.
 // 'this' is the button html element itself
 $(this).toggleClass('black white');
}

/** This event will dynamically create buttons **/
function create_button() {
  // first I get the length of how many buttons exist,
  // simply to add to the button text
 var len = $('ul li').length,
  // then I create a <li> to append to the <ul>
  li = $('<li />').appendTo('ul'),
  // then, of course, I create the <button> and add it to the <li>
  btn = $('<button />').text('Button '+len).addClass('button-'+len).appendTo(li);
 // now we'll give the button a class for color
 btn.addClass(len%2 ? 'black': 'white')
}

/** This will simply show all "toggled" buttons **/
function show_buttons() {
 $('ul button').show();
}
$(function() {
 // As per the previously mentioned example
 // In jQuery, you can set events for a dynamic element by using a static parent.
 $('#ulDyno').on('click', '[class*=button-]', button_click_event)
 
 // In the following case, I'll simply use the DOM for brevity,
 //  but it's still best to use a "static" element with an ID
 // This event is simply for the "Add" button. To "dynamically" create buttons.
 $(document).on('click', '#btnAdd', create_button)// notice i didn't close with a ";"
  // With no close, the return is "$(document)", So I can write more code attached to it.
  // This event will show any "toggled" buttons
  .on('click', '#btnShow', show_buttons);
});
html, body { font-size: 20px; width: 100%; }
html, body, table { height: 100%; margin: 0 auto; padding: 0; text-align: center; }
div { left: 1em; position: fixed; top: 1em; }
ul { margin: 0 auto; padding: 0; }
li { list-style: none; margin: .5em auto; padding: 0; }
button { padding: .5em .8em; }
.black { background-color: #000; color: #fff }
.white { background-color: #fff; color: #000 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div><button id="btnAdd">Add Buttons</button><button id="btnShow">Show All Buttons</button></div>
<table>
 <tr>
  <td>
   <br />
   <ul id="ulDyno"></ul>
  </td>
 </tr>
</table>

Другие вопросы по тегам