我在sortable div中有一个复选框,由于某些晦涩的原因,单击或更改事件在触摸设备上触发两次,但在台式机上(而不是在Firefox开发工具上模拟触摸)触发两次。不利的影响是,该复选框连续两次被切换为原始状态。我提到div是可排序的,因为当它们不再可排序时,此复选框就可以正常工作。这是相关的部分:
$sortable.sortable({
items: '.sortable',
cancel: 'input,textarea,button,select,option'
});
我不知道为什么可排序的小部件会使click事件被触发两次。
我尝试解决此问题失败:
我尝试禁用切换复选框和手动设置其值的默认行为。但是由于某种原因,该复选框将不会被选中/取消选中。如果我通过控制台执行此操作,那么它会起作用:
// 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')
检查了绑定到输入的任何有问题的事件,但除了引导工具提示(鼠标悬停和mouseout事件)之外,当然,更改事件也没有其他问题。
编辑:基本上,当您在div或其子级中的任意位置单击时,可排序小部件似乎会产生一个单独的click事件。这就是点击/更改被两次触发的原因。
我的问题是:我如何区分事件的发起者,以便如果它是可排序的插件,则可以忽略该事件,而如果它是侦听器,则设置复选框会更改其事件值(并且在实际选中此复选框时执行其他可能要执行的其他操作)?
答案 0 :(得分:0)
尝试touchend,如果它也适用于点击,请使用以下方法,否则将其
分开$sortable.on("touchend click", 'input[type="checkbox"]', function(e) {
if(e.type == 'touchend'){
$(this).off('click');
// your function
}
});
否则都尝试
let checked = false;
$sortable.on("touchend click", 'input[type="checkbox"]', function(e) {
if(e.type == "touchend") {
checked = true;
// your function
}
else if(e.type == "click" && !checked ) {
// your function
}
});