我有一个相当复杂的UI构建,我希望能够禁用它的一部分,以便除了一个(重新启用按钮)之外的所有子元素都不可点击。
我正在向父级添加已禁用 class
并在父级上设置侦听器以检查点击次数,但由于子级元素事件未被委派,因此会触发在父母的点击处理程序之前,所以我无法阻止冒泡。
根据我的理解,使用捕获阶段并不是一个真正的选择,那么还有另一种方法吗?
我宁愿不在顶部拍一个新的HTML元素(叠加),因为我需要能够单击父内部的按钮来删除禁用状态。
我是否应该重写所有子元素点击处理程序而不是使用委托,所以只有父级正在侦听点击事件?
[更新更多解释和示例代码] 我有一个动态加载的面板,在我的网站的每个部分都不同。加载后,将运行特定于页面的脚本以将事件连接到面板中的各个元素。这包括链接和表单,以及可编辑元素(在DOM中只是常规跨度。)示例HTML:
<div class="infoPanelContent" id="detailSection">
<h1><span>
Details
<a class="sprite-icons flag" title="Flag" data-recordid="123123" href="/tickets/flag">Flag</a>
</span></h1>
<ul class="flexCol">
<li>
<h3>Status:</h3>
<span id="setStatus">
<span data-recordid="123123" data-projectid="104824" id="status" class="editWithSelect" title="Click to edit...">Open</span>
<input type="text" class="hidden" maxlength="50" placeholder="New Status">
</span>
</li>
</ul>
<!-- Responsiblity -->
<h1><span>
Responsibility</span>
<a data-orientation="left" title="Add people" href="/tickets/responsible?r=123123" class="toggleAddNew sprite-buttons iconAdd">Add people</a>
</h1>
<ul class="singleCol">
<li>
<p>Mel L.</p>
<a class="sprite-buttons iconRemove" data-itemid="432432" data-recordid="123123" data-projectid="104824" href="/tickets/delete-responsible">Delete</a>
</li>
</ul>
<h1>
<span>Attachments</span>
<a data-orientation="left" title="Add attachments" href="/tickets/attachments?r=123123" class="toggleAddNew sprite-buttons iconAdd">Add attachments</a>
</h1>
<ul class="singleCol attachments">
<li>
<p><a target="_blank" href="http://www.test.com"><span class="sprite-icons iconFiletypeIMG"></span><em>Sample (60 KB)</em></a></p>
</li>
</ul>
<p class="centerButton"><a data-delete="Delete Ticket" data-restore="Restore Ticket" class="sprite-buttons btnBlueLight" title="" data-recordid="123123" data-projectid="104824" href="/tickets/delete" id="deleteTicket"><strong class="sprite-buttons">Restore Ticket</strong></a></p>
连接功能的示例元素包括$(".flag")
,$("#status")
,$(".toggleAddNew")
等。需要点击的一个项目是底部的删除按钮(这是一个锚标记。)请记住,这个HTML可能在不同的页面上有所不同。如果我要委托锚点的点击,我没有问题,但它确实是一个问题,因为无法使用委托事件设置这个问题。我已经尝试添加一个监听器作为$("#infoPanel *").click( ... )
并停止传播,默认行为并返回false,但是项目的事件处理程序首先运行,因此不起作用。通常情况下,如果不是那个按钮,我会在整个事情上加上覆盖并称之为一天。
答案 0 :(得分:1)
在子元素的处理程序中执行此操作:
if ($(this).parent().is(".disabled")) {
return false;
}
或者如果是父母&#34;你的意思是进一步的祖先,做到这一点:
// In the child element's handler...
if ($(this).parents(".disabled").length) {
return false;
}
如果您仍想让活动冒泡,请从false
声明中删除return
。
正如评论中所述,使用.closest()
代替.parents()
可能会给出稍微好一点的结果,因为一旦找到第一个.disabled
祖先就可以停止测试。
答案 1 :(得分:1)
不完全确定你想在这里做什么,但据我所知,你想让父元素的所有后代都不可点击,除了其中一个子元素。
假设您打算在父元素上保持“禁用”类:
$('.disabled').find(':not(.enable_button)').on('click', function() {
return false;
});
这也假设您可以在要单击的子元素上放置一个“enable_button”类。如果您不想使用课程,我确信有一些方法可以识别它。
当用户点击重新启用按钮时,只需删除此处理程序。
答案 2 :(得分:0)
我使用jEditable的.editable('disabled')
方法的组合解决了这个问题,然后直接在禁用面板内的a
和button
元素上添加处理程序(不包括恢复按钮)。确保我绑定的元素使用委托,因此我控制的任何事件都会注册到面板。这使我能够禁用/启用全局,并为每个部分编写更清晰的代码。