原生JavaScript实现拖拽父元素时取消子元素点击事件
解决方案:拖拽父容器时取消子元素点击事件
核心思路
通过区分「点击」和「拖拽」操作,设置标志位判断是否触发子元素的点击事件:只有当鼠标按下后未发生有效拖拽(移动距离极小)时,才执行子元素的点击逻辑;若发生拖拽,则阻止子元素点击事件触发,同时不影响父容器的拖拽功能。
修改后的代码
// horizontal drag scroll for items const itemScroll = document.querySelector('#itemScroll'); var isDown = false; var isDragged = false; // 新增:标记是否发生拖拽 var startX; var scrollLeft; itemScroll.addEventListener('mousedown', (e) => { isDown = true; isDragged = false; // 每次按下鼠标重置拖拽标记 itemScroll.classList.add('active'); startX = e.pageX - itemScroll.offsetLeft; scrollLeft = itemScroll.scrollLeft; }); itemScroll.addEventListener('mouseleave', () => { isDown = false; isDragged = false; itemScroll.classList.remove('active'); }); itemScroll.addEventListener('mouseup', () => { isDown = false; itemScroll.classList.remove('active'); }); itemScroll.addEventListener('mousemove', (e) => { if (!isDown) return; e.preventDefault(); const x = e.pageX - itemScroll.offsetLeft; const walk = x - startX; // 当移动距离超过5px时,标记为拖拽操作(阈值可按需调整) if (Math.abs(walk) > 5) { isDragged = true; } itemScroll.scrollLeft = scrollLeft - walk; }); // click an item to change bg-color const items = document.querySelectorAll('.item'); for (var i = 0; i < items.length; i++) { items[i].addEventListener('click', function (e) { // 如果发生了拖拽,阻止点击事件执行 if (isDragged) { e.preventDefault(); e.stopPropagation(); isDragged = false; // 重置标记,不影响下一次操作 return; } this.classList.toggle('active'); }); }
关键说明
- 新增
isDragged变量,用于标记是否发生了有效拖拽,移动距离阈值可根据交互需求调整。 - 在
mousedown事件中重置isDragged,确保每次鼠标按下都重新判断操作类型。 - 在
mousemove中检测鼠标移动距离,超过阈值则标记为拖拽状态。 - 在子元素的
click事件中,先判断isDragged状态:若为true则阻止事件执行,否则正常执行类名切换逻辑。
内容的提问来源于stack exchange,提问作者user19788092
相关产品推荐
相关产品推荐

