小編給大家分享一下vue中怎么利用iscroll.js解決pc端滾動問題,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
站在用戶的角度思考問題,與客戶深入溝通,找到康馬網(wǎng)站設(shè)計與康馬網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站建設(shè)、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名與空間、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋康馬地區(qū)。vue是什么Vue是一套用于構(gòu)建用戶界面的漸進式JavaScript框架,Vue與其它大型框架的區(qū)別是,使用Vue可以自底向上逐層應(yīng)用,其核心庫只關(guān)注視圖層,方便與第三方庫和項目整合,且使用Vue可以采用單文件組件和Vue生態(tài)系統(tǒng)支持的庫開發(fā)復(fù)雜的單頁應(yīng)用。
項目中經(jīng)常遇到區(qū)域超出部分會出現(xiàn)滾動條,滾動條在pc端可以通過鼠標(biāo)滾輪控制上下,在移動端可以通過鼠標(biāo)拖動頁面進行滾動,這兩種場景都是符合用戶習(xí)慣,然而這種滾動條一般都是豎【vertical】項滾動條,如果pc端出現(xiàn)橫向滾動條【horizontal】,在不做處理的情況下,你只能用鼠標(biāo)拖動橫向滾動條按鈕【scrollerbar】展示滾動區(qū)域,而且為了美觀,一般滾動條會進行樣式編寫或者隱藏,那么橫向區(qū)域默認情況下就沒法滾動。
二、描述
現(xiàn)為了解決pc端滾動區(qū)域能像移動端一樣,能夠通過鼠標(biāo)拖動滾動區(qū)域直接進行滾動,如圖所示
pc端滾動示例圖
滾動實例用到知識點如下:
采用vue-cli3+iscroll.js組合的方式;
使用 vue 自定義指令實現(xiàn) iscroll 實例化和參數(shù)配置;
實現(xiàn)橫向滾動區(qū)域和豎向滾動區(qū)域之間的聯(lián)動;
實現(xiàn)橫向滾動條居中顯示和使用scrollIntoView()方法的差別
三、自定義指令 v-iscroll
1、新建指令文件
這里使用 vue 自定義指令初始化 iscroll 實例,在 vue-cli3 項目目錄下新建vIscroll.js,文件代碼如下:
const IScroll = require('iscroll') const VIScroll = { install: function (Vue, options) { Vue.directive('iscroll', { inserted: function (el, binding, vnode) { let callBack let iscrollOptions = options <!--vue組件中綁定的兩個參數(shù) option、instance--> const option = binding.value && binding.value.option const func = binding.value && binding.value.instance // 判斷輸入?yún)?shù) const optionType = option ? [].toString.call(option) : undefined const funcType = func ? [].toString.call(func) : undefined // 兼容 google 瀏覽器拖動 el.addEventListener('touchmove', function (e) { e.preventDefault() }) // 將參數(shù)配置到new IScroll(el, iscrollOptions)中 if (optionType === '[object Object]') { iscrollOptions = option } if (funcType === '[object Function]') { callBack = func } // 使用vnode綁定iscroll是為了讓iscroll對象能夠夸狀態(tài)傳遞,避免iscroll重復(fù)建立 // 這里面跟官方網(wǎng)站 const myScroll = new IScroll('#wrapper',option) 初始化一樣 vnode.scroll = new IScroll(el, iscrollOptions) // 如果指令傳遞函數(shù)進來,把iscroll實例傳遞出去 if (callBack) callBack(vnode.scroll) }, componentUpdated: function (el, binding, vnode, oldVnode) { // 將scroll綁定到新的vnode上,避免多次綁定 vnode.scroll = oldVnode.scroll // 使用 settimeout 讓refresh跳到事件流結(jié)尾,保證refresh時數(shù)據(jù)已經(jīng)更新完畢 setTimeout(() => { vnode.scroll.refresh() }, 0) }, unbind: function (el, binding, vnode, oldVnode) { // 解除綁定時要把iscroll銷毀 vnode.scroll = oldVnode.scroll vnode.scroll.destroy() vnode.scroll = null } }) } } module.exports = VIScroll
這里附上 iscroll.js 5 官方文檔地址, iscroll npm 包地址,相關(guān)屬性和方法自行查看。
2、加載引用指令
首先在 main.js 中加載指令:
import Vue from 'vue' import App from './App.vue' import "./assets/reset.css" // 加載scroll指令 import VIscroll from './directive/vIscroll' Vue.use(VIscroll) Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app')
使用指令,摘自 tabList.vue 組件部分代碼如下:
<template> <div class="tab-container"> <div class="scroll-container" v-iscroll="{ option: iscrollConf, instance: getIscroll }" ref="scrollContainer" > <ul class="tab-li-container" ref="tabLiContainer" > <li class="tab-li-item" v-for="(item, index) in list" :key="item.id" :id="item.id" ref="tabItem" @click="tabEvent(item, index)" > <div class="item" :class="{ 'item-active': currentId == item.id }" >{{item.num}}</div> </li> </ul> </div> <div class="tab-left" @click="tabBtnEvent('left')" ><</div> <div class="tab-right" @click="tabBtnEvent('right')" >></div> </div> </template> <script> export default { props: ['list'], data () { return { iscrollConf: { bounce: true, mouseWheel: true, click: true, scrollX: true, scrollY: false }, currentId: null, currentIndex: 0, myScroll: null } }, mounted () { this.$refs.tabLiContainer.style.width = this.$refs.tabItem[0].offsetWidth * this.list.length + 'px' this.$nextTick(() => { this.myScroll.refresh() }) }, methods: { tabEvent (item, currentIndex) { <!--點擊某個li 按鈕事件處理邏輯--> }, tabBtnEvent (direction) { <!--左右切換邏輯事件--> }, getIscroll (iscroll) { this.myScroll = iscroll } }, watch: { list: { handler (l) { this.currentId = l[0].id }, immediate: true, deep: true } } } </script> <style scoped> // 樣式 </style>
上述代碼中 v-iscroll 指令傳入兩個字段參數(shù):
option:配置iscroll參數(shù),這里面注意scrollX,scrollY兩個屬性,代表的是橫向還是豎向滾動;
instance:回調(diào)方法的調(diào)用, vIscroll.js 中執(zhí)行回調(diào)方法,通過該組件方法 getIscroll() 獲取到 iscroll 的實例。
3、上下滾動區(qū)域聯(lián)動
上面的代碼可以解決開篇場景中的問題,現(xiàn)在實現(xiàn)上下區(qū)域聯(lián)動,通過點擊橫向滾動條某個按鈕,使其變成選中狀態(tài),然后豎向滾動條對應(yīng)的項跳到首位,如圖所以:
聯(lián)動示例圖
3-1、聯(lián)動實現(xiàn)方法
點擊按鈕的方法:
tabEvent (item, currentIndex) { this.currentId = item.id this.currentIndex = currentIndex <!--這里實現(xiàn)按鈕始終居中顯示,暫時省略,下面補充--> ... <!--傳給豎向滾動組件--> this.$emit("switchTab", this.currentId, this.currentIndex) },
豎向滾動區(qū)域組件【App.vue】代碼部分如下,并對 switchTab() 方法進行詳細注釋:
<template> <div id="app"> <TabList :list="list" @switchTab="switchTab" ></TabList> <!-- v-iscroll="defalutOption" --> <div v-iscroll="{ option: defalutOption, instance: getIscroll }" class="tab-content-container" ref="detailItemContainer" > <ul class="tab-list-container"> <li v-for="item in list" :key="item.id" class="list-item" ref="detailItem" > <div>{{item.value}}</div> </li> </ul> </div> </div> </template> <script> import TabList from './components/tabList.vue' export default { name: 'App', components: { TabList, }, data () { return { list: [ { id: 1, value: '這是第1題', num: 1 }, <!--...省略數(shù)據(jù)展示--> { id: 16, value: '這是第16題', num: 16 } ], defalutOption: { bounce: true, mouseWheel: true, click: true, scrollX: false, scrollY: true }, myScroll: null } }, methods: { switchTab (currentId, currentIndex) { <!--對選中的當(dāng)前項,這里就是“3”按鈕對應(yīng)的“這是第3題”,求出它距離父元素的上邊距offsetTop值--> const offsetTop = this.$refs.detailItem[currentIndex].offsetTop <!--滾動的范圍不能超過這個滾動體的底部,這里面用到iscroll的屬性maxScrollY--> const y = offsetTop >= Math.abs(this.myScroll.maxScrollY) ? this.myScroll.maxScrollY : -offsetTop <!--調(diào)用iscroll的方法進行滾動到相應(yīng)的位置--> this.myScroll.scrollTo(0, y) }, <!--獲取實例--> getIscroll (iscroll) { this.myScroll = iscroll } } } </script> <style scoped> <!--樣式--> ... </style>
這里面用到的都是 iscroll 插件自帶的屬性和方法進行滾動邊界的判斷和滾動,比用 JavaScript 方法方便的多,而且用了iscroll作為滾動容器,已經(jīng)在vIscroll.js禁用了相關(guān)瀏覽器默認事件。
3-2、居中顯示
這里 JavaScript 有個 scrollIntoView() 方法, 官方文檔鏈接 ,這個方法讓當(dāng)前的元素滾動到瀏覽器窗口的可視區(qū)域內(nèi)。關(guān)鍵缺點是,如果橫向滾動和豎向滾動都同時用到這個方法,只能保證一個滾動區(qū)域有效,另一個會不滾動。
使用 scrollIntoView() 方法配置如下:
this.$refs.tabItem[this.currentIndex].scrollIntoView({ behavior: "smooth", inline: "center", block: 'nearest' })
這里在橫向滾動區(qū)域添加了一對左右按鈕,實現(xiàn)切換功能,如圖所示:
切換按鈕示例圖
切換按鈕事件方法就是通過改變上一個、下一個按鈕下標(biāo),調(diào)用方法,實現(xiàn)切換功能,切換事件方法邏輯如下:
tabBtnEvent (direction) { const max = this.$refs.tabItem.length if (direction === 'left' && this.currentIndex > 0) { this.currentIndex-- } if (direction === 'right' && this.currentIndex < max - 1) { this.currentIndex++ } <!--調(diào)用單擊按鈕事件--> this.tabEvent(this.$refs.tabItem[this.currentIndex], this.currentIndex) },
下面對 單擊按鈕事件 添加居中邏輯,詳細代碼和解析圖如下,可以對比查看:
居中計算圖
tabEvent (item, currentIndex) { this.currentId = item.id this.currentIndex = currentIndex // 獲取滾動容器的長度的一半,即中間點 const scrollContainerHalfWidth = this.$refs.scrollContainer.offsetWidth / 2 // 獲取單個item的一半長度 const tabItemHalfWidth = this.$refs.tabItem[currentIndex].offsetWidth / 2 // 求取插值,就是開始到中間開始位置的距離 const halfDistance = scrollContainerHalfWidth - tabItemHalfWidth // 求取當(dāng)前item的相對總長度的偏移量 const currentItemOffsetLeft = this.$refs.tabItem[currentIndex].offsetLeft // scroll 移動到中間的值 const x = halfDistance - currentItemOffsetLeft this.myScroll.scrollTo(x, 0) this.$emit("switchTab", this.currentId, this.currentIndex) },
4、總結(jié)
1、整個實例用的都是iscroll插件相關(guān)屬性實現(xiàn)的滾動,避免同時使用JavaScript方法造成的代碼混亂;
2、利用自定義指令的方式有效的避免了傳統(tǒng)實例化iscroll帶來的代碼冗余,使其方便簡潔;
3、本實例滾動選項都是字符串,如果出現(xiàn)圖片的情況,合理使用iscroll.refresh() 方法,在正確的時期重新計算滾動區(qū)域,避免滾動邊界受限;
以上是“vue中怎么利用iscroll.js解決pc端滾動問題”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
文章標(biāo)題:vue中怎么利用iscroll.js解決pc端滾動問題-創(chuàng)新互聯(lián)
網(wǎng)頁網(wǎng)址:http://aaarwkj.com/article0/ggjoo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、靜態(tài)網(wǎng)站、App設(shè)計、外貿(mào)建站、品牌網(wǎng)站制作、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容