better-scroll不能滚动之 滚动监听-左右联动
滚动监听
better-scroll 无法滚动的分析,直接翻到最后,看问题汇总,希望能帮助你解决。
借用一下人家这个好看的项目图片,做一个解释。左边的内容会跟右边的内容一起关联,点击左边的菜单,右边会滚动到对应菜单的内容区域;滚动右边的内容,左边会滚动到对应的菜单项。 就是这个简单的左右关联的项目。方法提供了两个。
jq的方法:
定义两个方法:滚动的一个方法,和点击的方法。
滚动方法:
const _scrollMethod = function(){ document.addEventListener('scroll', function (e) { e.preventDefault(); let sectionTitle = $('.icl-section-list-contents'); //获取到list 的内容 ,下面将对这个 列表做遍历 let screenHeight = $(window).height(); let scrollTop = $(window).scrollTop(); let scrollHeight = $(document).height(); let sectionTitleHeight = $('.icl-section-list-contents').height(); sectionTitle.each(function() { // 遍历里面的内容,抓取里面的每个标题的位置,做下面的高度比较逻辑处理 let sectionTitleTop = $(this).offset().top - scrollTop; if(scrollTop+sectionTitleHeight>screenHeight){ if(sectionTitleTop<(screenHeight/2)) { var index = sectionTitle.index($(this)); $('.sectionList').find('.list-group-item').removeClass('active'); $('.sectionList').find('.list-group-item').eq(index).addClass(function (index, activeClass) { activeClass = 'active'; // console.log($(this)) return activeClass; }); } } }) // 滚到最后的内容,如果当节list 标题无法滚动到屏幕中间的位置的时候,给左边最后一个菜单,追加class if(scrollTop + screenHeight == scrollHeight){ $('.sectionList').find('.list-group-item').removeClass('active'); $('.sectionList').find('.list-group-item').last().addClass('active'); } // 给第一个追加class if ($(window).scrollTop() < 10 ){ $('.sectionList').find('.list-group-item').removeClass('active'); $('.sectionList').find('.list-group-item').eq(0).addClass('active'); } }, false); }
点击菜单的方法:
const _scroll =function () { $('.sectionList .list-group-item').click(function () { let chapterListTile = $('.list-group-item'); let _this = this; let chapterIndex = chapterListTile.index(_this); var _thisScroll = $('.icl-section-list-contents').eq(chapterIndex); // jq 的animate 的动画方法,第一个参数滚动的距离,第二个参数 滚动时间 ,第三回掉函数 $('html').animate({scrollTop:_thisScroll.offset().top - '200'}, 1000, function () { $('.sectionList').find('.list-group-item').removeClass('active'); $(_this).addClass('active'); let sectionId = $(_this).find('.icl-section-name').attr('id'); }); }) }
上面的代码针对具体的项目,左右分栏,css 忽略。上面的方法,在抓取对应的index的时候,判断遍历当前的list的标题的位置,在当前屏幕的中间位置以上,才抓取index。 改进方法: 采用区间方法,遍历数组后,获取高度累加,形成一个数组, listHeigt + = current.clinetHeight
在vue 项目的一个插件方法:
引用一个插件 better-scroll
安装
npm install better-scroll --save
使用 (导入)
import BScroll from 'better-scroll'
这样项目中就有了一个 BScroll 的对象。接下来就要初始化这个 BScroll 对象。
代码如下:
mounted () { // 只有dom 在页面显示完全后,bs 才能抓到高度,如果在那种tab 标签的形式中,在display:none的情况下,无法抓取高度 this.$nextTick(() => { this._initScroll(); // 将初始化的方法,封装在这个方法中,下面就是对应的方法 this.calculateHeight(); }) },
_initScroll () {
this.listScroll = new BScroll(this.$refs.newsListWrapper, {})
this.contentScroll = new BScroll(this.$refs.newsContentWrapper, {
probeType: 3, // 实时位置 暴露出来
});
this.contentScroll.on('scroll', (pos) => { // 这是bs 提供的一个滚动获取 y 值的方法,这个 y 值怎么算的
this.scrollY = Math.abs(Math.round(pos.y));
// console.log(this.scrollY,'scrolly的值')
});
},
在贴上计算高度的方法:
calculateHeight () { var contentWrapper = this.$refs.foodList; // == $('.el') let height = 0; this.listHeight.push(height); for(var i=0;i<contentWrapper.length;i++) { let item = contentWrapper[i]; height += item.clientHeight; // 获得每个区间的高度 this.listHeight.push(height); // console.log(this.listHeight,'listheight') } },
计算属性的一个方法:
computed: { currentIndex () { for (let i = 0; i < this.listHeight.length; i++) { let height1 = this.listHeight[i]; let height2 = this.listHeight[i + 1]; if (!height2 || (this.scrollY >= height1 && this.scrollY < height2)) { return i; } } return 0; }, },
点击菜单的一个方法:
selectMenu(index) { let foodList = this.$refs.foodList; let el = foodList[index]; this.contentScroll.scrollToElement(el, 500); // bs 提供的滚动方法},
这里左右联动的思想就是,抓取右边元素的高度位置,然后看当前的高度在哪个高度区间,就把这个 listHeight 的索引返回出来,用作 dom 上追加class的判断。
在vue 实例的 mounted 的方法中,初始化这个 bs 对象。
顺便解释一下这的 关于vue的两个知识点 mounted 和 $nextTick :
$nextTick : 官方api 下面说
也就是 在dom 渲染好后,再执行某个关于dom的 执行方法,比如,要取dom 上的某个数据,这里可以用 setTimeout 替换这个 $nextTick。
mounted : 官方api 下说
也就是 el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子,vue的 el 挂载到 dom 上后调用 这个方法
和created的方法不一样,created 是在 vue实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调, 但是挂载阶段还没开始,$el 属性目前不可见。
(更多关于 vue 的笔记陆续更新中)
better-scroll 的方法注意事项。
这个插件的作者说:
网上很多同学使用过后,会有发问求助说无法滚动,这时候,不要急先把 自己初始化的bs 打印出来看看。下面是我的:
垂直方向不能滚动的主要三个属性的 都不是正确的参数,说明,实例是初始化了,但是初始化后,相关的参数,它没有获取到,比如父级的高度和要滚动子集的高度。作者也强调了这个问题的关键,那么什么情况会导致这个 高度没有获取到呢?
我遇到的一个坑:在使用tab 标签里初始化一个未被激活的tab 项,这个没有被激活的项 dispaly:none ,高度无法获取。但是在 vue实例 执行后,这个 bs 已经初始化了,只不过初始化后的bs ,无法获取相关的高度到而已。然后,我一开始就让这个使用bs的 tab激活,然后就有了相关的 参数
然后就可以滚动了,所以总结问题呢:
遇到不能滚动的情况以下分析:
1。是否初始化了父级元素,需要滚动的子元素是否是第一个
2。打印bs 对象,查看是否有bs对象,相关的参数(上面图中已经画出),是否正确
3。父子高度是否有,且子高度大于父高度 (使用小诀窍: 先不要初始化这个bs,先看父子高度是否正确,再初始化这个bs 对象,确保实例化之前,高度得有)
以上是我个人的一些见解,如有不妥,欢迎指出,一起交流。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
K8s Security Best Practices-K8S安全最佳实践
关于安全-写在前面的:Security is complex and a process 安全是复杂的,而且是一个过程 Security combines many diffenrent things 安全结合了许多不同的东西 Environments change,security cannot stay in a certain state 环境变化,安全性不能保持一定状态 Attackers have advantage ***者有优势 3.1 . They decide time 他们决定的时间(任意时间) 3.2. They pick what to attack ,like weakest link 他们选择要***的内容,例如最薄弱的环节 1. Security Principles 安全原则 Defense in depth 深度防御 Least Privilege 最小权限原则 Limiting the Attack Surface 限制***面 Layered defence and Redundancy 分层防御和冗余 2. K8s Security Categ...
- 下一篇
熔断原理与实现Golang版
在微服务中服务间依赖非常常见,比如评论服务依赖审核服务而审核服务又依赖反垃圾服务,当评论服务调用审核服务时,审核服务又调用反垃圾服务,而这时反垃圾服务超时了,由于审核服务依赖反垃圾服务,反垃圾服务超时导致审核服务逻辑一直等待,而这个时候评论服务又在一直调用审核服务,审核服务就有可能因为堆积了大量请求而导致服务宕机 由此可见,在整个调用链中,中间的某一个环节出现异常就会引起上游调用服务出现一些列的问题,甚至导致整个调用链的服务都宕机,这是非常可怕的。因此一个服务作为调用方调用另一个服务时,为了防止被调用服务出现问题进而导致调用服务出现问题,所以调用服务需要进行自我保护,而保护的常用手段就是熔断 熔断器原理 熔断机制其实是参考了我们日常生活中的保险丝的保护机制,当电路超负荷运行时,保险丝会自动的断开,从而保证电路中的电器不受损害。而服务治理中的熔断机制,指的是在发起服务调用的时候,如果被调用方返回的错误率超过一定的阈值,那么后续的请求将不会真正发起请求,而是在调用方直接返回错误 在这种模式下,服务调用方为每一个调用服务(调用路径)维护一个状态机,在这个状态机中有三个状态: 关闭(Close...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS关闭SELinux安全模块
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作