滚动监听

better-scroll 无法滚动的分析,直接翻到最后,看问题汇总,希望能帮助你解决。

  借用一下人家这个好看的项目图片,做一个解释。左边的内容会跟右边的内容一起关联,点击左边的菜单,右边会滚动到对应菜单的内容区域;滚动右边的内容,左边会滚动到对应的菜单项。 就是这个简单的左右关联的项目。方法提供了两个。

jq的方法:

定义两个方法:滚动的一个方法,和点击的方法。

滚动方法:

  1. const _scrollMethod = function(){
  2. document.addEventListener('scroll', function (e) {
  3. e.preventDefault();
  4. let sectionTitle = $('.icl-section-list-contents'); //获取到list 的内容 ,下面将对这个 列表做遍历
  5. let screenHeight = $(window).height();
  6. let scrollTop = $(window).scrollTop();
  7. let scrollHeight = $(document).height();
  8. let sectionTitleHeight = $('.icl-section-list-contents').height();
  9. sectionTitle.each(function() { // 遍历里面的内容,抓取里面的每个标题的位置,做下面的高度比较逻辑处理
  10. let sectionTitleTop = $(this).offset().top - scrollTop;
  11. if(scrollTop+sectionTitleHeight>screenHeight){
  12. if(sectionTitleTop<(screenHeight/2)) {
  13. var index = sectionTitle.index($(this));
  14. $('.sectionList').find('.list-group-item').removeClass('active');
  15. $('.sectionList').find('.list-group-item').eq(index).addClass(function (index, activeClass) {
  16. activeClass = 'active';
  17. // console.log($(this))
  18. return activeClass;
  19. });
  20. }
  21.  
  22. }
  23. })
         // 滚到最后的内容,如果当节list 标题无法滚动到屏幕中间的位置的时候,给左边最后一个菜单,追加class
  24.   if(scrollTop + screenHeight == scrollHeight){
  25. $('.sectionList').find('.list-group-item').removeClass('active');
  26. $('.sectionList').find('.list-group-item').last().addClass('active');
  27. }
          // 给第一个追加class
  28. if ($(window).scrollTop() < 10 ){
  29. $('.sectionList').find('.list-group-item').removeClass('active');
  30. $('.sectionList').find('.list-group-item').eq(0).addClass('active');
  31. }
  32. }, false);
  33. }

点击菜单的方法:

  1. const _scroll =function () {
  2. $('.sectionList .list-group-item').click(function () {
  3. let chapterListTile = $('.list-group-item');
  4. let _this = this;
  5. let chapterIndex = chapterListTile.index(_this);
  6. var _thisScroll = $('.icl-section-list-contents').eq(chapterIndex);
          // jq 的animate 的动画方法,第一个参数滚动的距离,第二个参数 滚动时间 ,第三回掉函数
  7. $('html').animate({scrollTop:_thisScroll.offset().top - '200'}, 1000, function () {
  8. $('.sectionList').find('.list-group-item').removeClass('active');
  9. $(_this).addClass('active');
  10. let sectionId = $(_this).find('.icl-section-name').attr('id');
  11. });
  12. })
  13. }

上面的代码针对具体的项目,左右分栏,css 忽略。上面的方法,在抓取对应的index的时候,判断遍历当前的list的标题的位置,在当前屏幕的中间位置以上,才抓取index。 改进方法: 采用区间方法,遍历数组后,获取高度累加,形成一个数组, listHeigt + = current.clinetHeight

在vue 项目的一个插件方法:

引用一个插件 better-scroll

安装

npm install better-scroll --save 

使用 (导入)

import BScroll from 'better-scroll'

这样项目中就有了一个 BScroll 的对象。接下来就要初始化这个 BScroll 对象。

代码如下:

  1. mounted () { // 只有dom 在页面显示完全后,bs 才能抓到高度,如果在那种tab 标签的形式中,在display:none的情况下,无法抓取高度
  2. this.$nextTick(() => {
  3. this._initScroll(); // 将初始化的方法,封装在这个方法中,下面就是对应的方法
  4. this.calculateHeight();
  5. })
  6. },
_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的值')
  });
},
  1.  

在贴上计算高度的方法:

  1. calculateHeight () {
  2. var contentWrapper = this.$refs.foodList; // == $('.el')
  3. let height = 0;
  4. this.listHeight.push(height);
  5. for(var i=0;i<contentWrapper.length;i++) {
  6. let item = contentWrapper[i];
  7. height += item.clientHeight; // 获得每个区间的高度
  8. this.listHeight.push(height);
  9. // console.log(this.listHeight,'listheight')
  10. }
  11. },

计算属性的一个方法:

  1. computed: {
  2. currentIndex () {
  3. for (let i = 0; i < this.listHeight.length; i++) {
  4. let height1 = this.listHeight[i];
  5. let height2 = this.listHeight[i + 1];
  6. if (!height2 || (this.scrollY >= height1 && this.scrollY < height2)) {
  7. return i;
  8. }
  9. }
  10. return 0;
  11. },
  12. },

点击菜单的一个方法:

  1. selectMenu(index) {
  2. let foodList = this.$refs.foodList;
  3. let el = foodList[index];
  4. this.contentScroll.scrollToElement(el, 500); // bs 提供的滚动方法
  5. },

