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>