jQuery 切换动态创建的元素

jQuery toggle dynamically created elements

我有这样的东西,但它不起作用:

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

var id = 0;        

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

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

});

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

我想要的是:有一些 DIVs,比如 button-1,button-2 ...等等。我做了一个切换,我想用这个循环来自动化它,因为内容是动态生成的。但这似乎是错误的方式......在这个循环中它不起作用。

那么如何为按钮 1、按钮 2 等动态切换??

就说到这里了,好像说错了:

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

编辑

好吧,也许我的问题有点乱谢谢大家到目前为止的回答,我真的很感激!但是没有适合我的正确答案......现在又一次更具体:

我有一些带有 material 图标的按钮,它们应该会在点击时改变它们的状态。

<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 内容是动态生成的,所以有 likebutton-1,likebutton-2...

然后还有一个DIV显示了点赞数:

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

DIV两者都在一个外容器中。

这是我的 jQuery 代码:

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

好吧,那个代码对我有用。图标从最喜欢切换到 favorite_border,点赞从 99 切换到 100...(这只是一个演示应用程序,因此没有必要真正计算点赞)

但我也想动态生成 jQuery 代码,而那是行不通的...现在我必须手动设置 likebutton-1、likebutton-2 的开关 ...

试试这个吧! :)

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

我想这就是你的意思:D

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

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

你有一些很好的答案。但看起来你错过了这是多么简单。您需要使用 jQuery's .on method. You can look at this SO Q&A 来获取有关设置动态事件的更多信息。

然而,总而言之,它的意思是:"assigning events for dynamic elements to a static parent."阅读此处了解有关 的更多信息。简而言之,动态意味着在页面加载后创建。

所以本质上,你可以使用 given by Jamie Phan,你只需要简单地了解如何实现它。

你真正需要的只是一个“static parent”。这是加载页面时已存在于 HTML 中的元素。就我个人而言,我经常使用 DOM 对象,但是,最好有一个具有 ID 的近亲。例如,如果您的 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();
})

以下是如何轻松实施这些技术的快速示例。我添加了一些东西,以便您可以看到它的完整功能,但我会尝试深入解释所有内容。

Modified to simply toggle classes (aka change state) of buttons

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

根据您的最新更新,我建议您对 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> 

我将 class icon-fav 添加到您的元素中,以便提前更轻松地访问它。

现在我们对你喜欢的部分做同样的事情并改进代码结构。将 like-count(即数字)与文本分开。所以我们可以很容易地增加或减少这个数字。

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

由于删除了 class 的 -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 变量类似于 search-base。我使用 .find() 一路向上遍历——如果有必要的话——因为你可能有一个更嵌套的结构。

这里是working jsfiddle!试一试。