这里左右联动的思想就是,抓取右边元素的高度位置,然后看当前的高度在哪个高度区间,就把这个 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 对象,确保实例化之前,高度得有)

以上是我个人的一些见解,如有不妥,欢迎指出,一起交流。

better-scroll不能滚动之 滚动监听-左右联动的更多相关文章

  1. 对ListView滚动状态的监听

    有的时候,我们需要对ListView滚动做一个相应的监听事件,例如:要实现如下图通讯录的功能: 思路为:首先呢,中间那个"路"字为一个TextView,它与ListView采用相对 ...

  2. 【Flutter】可滚动组件之滚动控制和监听

    前言 可以用ScrollController来控制可滚动组件的滚动位置. 接口描述 ScrollController({ // 初始滚动位置 double initialScrollOffset = ...

  3. bootstap 滚动监听

    ---首先结合源代码介绍官网的说明 ---然后总结了使用滚动监听的几个步骤 ---最后给出一个简单的例子 ---关键的一点:整体有点零散和乱七八糟,辛苦你的思维和眼睛了,呵呵 ------------ ...

  4. js进阶 12-6 监听鼠标滚动事件和窗口改变事件怎么写

    js进阶 12-6 监听鼠标滚动事件和窗口改变事件怎么写 一.总结 一句话总结:滚动事件scroll(),浏览器窗口调整监听resize(),思考好监听对象. 1.滚动事件scroll()的监听对象是 ...

  5. 监听页面中的某个div的滚动事件,并将其滚动距离保存到cookie

    在html中,写一个id为type的div: <div class="type" id="type"></div> css: .type ...

  6. 最优-scroll事件的监听实现

    1. 背景和目标 前端在监听scroll这类高频率触发事件时,常常需要一个监听函数来实现监听和回调处理.传统写法上利用setInterval或setTimeout来实现. 为了减小 CPU 开支,往往 ...

  7. onscroll事件没有响应的原因以及vue.js中添加onscroll事件监听的方法

    1 onscroll事件失效 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  8. 原生JS和JQuery代码编写窗口捕捉函数和页面视觉差效果(scroll()、offsetTop、滚动监听的妙用)

    想实现窗口滚动到一定位置时,部分网页的页面发生一些变化,但是手头没有合适的插件,所以就想到自己编写一个简易的方法, 想到这个方法要有很高的自由度和适应性,在这,就尽量的削减其功能,若有错误的地方或者更 ...

  9. 滚动监听(bootstrap)

    1.05 腊八节   一直都想知道滚动监听是怎么做出来的,今天终于扒拉出来了,在使用的时候只要加上div定位就可以了... <head> <link rel="styles ...

随机推荐

  1. 使用javascript正则表达式实现遍历html字符串

    最近在尝试实现一个js模板引擎,其中涉及到使用js解析html字符串的功能.由于我实现的这个模板不止是要能替换参数输出html字符串,还要可以解析出每个dom元素的名称及参数啥的. 网上找到了一个叫做 ...

  2. 关于APICloud读取不到虚拟机及数据库的问题

    工具:apicloud编辑器 虚拟机:夜神虚拟机(nox_setup_v6.0.1.0_full)版本 数据库:Oracle 11G 以为夜神虚拟机版本太高,进程adb.exe读取不出虚拟机和数据库, ...

  3. shell脚本小案例

    1.获取远程ftp数据到本地目录 #!/bin/bash ftp -n<<! open 135.0.24.19 user exchange exchange binary cd /idep ...

  4. 自学Python2.7-collections系列

    Python collections系列 Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供 ...

  5. 自学Python2.5-基本数据类型-set集合

    Python set集合 一. set集合概述 ①set集合,是一个无序且不重复的元素集合.②集合对象是一组无序排列的可哈希的值,集合成员可以做字典中的键.③集合支持用in和not in操作符检查成员 ...

  6. [UWP]了解模板化控件(6):使用附加属性

    1. 基本需求 之前的ContentView2添加了PointerOver等效果,和TextBox等本来就有Header的控件放在一起反而变得鹤立鸡群. 为了解决这个问题,这次把ContentView ...

  7. .Net Ajax跨域请求实现

    下一阵子要做一个网站Web储备一下知识,AJAX 实现跨域请求,估计会用到,以前在学  WebServer  时候老师整理的一个文档,现在便于查阅和使用现在放到我的博客中. 一般平时我写web页面的时 ...

  8. ligerUI---ligerGrid默认选中checkbox

    写在前面: ligerGrid中是可以带有checkbox(前面有可以选择打勾勾的框框)的,对于checkbox默认选中 这次项目中也要做,因为一个系统的增删改查,在修改一条数据的时候,是需要对原来的 ...

  9. Java面试题汇总

    第一阶段:三年我认为三年对于程序员来说是第一个门槛,这个阶段将会淘汰掉一批不适合写代码的人.这一阶段,我们走出校园,迈入社会,成为一名程序员,正式从书本 上的内容迈向真正的企业级开发.我们知道如何团队 ...

  10. node.js stream

    stream是一个接口,流是可以从一个读取或写入数据的目标对象 ,Node 中有很多对象实现了这个接口   一.nodejs stream类型 1. Readable - 可读操作. Writable ...