You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现动态生成div的独立Swipe交互,解决全局响应问题

解决动态生成元素的独立滑动响应问题

你的问题核心很明确:当前代码里用全局选择器$('.option1')会选中页面上所有同类元素,所以滑动一个swipeArea会影响全部。和你之前用$(this)实现独立响应的思路一样,我们只需要把操作范围限定在当前触发滑动的swipeArea内部即可。

具体修改步骤:

  1. 保留当前元素的引用:在循环绑定事件时,用闭包保存当前swipeArea的引用(避免循环变量共享导致的元素混淆问题)。
  2. 限定选择器范围:在滑动回调里,只查找当前swipeArea内部的.option1和.option2,而不是全局查找。

修改后的完整JavaScript代码:

var el = document.getElementsByClassName('swipeArea');
for (var i = 0; i < el.length; i++) {
  // 用立即执行函数创建闭包,固定当前的swipeArea元素
  (function(currentSwipeArea) {
    swipedetect(currentSwipeArea, function(swipedir) {
      // 只在当前滑动区域内查找选项元素
      var $option1 = $(currentSwipeArea).find('.option1');
      var $option2 = $(currentSwipeArea).find('.option2');

      if (swipedir == 'up') {
        $option1.css('display', 'block');
        $option2.css('display', 'none');
      } else if (swipedir == 'down') {
        $option1.css('display', 'none');
        $option2.css('display', 'block');
      } else {
        $option1.css('display', 'none');
        $option2.css('display', 'none');
      }
    });
  })(el[i]);
}

// 你的swipedetect函数保持不变
function swipedetect(el, callback){
  var touchsurface = el,
    swipedir,
    startX,
    startY,
    distX,
    distY,
    threshold = 150, //required min distance traveled to be considered swipe
    restraint = 100, // maximum distance allowed at the same time in perpendicular direction
    allowedTime = 300, // maximum time allowed to travel that distance
    elapsedTime,
    startTime,
    handleswipe = callback || function(swipedir){}

  touchsurface.addEventListener('touchstart', function(e){
    var touchobj = e.changedTouches[0]
    swipedir = 'none'
    dist = 0
    startX = touchobj.pageX
    startY = touchobj.pageY
    startTime = new Date().getTime() // record time when finger first makes contact with surface
    e.preventDefault()
  }, false)

  touchsurface.addEventListener('touchmove', function(e){
    e.preventDefault() // prevent scrolling when inside DIV
  }, false)

  touchsurface.addEventListener('touchend', function(e){
    var touchobj = e.changedTouches[0]
    distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface
    distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface
    elapsedTime = new Date().getTime() - startTime // get time elapsed
    if (elapsedTime <= allowedTime){ // first condition for swipe met
      if (Math.abs(distY) >= threshold && Math.abs(distX) <= restraint){ // 2nd condition for vertical swipe met
        swipedir = (distY < 0)? 'up' : 'down' // if dist traveled is negative, it indicates up swipe
      }
    }
    handleswipe(swipedir)
    e.preventDefault()
  }, false)
}

为什么这样修改有效?

  • 闭包的作用:循环中用立即执行函数把当前的el[i]赋值给currentSwipeArea,确保每个滑动回调都能拿到自己对应的swipeArea元素,不会因为循环变量i的更新而混淆。
  • 范围限定的选择器:$(currentSwipeArea).find('.option1')只会查找当前滑动区域内部的选项元素,不会影响其他动态生成的swipeArea里的内容,和你之前用$(this)实现独立响应的逻辑完全一致。

额外优化建议(可选):

  • 可以把css('display', ...)换成jQuery的show()和hide()方法,写法更简洁:比如$option1.show(); $option2.hide();
  • 如果你的项目支持ES6+,可以用let代替var来声明循环变量,这样可以省去闭包:
    for (let i = 0; i < el.length; i++) {
      let currentSwipeArea = el[i];
      swipedetect(currentSwipeArea, function(swipedir) {
        // 后续逻辑和上面一致
      });
    }
    

内容的提问来源于stack exchange,提问作者mark n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:25:16