Javascript 如何停止当前在触控板上的滑动
我们正在开发一个具有独特导航功能的网站。它的一部分包括在每个向上或向下滚动时,启动JavaScript并导航到不同的HTML元素。它位于Vue.js/Nuxt中 到目前为止,除了触摸板的使用,一切都运行得很好。最初用触控板用两个手指轻扫可以工作——然而,这似乎启动了某种平滑的滚动,需要一段时间才能完成。如果您尝试用两个手指朝同一方向再次滑动,它将被视为一个长滚动,不会触发JavaScript以进入下一页。我做了一个deltaY的控制台日志,因为这是一个2个手指的滑动(平滑滚动?),deltas需要一两秒钟才能完成 这会导致问题,因为您无法使用触控板快速浏览各个部分。您必须向下滑动,等待滚动完成,然后再次向下滑动 我们如何解决这个问题?有没有办法杀死当前的卷轴,或者消除平滑的卷轴,让卷轴以一种或另一种方式移动100个delta 提前谢谢 Vue.js代码Javascript 如何停止当前在触控板上的滑动,javascript,vue.js,scroll,swipe,trackpad,Javascript,Vue.js,Scroll,Swipe,Trackpad,我们正在开发一个具有独特导航功能的网站。它的一部分包括在每个向上或向下滚动时,启动JavaScript并导航到不同的HTML元素。它位于Vue.js/Nuxt中 到目前为止,除了触摸板的使用,一切都运行得很好。最初用触控板用两个手指轻扫可以工作——然而,这似乎启动了某种平滑的滚动,需要一段时间才能完成。如果您尝试用两个手指朝同一方向再次滑动,它将被视为一个长滚动,不会触发JavaScript以进入下一页。我做了一个deltaY的控制台日志,因为这是一个2个手指的滑动(平滑滚动?),deltas需
export default {
layout: 'empty',
components: {
Footer,
Logo,
LottieAnimation,
ServiceIcon,
CloseBtn
},
async asyncData({ app }) {
try {
return await app.$api.$get('/services.json')
} catch (error) {
return {
error
}
}
},
data() {
return {
activePage: 0,
config: {},
error: null,
goToPageTimer: null,
isTouchpad: null,
page: {},
scrollDisabled: false,
scrollPercentage: 0,
scrollPercentageOld: 0,
scrollDirection: null,
scrollTimer: null,
touchStart: null,
touchTimer: null,
lastWheelDirection: null,
lastWheelEvent: null,
wheelEventsCount: 0,
wheelEventsLimit: 25,
wheelStopTime: 120
}
},
watch: {
scrollPercentage(newValue, oldValue) {
this.scrollDirection = newValue > oldValue ? 'bottom' : 'top'
if (this.scrollDirection === 'bottom') {
this.goToNextPage()
} else {
this.goToPreviousPage()
}
}
},
mounted() {
window.addEventListener('keydown', this.onKeyDown)
window.addEventListener('scroll', this.handleScroll)
window.addEventListener('wheel', this.onMouseWheel)
window.addEventListener('touchend', this.onTouchEnd)
window.addEventListener('touchstart', this.onTouchStart)
this.initPage()
},
destroyed() {
window.removeEventListener('keydown', this.onKeyDown)
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener('wheel', this.onMouseWheel)
window.removeEventListener('touchend', this.onTouchEnd)
window.removeEventListener('touchstart', this.onTouchStart)
},
methods: {
disableScrolling() {
this.scrollDisabled = true
if (this.goToPageTimer) {
clearTimeout(this.goToPageTimer)
}
this.goToPageTimer = setTimeout(() => {
this.scrollDisabled = false
}, 30)
},
getServicePageId(slug) {
let servicePageId = null
Object.keys(this.page.childPages).forEach((pageId) => {
if (this.page.childPages[pageId].slug === slug) {
servicePageId = parseInt(pageId)
}
})
return servicePageId
},
goToNextPage() {
if (
this.scrollDisabled ||
this.activePage === this.page.childPages.length
) {
return
}
this.activePage = this.activePage === null ? 0 : this.activePage + 1
if (this.activePage < this.page.childPages.length) {
this.scrollToActivePage()
}
},
goToPreviousPage() {
if (this.scrollDisabled) {
return
}
if (!this.activePage) {
return
}
this.activePage -= 1
this.scrollToActivePage()
},
goToPage(index) {
if (this.scrollDisabled) {
return
}
this.activePage = index
this.scrollToActivePage()
},
handleScroll() {
// If scrolling to top do nothing
if (!window.scrollY) {
return
}
if (this.activePage < this.page.childPages.length - 1) {
window.scrollTo(0, 0)
}
},
initPage() {
if (this.$route.query.service) {
this.activePage = this.getServicePageId(this.$route.query.service)
}
},
isServiceActiveOrIsLatestService(slug) {
const servicePageId = this.getServicePageId(slug)
// Service is active
if (this.activePage === servicePageId) {
return true
}
const latestServicePageId = this.page.childPages.length - 1
// Service is the latest and active page is over it (user is looking the footer)
return (
servicePageId === latestServicePageId &&
this.activePage > latestServicePageId
)
},
onKeyDown(e) {
const nextPageKeys = [
34, // Page down
39, // Arrow right
40 // Arrow down
]
const previousPageKeys = [
33, // Page up
37, // Arrow left
38 // Arrow up
]
if (nextPageKeys.includes(e.keyCode)) {
this.goToNextPage()
} else if (previousPageKeys.includes(e.keyCode)) {
this.goToPreviousPage()
}
},
onMouseWheel(event) {
const now = +new Date()
const millisecondsSinceLastEvent = this.lastWheelEvent
? now - this.lastWheelEvent
: 0
const eventsLimitReached = this.wheelEventsCount > this.wheelEventsLimit
const stopTime = this.wheelStopTime
const delta = Math.sign(event.deltaY)
const directionChanged = delta !== 0 && this.lastWheelDirection !== delta
this.lastWheelEvent = now
if (directionChanged) {
this.lastWheelDirection = delta
}
if (
!directionChanged &&
!eventsLimitReached &&
millisecondsSinceLastEvent &&
millisecondsSinceLastEvent <= stopTime
) {
this.wheelEventsCount += 1
return
}
this.wheelEventsCount = 0
if (delta === -1) {
this.goToPreviousPage()
} else {
this.goToNextPage()
}
},
onTouchEnd(e) {
const now = +new Date()
const touchEndX = e.changedTouches[0].clientX
const touchEndY = e.changedTouches[0].clientY
// Try to guess single touch based on touch start - touch end time
const isSingleTouch = now - this.touchTimer <= 100
// Single touch
if (isSingleTouch && this.touchStart.x === touchEndX) {
const horizontalPercentage = Math.ceil(
(touchEndX * 100) / window.innerWidth
)
const verticalPercentage = Math.ceil(
(touchEndY * 100) / window.innerHeight
)
if (horizontalPercentage <= 40) {
this.goToPreviousPage()
return
}
if (horizontalPercentage >= 60) {
this.goToNextPage()
return
}
if (verticalPercentage <= 40) {
this.goToPreviousPage()
return
}
if (verticalPercentage >= 60) {
this.goToNextPage()
return
}
}
// Touch move
if (this.touchStart.y > touchEndY + 5) {
this.goToNextPage()
} else if (this.touchStart.y < touchEndY - 5) {
this.goToPreviousPage()
}
},
onTouchStart(e) {
this.touchTimer = +new Date()
this.touchStart = {
x: e.touches[0].clientX,
y: e.touches[0].clientY
}
},
onVisibilityChanged(isVisible, entry) {
if (isVisible) {
entry.target.classList.add('dynamic-active')
} else {
entry.target.classList.remove('dynamic-inactive')
}
},
scrollToActivePage() {
this.scrollToService(this.page.childPages[this.activePage].slug)
},
scrollToRef(ref) {
if (!this.$refs[ref]) {
return
}
if (this.$refs[ref][0]) {
this.$scrollTo(this.$refs[ref][0], 100, {
force: true,
cancelable: false
})
} else {
this.$scrollTo(this.$refs[ref], 100, { force: true, cancelable: false })
}
this.disableScrolling()
},
scrollToService(slug) {
this.scrollToRef(`service-${slug}`)
},
serviceBgImageUrl(service) {
return require(`~/assets/img/services/backgrounds/${service.slug}.jpg`)
}
},
head() {
const data = {
bodyAttrs: {
class: 'services'
}
}
if (this.page.data) {
data.title = this.page.data.title
data.meta = this.page.metadata
}
return data
}
}
导出默认值{
布局:“空”,
组成部分:{
页脚,
标志
洛蒂动画,
ServiceIcon,
关闭
},
异步数据({app}){
试一试{
return wait app.$api.$get('/services.json'))
}捕获(错误){
返回{
错误
}
}
},
数据(){
返回{
activePage:0,
配置:{},
错误:null,
goToPageTimer:null,
isTouchpad:null,
页码:{},
禁用滚动条:false,
百分比:0,
scrollPercentageOld:0,
滚动方向:空,
滚动计时器:空,
touchStart:null,
touchTimer:null,
lastWheelDirection:空,
lastWheelEvent:null,
wheelEventsCount:0,
wheelEventsLimit:25,
车轮停止时间:120
}
},
观察:{
滚动百分比(新值、旧值){
this.scrollDirection=newValue>oldValue?'bottom':'top'
如果(this.scrollDirection==='bottom'){
this.goToNextPage()
}否则{
this.goToPreviousPage()
}
}
},
安装的(){
window.addEventListener('keydown',this.onKeyDown)
window.addEventListener('scroll',this.handleScroll)
window.addEventListener('wheel',this.onMouseWheel)
window.addEventListener('touchend',this.onTouchEnd)
window.addEventListener('touchstart',this.onTouchStart)
this.initPage()
},
销毁(){
window.removeEventListener('keydown',this.onKeyDown)
window.removeEventListener('scroll',this.handleScroll)
window.removeEventListener('wheel',this.onmouseheel)
window.removeEventListener('touchend',this.onTouchEnd)
window.removeEventListener('touchstart',this.onTouchStart)
},
方法:{
禁用滚动(){
this.scrollDisabled=true
if(this.goToPageTimer){
clearTimeout(this.goToPageTimer)
}
this.goToPageTimer=setTimeout(()=>{
this.scrollDisabled=false
}, 30)
},
getServicePageId(slug){
让servicePageId=null
Object.keys(this.page.childPages).forEach((pageId)=>{
if(this.page.childPages[pageId].slug==slug){
servicePageId=parseInt(pageId)
}
})
返回服务页面ID
},
goToNextPage(){
如果(
此文件已禁用||
this.activePage==this.page.childPages.length
) {
返回
}
this.activePage=this.activePage==null?0:this.activePage+1
if(this.activePagelatestServicePageId
)
},
onKeyDown(e){
const nextPageKeys=[
34,//向下翻页
39,//向右箭头
40/向下箭头
]
const previousPageKeys=[
33,//翻页
37,//向左箭头
38/向上箭头
]
if(下一页键。包括(例如键码)){
this.goToNextPage()
}else if(上一页键。包括(例如键码)){
this.goToPreviousPage()
}
},
onMouseWheel(事件){
const now=+新日期()
const毫秒ssincelastEvent=this.lastWheelEvent
?现在-这是最后一次事件
: 0
const eventsLimitReached=this.wheeleventscont>this.wheelEventsLimit
const stopTime=此.wheelStopTime
常量增量=数学符号(event.deltaY)
const directionChanged=delta!==0&&this.lastweeldirection!==delta
this.lastWheelEvent=现在
如果(方向改变){
此.lastWheelDirection=delta
}
如果(
!方向已更改&&
!eventslimitreach&&
毫秒nClastEvent&&
毫秒nClastEvent stackblitz