我正在尝试将单击事件处理程序添加到动态添加的链接以防止默认行为(但允许传播,以便将单击传递到下面的另一个处理程序)。
当我这样做时:
$('.menulink').on('click', function(e) {
e.preventDefault();
console.log('menu clicked');
alert('now');
});
在$(window).load中,那么它在桌面上可以正常工作。但是,如果我使用:
$(document).on('click', '.menulink', function(e) {
e.preventDefault();
console.log('menu clicked');
alert('now');
});
在 $(document).ready 中,它永远不会触发。仅供参考,我正在使用 Jquery 1.11.1。
任何人都可以建议为什么委托版本不起作用(我尝试使用其他可见的父容器,但又回到使用 $(document) 进行测试,但没有一个有效)。
此外,即使在第一个工作示例中,它在台式机上也能正常工作,但在 Android 上它有时会触发,有时只是跟随链接 url 而不触发点击处理程序,但似乎没有任何关于它何时有效和何时不工作的逻辑!
谁能看出我做错了什么!!(请参阅下面的"按要求更新 2",其中包括显示问题的小提琴)
根据要求更新:
我正在使用 http://tikku.com/jquery-radmenu-plugin 进行径向菜单,该菜单采用列表并使用列表项以编程方式为菜单创建另一个元素。因此,当插件加载时,链接会动态添加到径向菜单(围绕每个项目)中,初始 HTML 列表为:
<div id="radial_container" class="ui-radmenu-parent visible">
<ul style="display: none;" class="list">
<li class="item"><div class="menuopt2"><a class="menulink" href="/url2"><img class="svghover" alt="OPT2" src="/img/pages/2.png"><div class="menulabel">OPT2</div></a></div></li>
<li class="item"><div class="menuopt14"><a class="menulink" href="/url14"><img class="svghover" alt="OPT14" src="/img/pages/14.png"><div class="menulabel">OPT14</div></a></div></li>
<li class="item"><div class="menuopt20"><a class="menulink" href="/url20"><img class="svghover currentsectionicon" alt="OPT20" src="/img/pages/20-ro.png"><div class="menulabel">OPT20</div></a></div></li>
<li class="item"><div class="menuopt74"><a class="menulink" href="/url74"><img class="svghover" alt="OPT74" src="/img/pages/74.png"><div class="menulabel">OPT74</div></a></div></li>
</ul>
</div>
插件加载后,它会生成以下标记:
<div class="radial_div" style="position: relative;">
<div style="position: absolute; left: 596.277px; top: 93.8734px;" class="radial_div_item"><div class="menuopt2"><a class="menulink" href="/url2"><img class="svghover" alt="OPT2" src="/img/pages/2.png"><div class="menulabel">OPT2</div></a></div></div>
<div style="position: absolute; left: 874.839px; top: 11.8205px;" class="radial_div_item"><div class="menuopt14"><a class="menulink" href="/url14"><img class="svghover" alt="OPT14" src="/img/pages/14.png"><div class="menulabel">OPT14</div></a></div></div>
<div style="position: absolute; left: 1165.16px; top: 9.64253px;" class="radial_div_item"><div class="menuopt20"><a class="menulink" href="/url20"><img class="svghover currentsectionicon" alt="OPT20" src="/img/pages/20-ro.png"><div class="menulabel">OPT20</div></a></div></div>
<div style="position: absolute; left: 1443.72px; top: 91.8418px;" class="radial_div_item"><div class="menuopt74"><a class="menulink" href="/url74"><img class="svghover" alt="OPT74" src="/img/pages/74.png"><div class="menulabel">OPT74</div></a></div></div>
</div>
根据要求更新 2:
我创建了一个大大简化的小提琴,只显示菜单和相关链接。如果您访问 http://jsfiddle.net/7asLq/2/那么您可以看到它正确地遵循 radmenu 的 onselect 处理程序和 .menulink 的单击处理程序,并且由于 preventdefault,阻止指向菜单链接 href。如果将"$('.menulink').on('click', function(e) {"替换为"$(document).on('click', '.menulink', function(e) {"(这在代码中被注释掉),那么它会运行onselect处理程序,并且只定向到menulink href,并且永远不会运行menulink单击处理程序。希望这能更清楚地表明问题?
非常感谢,
戴夫
几个问题。首先,样式可以防止链接成为目标。锚点的样式设置为其计算大小为 0 x 0(当您将鼠标悬停在链接上时,请使用 Chrome DOM 检查器查看此信息)。
快速解决方法是赋予它们与按钮相同的大小:
.menulink{
display: block;
width:30px;
height:30px;
}
第二个问题是插件在内部停止 click 事件的传播,因此委托的处理程序永远不会看到它。
您可以在插件中selectMenuitem
末尾注释掉一行代码以解决眼前的问题(这是非最小版本):
function selectMenuitem(evt) {
var $this = $(this);
var $element = $(evt.target);
var container = $.radmenu.container;
if (!$element.hasClass(container.itemClz))
$element = $element.closest("." + container.itemClz);
var isInNested = $element.parents("." + container.itemClz).length > 0;
var index = $element.index();
if (!isInNested)
$this.parents("." + container.clz).radmenu(index);
else
$this.radmenu(index);
//cancelBubble(evt); <<<<<<<<<<<<<<<< Remove this
};
这是JSFiddle中的结果:http://jsfiddle.net/7asLq/10/
对于动态注入的元素,应使用委托方法。有关更多详细信息,请参阅 API 文档:http://api.jquery.com/delegate/
让我们假设原始代码有一个外部 DIV,带有 Id = "outerWrapper"
。
因此,您的处理程序应如下所示:
$("#outerWrapper").delegate(".radial_div_item div .menulink","click",function(e){
e.preventDefault();
console.log('menu clicked');
alert('now');
});