【发布时间】:2019-10-21 14:46:11
【问题描述】:
我在sortable div 中有一个复选框,其中点击或更改事件在触摸设备上触发了两次,但在桌面上没有触发(也没有在 Firefox 开发工具上模拟触摸),原因不明。不想要的效果是复选框连续切换两次,使其保持原始状态。我提到 div 是可排序的,因为当它们不再可排序时,复选框工作得很好。以下是相关部分:
$sortable.sortable({
items: '.sortable',
cancel: 'input,textarea,button,select,option'
});
我不知道为什么可排序小部件会触发两次点击事件。
我试图处理这个问题没有成功:
我尝试禁用切换复选框并手动设置其值的默认行为。但是由于某种原因,该复选框不会被选中/取消选中。如果我通过控制台执行此操作,它确实有效:
// same with the "change" event
// the reason the event is bound to $sortable rather than the inputs themselves is that
// new sortable divs are added dynamically so otherwise they wouldn't have the event bound to them
$sortable.on('click', 'input[type="checkbox"]', function (e) {
e.stopImmediatePropagation();
// this does disable the default behaviour of checking/unchecking the box
e.preventDefault();
const $this = $(this);
// this doesn't check/uncheck the box at all, but setting a global variable to $this and doing it via console does work
$this.prop('checked', !$this.prop('checked'));
});
我尝试了一种更典型的使用标志的方法,但是似乎存在一些竞争条件(或者任何它被称为的,因为如果我没记错的话 js 是单线程的)并且该函数无论如何都会运行两次:
let checked = false;
$sortable.on('click', 'input[type="checkbox"]', function() {
if (checked) return;
// this is output twice, which is not what we are after
console.log('running');
checked = true;
// here ideally we would set the value of the checkbox
checked = false;
});
我已经使用 $._data($checkboxes[0], 'events') 检查了绑定到输入的任何有问题的事件,但除了引导工具提示(鼠标悬停和鼠标悬停事件)以及更改事件之外,没有其他问题。
编辑: 基本上,当您单击 div 或其子项中的任何位置时,可排序小部件似乎会产生单独的单击事件。这就是 click/change 被触发两次的原因。
我的问题是: 如何区分事件的发起者,以便如果它是可排序插件,则可以忽略该事件,而如果它是我设置的侦听器,复选框确实会改变它值(并且当复选框被实际选中时,我执行了我可能想要执行的任何其他操作)?
【问题讨论】:
-
您使用的是哪种触控设备?
-
@Buisson 只是我的 Android 手机,但一些用户在“移动”上使用我们的网站时报告了这个问题(我没有被告知具体是哪种触摸设备)
-
也许你已经为这个复选框添加了两个点击监听器?
-
@Buisson 并没有这样显示:
$._data($sortable[0], 'events')仅显示input[type="checkbox"]选择器的单击事件。 -
可能是因为,你的 sortable 和 checkbox 都触发了点击事件,
标签: javascript jquery