Better Scroll 滚动后无法触发 click 事件怎么办?

Code°旗施 阅读 58

我用 Better Scroll 做了一个横向滚动的导航栏,但点击里面的按钮没反应,click 事件完全不触发。查了文档说是因为 BS 阻止了原生点击,但我已经加了 click: true 配置,还是不行。

试过用 @click.native(Vue 项目),也试过监听 bs.on('click', ...),但要么没效果,要么拿到的不是我想要的元素。是不是哪里配置错了?

const bs = new BScroll('.nav-wrapper', {
  scrollX: true,
  scrollY: false,
  click: true,
  tap: true
})

// 事件绑定在子元素上
document.querySelector('.nav-item').addEventListener('click', () => {
  console.log('clicked!')
})
我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
Good“沐语
兄弟,这个坑我踩过,说多了都是泪。

你配置 click: true 其实没毛病,但问题在于 BS 拦截了原生 click事件后,所谓的"click" 其实是 BS 自己模拟的,跟原生的 click 事件完全两码事。你在子元素上直接绑原生 addEventListener 是没用的,因为事件根本没传到那儿。

正确的做法是用 BS 提供的事件系统:

const bs = new BScroll('.nav-wrapper', {
scrollX: true,
scrollY: false,
click: true,
tap: true
})

// 用 BS 的 tap 事件,更接近原生点击的体验
bs.on('tap', (e) => {
// e.target 才是你点击的那个元素
console.log('clicked!', e.target)

// 如果想拿到具体的数据,可以从 dataset 取
// console.log(e.target.dataset.id)
})
```

为什么你用 bs.on('click', ...) 拿不到想要的元素?因为你拿的是事件对象本身,没从 e.target 里取。

另外在 Vue 里也是同理,别用 @click.native,直接用 @click 配合 BS 的事件或者在 mounted 里用 bs.on('tap', ...) 来处理。

tap 事件比 click 响应更快,没有 300ms 延迟,体验更接近原生,导航栏这种场景用 tap 就对了。
点赞
2026-03-19 15:05
迷人的书娟
问题在于 Better Scroll 的 click 事件机制。它不是触发原生 click 事件,而是派发自己的自定义事件,你直接在子元素上绑原生 listener 肯定收不到。

两种解决思路:

第一种,用 BScroll 实例来监听 click。它会返回被点击的原始事件对象:

const bs = new BScroll('.nav-wrapper', {
scrollX: true,
scrollY: false,
click: true,
tap: true
})

// 绑定在 BScroll 实例上,不是子元素
bs.on('click', (e) => {
// e.target 是实际被点击的 DOM 元素
console.log('clicked!', e.target)

// 如果需要判断点击的是哪个元素
if (e.target.classList.contains('nav-item')) {
// 处理逻辑
}
})


第二种,用事件委托,在外层容器直接监听原生 click(适用于较新版本的 Better Scroll):

document.querySelector('.nav-wrapper').addEventListener('click', (e) => {
const target = e.target.closest('.nav-item')
if (target) {
console.log('clicked!', target)
}
})


另外提醒一下,Better Scroll 2.x 版本对 click 的处理有些变化。如果你用的是 2.x,可以检查一下是否需要额外配置 probeType: 3 才能保证事件正常触发。还有一个坑是如果子元素是动态渲染的,记得在 nextTick 之后再去初始化 BScroll,否则可能会出现元素获取不到的情况。
点赞
2026-03-16 21:23