Jquery 事件侦听器不处理附加元素(他们应该,不是吗?)

Posted

技术标签:

【中文标题】Jquery 事件侦听器不处理附加元素(他们应该,不是吗?)【英文标题】:Jquery event listeners not working on appended elements (and they should, shouldn't they?) 【发布时间】:2017-09-16 05:11:44 【问题描述】:

我正在为我的 Rails 应用程序使用 Jquery UI datepicker,并且我想在下个月有人单击按钮时触发一个事件。它没有触发任何东西。我的 JQuery 版本是 v1.12.4。

这是我的 html 代码示例:

<input type='text' name='date_from' class="form-control date_picker" placeholder="Data de ida..." id='datetimepicker1' required/>
<div id="datepicker1" class="calendar"></div>

日期选择器的 HTML 代码是 JQuery UI 生成的默认代码。

这是我的 javascript 尝试:

  $('body').on('click','.ui-datepicker-next',function(e)
    console.log('Next/prev month')
    e.preventDefault();
  );

它什么也没做!它不会在控制台上引发错误,不会打印任何内容,也不会将点击事件附加到具有ui-datepicker-next 类的元素上。

如果我将以下代码复制并粘贴到控制台中,它适用于文档中的当前元素。

$('.ui-datepicker-next').click(function(e)
    console.log('Next/prev month')
    e.preventDefault();
);

我以前从来没有遇到过,所以如果这个问题应该更详细一点,我很抱歉,但我真的不知道我还应该在这里提什么。

编辑:

jsfiddle:https://jsfiddle.net/9484zzrL/

这是迄今为止我在 jsfiddle 上重新创建问题所能做的最好的事情。 如果您单击所选月份的某一天,则可以,但如果您更改月份,它将不再起作用。

编辑2:

我相信这完美地重现了我的问题。当我在日历中选择任何日期时,事件不会触发。

https://jsfiddle.net/awhwr3uv/

【问题讨论】:

您的&lt;input&gt; 元素没有“ui-datepicker-next”类。 你能在 sn-p 中重新创建这个吗? 我没有看到您甚至将日期选择器附加到输入。喜欢$('#datepicker1').datepicker(); 我的猜测是,在您的 javascript 代码运行时,该元素尚不存在。请尝试使用以下命令对其进行调试:console.log($('.ui-datepicker-next').length)) 如果是这样,请在 document.ready 函数中使用您的事件侦听器。否则,请上传您的完整 javascript 文件。 对代码的缺失部分感到抱歉。这是我能在 jsfiddle 上重新创建的最好方法:jsfiddle.net/8n85dgxt 【参考方案1】:

编辑:

所以我查看了您最新的 jFiddle。我想知道你是否尝试过使用这样的东西:

$("#datepicker1").datepicker(
  firstDay: 1,
  onSelect: function(date) 
    console.log('Date Selected: ' + date);

    //Do some other cool stuff here

    $(this).hide();
  
);

$("#datepicker2").datepicker(
  firstDay: 1,
  onSelect: function(date) 
    console.log('Date Selected: ' + date);

    //Do some other cool stuff here

    $(this).hide();
  
);

您可以在 jFiddle 中的 onSelect 选项中执行所需的所有操作,它甚至将日期作为参数传递给回调。

原创

改变这个:

$('body').on('click','.ui-datepicker-next',function(e)
    console.log('Next/prev month')
    e.preventDefault();
    //setTimeout(date_picker_listener(),500)
);

到这里:

$(document).on('click','.ui-datepicker-next',function(e)
    console.log('Next/prev month')
    e.preventDefault();
    //setTimeout(date_picker_listener(),500)
);

它在你的小提琴中工作。

编辑

我想解释一下我对您的代码为什么不起作用的猜测。

我认为这是因为 jQuery 已经为按钮类的 body 元素附加了一个单击侦听器。因为 2 个单击侦听器附加到同一类元素的主体,所以 JavaScript 引擎到达的第一个是触发的。

实际上,当您使用 on 方法将点击侦听器附加到正文时,JavaScript 引擎会不断扫描正文以查找点击,然后检查点击是否与您的选择器匹配。因为 jQuery 已经在该选择器的主体上拥有了单击侦听器,所以您的侦听器从未收到该事件。

考虑到这一点,通过将点击侦听器附加到文档,您设置了一个全新的侦听器,引擎现在也在扫描文档以查找点击并查看它是否与您的选择器匹配。因为你是唯一一个监听你的文档的人得到事件。

所以我通过将侦听器从单击更改为鼠标悬停来测试它,果然它可以工作。

$('body').on('mouseover','.ui-datepicker-next',function(e)
    console.log('Next/prev month')
    e.preventDefault();
    //setTimeout(date_picker_listener(),500)
);

我希望这会有所帮助。关于为什么您的代码不起作用,这是我能想到的最好的方法。

【讨论】:

谢谢!确实,它确实解决了我的问题。同样的方法在我的应用程序中仍然不起作用:(看来我没有很好地重现问题。如果你仍然想尝试一下,我很确定这个完美地重现了我的问题。jsfiddle.net/awhwr3uv选择一个date 不会触发任何事情,它应该触发。 当我单击日期时,控制台会不断记录此错误。获取nikkomsgchannel/……2d0050005f005e00100023005c0047002c000c0057005800280052005c005c005f0029005f 嗯,我看不到。我的浏览器没有记录任何有意义的东西......萤火虫也没有。 我过几个小时再看一遍。 好的,再看一遍并编辑我的答案。我认为这将解决您的问题。

以上是关于Jquery 事件侦听器不处理附加元素(他们应该,不是吗?)的主要内容,如果未能解决你的问题,请参考以下文章

为事件jQuery选择特定的新附加节点副本

chrome扩展跟踪前端JavaScript,该JavaScript使用DOM/jQueryAPI在运行时操作html-DOM元素(例如,更改样式、附加事件侦听器)。

jQuery事件处理程序.on()不起作用

如何为附加到元素的每个事件侦听器打印或迭代? [复制]

jQuery + DevTools:如何快速获取附加到元素的事件处理程序

WPF附加事件定义