700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > vue watch 修改滚动条_vue实现滚动监听 点击瞄点平滑滚动 控制内嵌滚动条滚动...

vue watch 修改滚动条_vue实现滚动监听 点击瞄点平滑滚动 控制内嵌滚动条滚动...

时间:2019-01-27 06:23:53

相关推荐

vue watch 修改滚动条_vue实现滚动监听 点击瞄点平滑滚动 控制内嵌滚动条滚动...

滚动效果

当页面滑动时,左边导航栏会自动定位到当前标题,一级标题展开,二级标题的字体变红色,字体前面有一个小图标。

上图。。。。。。。。。。。

Html代码

{{NItem1.ordered}}{{NItem1.title}}

{{NItem1.ordered}}.{{NItem2.ordered}}{{NItem2.title}}

{{VideoList.title}}

{{AuthorList.name}}

{{VideoList.create_time}}

{{VideoList.view_num}}

6666

一、明确各种位置

图片来源于网络

这次项目最常用的就是 scrollTop 、offsetTop

其中 srcollTop可以理解为 :页面随着滚动条下滑而隐藏的高度

offsetTop 可以理解为 :当前元素距离它最近的祖先元素顶部的距离,并且这个祖先元素的position不为static。如果没有,则是该元素与body顶部的距离

二、滚动思路

滚动到什么地方,左边导航栏出现样式??

当滚动的高度>=右边第i个div的offsetTop,则左边的第i个标题出现样式。

三、添加滚动监听事件

1.添加滚动监听事件

知识点:addEventListener() 方法,事件监听

用法:element.addEventListener(event, function, useCapture);

第一个参数是:事件的类型。这个项目是滚动监听,所以event是写“scroll”。(其他项目可根据需求,如果是点击就写“click”,以此类推);

第二个参数是:监听事件时调用的函数。这里调用的是 this.menu 这个函数。

第三个参数是:布尔值。即true/false,这个参数是与事件捕获和事件冒泡有关,与这两个有关一般是点击事件,这个项目是滚动事件,所以第三个参数可以不写。

mounted(){

window.addEventListener("scroll",this.menu)

}

2.在data里面定义一个字符串scroll存放滚动的高度也就是scrollTop,并且在watch中监听data里面scroll的数据变化。

data(){

return{

scroll:""

}

},

watch(){

srcoll:function(){

//这里放的函数下面讲到

}

}

四、在methods定义方法,主要有三个步骤

1.触发滚动监听事件时,调用的函数,此函数的作用是获取滚动条的高度

menu:function(){

this.srcoll=window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;

}

//兼容不同的三个浏览器版本

//也就是上文调用的函数window.addEventListener("scroll",this.menu)

2.定义一个平滑滚动的方法,参考网络上的大神写的。

定义变量total=div[index].offsetTop,则滚动条就需要滚动这个total的距离。

为了达到平滑滚动的效果,把总距离total分成50个小段,每10ms执行一次。

并且还要区分是向上滑动还是向下滑动,完整代码如下:

jump:function(index){ //把左边导航栏li的下标传进来。

this.isshow=index;//使左边导航出现相应的样式

let divArr=document.querySelectorAll(".notes_text");//获取右边的div数组

let total=divArr[index].offsetTop;//获取第index个div到窗口顶部的距离

let distance = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset//获取滚动条的高度(兼容三种浏览器版本)

//平滑滚动的效果,把总距离分成50个小段,每10ms执行一次

let step = total / 50

if (total > distance) { //当divArr.[index]offsetTop的距离>滚动条的距离,向下滑动,此时滑动的距离是total

smoothDown() //向下滑动

} else {

let newTotal = distance - total //当div到窗口的距离

step = newTotal / 50;

smoothUp()

}

//向下滑动

function smoothDown () {

if (distance < total) {

distance = distance + step

document.body.scrollTop = distance

document.documentElement.scrollTop = distance

window.pageYOffset = total;

setTimeout(smoothDown, 10)

} else {

document.body.scrollTop = total

document.documentElement.scrollTop = total

window.pageYOffset = total;

}

}

//向上滑动

function smoothUp () {

if (distance > total) {

distance -= step

document.body.scrollTop = distance

document.documentElement.scrollTop = distance

window.pageYOffset = total;

setTimeout(smoothUp, 10)

} else {

document.body.scrollTop = total

document.documentElement.scrollTop = total

window.pageYOffset = total;

}

}

}

3.定义方法实现当滚动条的高度>divArr[index].offsetTop时,左边样式改变的函数

loadSroll: function () {

let divArr=document.querySelectorAll(".notes_text");//获取右边div的数组

for (var i = 0; i < divArr.length; i++) {

if (this.scroll >= divArr[i].offsetTop) { //滚动条的高度>divArr[index].offsetTop,左边导航栏样式改变

var OrderId = divArr[i].getAttribute("data-id");//获取div中data-id的属性值。为了实现左边一级标题打开的效果

this.UnderTitle={id:OrderId,isshow:true};//实现一级标题打开

this.isshow = i;//实现字体变红,小图标出现

//控制左边内嵌滚动条滚动

var lOffsetTop = document.getElementById("lNav"+i).offsetTop;//获取左边导航栏li距离li最近的祖先元素id为left_y_scroll的元素的顶部的距离。(left_y_scroll的position为fixed),详情见下图

if(lOffsetTop > 300){ //当li的offsetTop大于300时,滚动条需要下滑,因为整个div的高度为350px,所以我这里设置了300

this.$refs.lys.scrollTop = lOffsetTop; //使子滚动条的滚动高度,等于lOffsetTop

}else{

this.$refs.lys.scrollTop = 0;//在不大于300的情况下,子滚动条的高度为0.

}

}

}

}

