我的页面上有全屏fixed
块,我想使用JavaScript wheel
事件浏览这些块。
如果那没有道理;简而言之,我有一个自定义轮播,我想一次使用鼠标滚轮浏览一个块,即一次滚动滚动/单击移动到上一个/下一个项目。
我当前的解决方案有效,但需要进行一些调整以使其更好地工作。
我遇到的问题是,在鼠标滚轮上滚动1次/单击有时会滚动一个块,有时会滚动2个块。
我正在使用的算法如下:
wheel
事件,将全局变量deltaY
的值增加/减少1(在点击模式下,每次滚动鼠标滚轮,鼠标滚轮都会触发35-40个事件,不确定这是否标准)deltaY
值发生变化,就应确定哪个块(按索引)应为active
。我用以下方法做到这一点; Math.floor(deltaY / 35)
,其中35
是我的鼠标滚轮引发的wheel
个事件的数量(对此不太确定,因为其他鼠标可能会有所不同)active
索引,并用deltaY
可除的整数更新35
我正在使用Vue.js,但是不用担心,如果您不熟悉它,我真正需要的只是算法,可以将其实现到我的代码中。
我还没有测试过这段代码,我只是根据自己的Vue.js代码为不熟悉Vue的那些人对其进行了模拟。
// Set the default values
let items = ['x', 'y', 'z'];
let active = 0;
let deltaY = 0;
/**
* Update the delta value and any other relevant
* values.
*
* @param {event} event
* @return void
*/
function updateDelta (value) {
active = Math.floor(value / 35);
deltaY = active * 35;
}
// Register the `wheel` event
window.addEventListener('wheel', (event) => {
// The navigation is only active when the page has not
// been scrolled
if (document.documentElement.scrollTop === 0) {
// If the last item is currently active then we do not need to
// listen to `down` scrolls, or, if the first item is active,
// then we do not need to listen to `up` scrolls
if (
(event.deltaY > 0 && (active - 1) === items.length)
|| (event.deltaY < 0 && deltaY === 0)
) {
return;
}
updateDelta(Math.sign(event.deltaY));
}
}, { passive: true });
我添加了清晰的注释来说明Vue在做什么
export default {
data() {
return {
items: ['x', 'y', 'z'],
active: 0, // Define the active index
deltaY: 0 // This is used for the scroll wheel navigation
}
},
created() {
// Register the `wheel` event
window.addEventListener('wheel', this._handleWheel, { passive: true });
},
destroyed() {
// Remove the `wheel` event
window.removeEventListener('wheel', this._handleWheel, { passive: true });
},
watch: {
// I have added watchers to both `deltaY` and `active`, however,
// this may not be necessary. These will not create an endless loop
// because the watcher is only called when a value is changed
active: function(index) {
// Whenever the `active` index changes, update the `deltaY` value
this.deltaY = index * 35;
},
deltaY: function(value) {
// Whenever the `deltaY` value changes, update the `active` index
this.active = Math.floor(value / 35);
}
},
methods: {
/**
* Handle the window wheel event.
*
* @param {event} event
* @return void
*/
_handleWheel (event) {
// The navigation is only active when the page has not
// been scrolled
if (document.documentElement.scrollTop === 0) {
// If the last item is currently active then we do not need to
// listen to `down` scrolls, or, if the first item is active,
// then we do not need to listen to `up` scrolls
if (
(event.deltaY > 0 && (this.active - 1) === this.items.length)
|| (event.deltaY < 0 && this.deltaY === 0)
) {
return;
}
this.deltaY += Math.sign(event.deltaY);
}
}
}
}
答案 0 :(得分:0)
正如您已经指出的那样,wheel
事件触发的次数可能会因鼠标的不同而有所不同。因此,依靠事件的数量来确定何时移动块始终是不可预测的。
相反,我建议尝试一种替代方法。例如,您可以尝试检测用户何时停止滚动,仅将索引增加1。快速的Google搜索返回了this helper function,就可以了。