JS委托动态声明元素的唯一事件(one())

时间:2018-10-24 13:27:24

标签: javascript jquery

我正在从事js项目。 HTML的某些部分是通过JS这样生成的:

html += '<div class="button"><a href="' + url1 + '>' + button_text1 + '</a></div>';
html += '<div class="button"><a href="' + url2 + '>' + button_text2 + '</a></div>';

我想要的是为每个按钮的第一次单击创建侦听器。

想法1:由于动态声明,请使用$(.button a).live('click', doSomething)。可悲的是,没有办法像这样在第一次点击时强制触发。也已弃用。

想法2:使用$(.button a).one('click', doSomething)。当DOM准备就绪时,由于on()而无法工作可能无法找到选择器,但仍会呈现($(document).ready(...))。在此处查看详细信息:https://jqueryhouse.com/jquery-on-method-the-issue-of-dynamically-added-elements/

想法3:使用$(body).one('click', '.button a', doSomething),即委托事件,如注明的消息来源所建议。
但是似乎JS的读法不是“这里是一个元素数组;为每个元素添加one('click')事件”,而是“添加one('click')事件以单击数组中的任何元素”,因为无论我单击哪个按钮,事件都只会触发一次。

我真的在试图找到如何处理这种情况的任何线索,但是没有运气。我将非常感谢您提供帮助或其他解决方法!

2 个答案:

答案 0 :(得分:2)

  

«我要为每个按钮的第一次点击创建监听器。»

此处的关键字是每个

尝试:

$(.button a).each(function(){
  $(this).one('click', doSomething); // (!)No prenthesis here... Just the function name.
});

.each()方法的文档。

由于您动态地添加了新元素...将html附加到了容器之后,因此对它们运行类似的每个循环,如下所示:

// Assuming you do this
$(".container_selector").append(html);

// Then run the each loop
$(".container_selector").find(".button a").each(function(){
  $(this).one('click', doSomething); // (!)No prenthesis here... Just the function name.
});

答案 1 :(得分:2)

您想得太多。因此,请使用事件委托和一些标志来说明它是否已运行。

$(document).on('click', '.test', function() {
  var elem = $(this)  // what was clicked
  if (elem.data('clicked')) {  // see if we clicked it
    return false  // if yes, ignore the click
  }
  elem.data('clicked', true)  // mark it was clicked
  elem.html((new Date).toLocaleString())  // do something
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">1</div>
<div class="test">2</div>
<div class="test">3</div>
<div class="test">4</div>

或者退出尚未运行的课程,然后将其删除

$(document).on('click', '.test-run', function() {
  var elem = $(this)  // what was clicked
  elem.removeClass('test-run')  // remove class so will not be clickable
  elem.html((new Date).toLocaleString())  // do something
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test test-run">1</div>
<div class="test test-run">2</div>
<div class="test test-run">3</div>
<div class="test test-run">4</div>