这里的这个函数,需要放在watch里面,因为这里的this.srcoll 是data里面的srcoll,而srcoll是靠watch监听。

所以我们需要在watch()里面写:

watch(){

srcoll:function(){

this.loadSroll()

}

}

lOffsetTop的距离如下图

滚动监听的效果,就可以实现了

完成代码如下!!!!!

import NavTop from "@/components/NavTop.vue"

import FooterContainer from "@/components/FooterContainer.vue"

export default{

components:{

NavTop,

FooterContainer

},

created(){

this.init();

},

data(){

return{

chapList:[],//一级标题和二级标题的数组

VideoList:[],

AuthorList:[],

epiList:[],

UnderTitle:"",//左边导航栏的状态判断,其中isshow为true且id相符时,显示

scroll:"",//存储滚动条的高度

isshow:-1,//默认导航栏小图标不显示,点击之后显示

left_up:false,

}

},

watch: {

scroll: function () { //用来监听data中的scroll字符串的变化

this.loadSroll()

}

},

mounted() {

window.addEventListener('scroll', this.menu);//在mounted钩子中给window添加一个滚动监听事件

},

methods:{

init:function(){

this.getVideoDetail();

},

getVideoDetail:function(){

this.$axios.get(this.GLOBAL.host+"/pub/api/v1/web/video_detail",{

params:{

video_id:this.$route. query.video_id

}

}).then(res =>{

//console.log(res.data.data);

this.VideoList=res.data.data.video;

this.AuthorList=res.data.data.author;

this.chapList=res.data.data.chapter_list;

//console.log(this.chapList);

for(var i=0;i

for(var j=0;j

this.epiList.push(this.chapList[i].episodeList[j])

for(var k=0;k

this.epiList[k].id=k+1;

//console.log(k)

}

}

}

//console.log(this.epiList);

});

},

UpClick:function(id){

if(typeof this.UnderTitle.isshow=="underfine"||this.UnderTitle.id!=id){

this.UnderTitle={id:id,isshow:true}

}else{

//当点击两次以上,ul隐藏的情况

this.UnderTitle.isshow=!this.UnderTitle.isshow;

}

},

menu:function(){

//获取滚动条的高度

this.scroll=window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;

},

jump:function(index){

this.isshow=index;//使左边导航出现相应的样式

//console.log(index)

let divArr=document.querySelectorAll(".notes_text");//获取右边的div数组

let total=divArr[index].offsetTop;//获取第index个div的offsetTop距离

let distance = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset//获取滚动条的高度(兼容三种浏览器版本)

//平滑滚动的效果,把总距离分成50个小段,每10ms执行一次

let step = total / 50

if (total > distance) { //当div到窗口的距离>滚动条的距离,向下滑动,此时滑动的距离是total

smoothDown() //向下滑动

} else {

let newTotal = distance - total //当div到窗口的距离

step = newTotal / 50;

smoothUp()

}

//向下滑动

function smoothDown () {

if (distance < total) {

distance = distance + step

document.body.scrollTop = distance

document.documentElement.scrollTop = distance

window.pageYOffset = total;

setTimeout(smoothDown, 10)

} else {

document.body.scrollTop = total

document.documentElement.scrollTop = total

window.pageYOffset = total;

}

}

//向上滑动

function smoothUp () {

if (distance > total) {

distance -= step

document.body.scrollTop = distance

document.documentElement.scrollTop = distance

window.pageYOffset = total;

setTimeout(smoothUp, 10)

} else {

document.body.scrollTop = total

document.documentElement.scrollTop = total

window.pageYOffset = total;

}

}

},

loadSroll: function () {

let divArr=document.querySelectorAll(".notes_text");

//console.log(divArr)

for (var i = 0; i < divArr.length; i++) {

if (this.scroll >= divArr[i].offsetTop - 88 ) { //这里其实可以减去一个数值,使其左边的导航栏的样式提前出现,我这里是减去了top栏的高度。

//console.log(i)

var OrderId = divArr[i].getAttribute("data-id");

//console.log(OrderId);

this.UnderTitle={id:OrderId,isshow:true};

this.isshow = i;

var lOffsetTop = document.getElementById("lNav"+i).offsetTop;//获取li到窗口的距离

console.log(lOffsetTop);

if(lOffsetTop > 300){ //当li的offsetTop大于300时,滚动条需要下滑,因为整个div的高度为350px,所以我这里设置了300

this.$refs.lys.scrollTop = lOffsetTop; //使子滚动条的滚动高度,等于lOffsetTop

}else{

this.$refs.lys.scrollTop = 0;//在不大于300的情况下,子滚动条的高度为0.

}

}

}

}

},

}

前端新手,代码冗长,有不合理和需要改进的地方麻烦提出

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。