在开发过程中程序员总会碰到产品经理提出的各种稀奇古怪的需求,尽管有些需求很奇葩,但不得不说有些须有还是能指引我们不断的学习与进步,最近在工作中就碰到这种问题。需求是要求在各主流浏览器上使用自定义的滚动条样式,并且达到完美兼容,此篇博客记录自己的分析过程。此篇博客的源码可访问slimscroll

为了能使用自定义的滚动条样式并且能在各主流浏览器上兼容,首先想到的就是css定制滚动条的样式。于是在网上搜索了下发现确实有这样的css样式存在:

ul::-webkit-scrollbar/*滚动条整体部分,其中的属性有width,height,background,border(就和一个块级元素一样)等。*/
ul::-webkit-scrollbar-button /*滚动条两端的按钮。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。*/
ul::-webkit-scrollbar-track /* 外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。*/
ul::-webkit-scrollbar-track-piece /*内层轨道,滚动条中间部分(除去)。*/
ul::-webkit-scrollbar-thumb /*滚动条里面可以拖动的那部分*/
ul::-webkit-scrollbar-corner /* 边角*/
ul::-webkit-resizer /*定义右下角拖动块的样式*/

这里只是初略的介绍下,具体的使用方法可参考这篇博客自定义浏览器滚动条的样式,打造属于你的滚动条风格

这种方法确实可以定制滚动条样式,但是仅仅是在webkit内核浏览器有效,不能达到完美兼容。上面的博客中推荐一种jquery插件来解决这个问题,但是介绍的并不全面,也不好使用。于是我在网上搜索了下发现类似的jquery插件有很多,为了更贴近项目需要我选择了jquery.slimscroll.js. 可是在实际使用的过程中发现该插件不支持滚动的内容翻页,一旦翻页追加新内容,因为内容高度的变化导致存在滚动内容跳跃的情况。

重现问题

看实际效果请猛击这里demo1

从该插件的github上下载源码,并引入到页面中,为了看到效果请打开调试面板,我设置了在内容滚动时输出其scrollTop值,根据输出的结果我们可以很明显的看到在追加新内容后,内容会有跳跃的情况

scrollTop 49
scrollTop 51
scrollTop 105 //内容向上跳跃了
scrollTop 108

打开源码分析原因

源码中的以下这段是在拖动滚动条时要触发的函数

// make it draggable and no longer dependent on the jqueryUI
if (o.railDraggable){ //默认设置为true
bar.bind("mousedown", function(e) {
var $doc = $(document);
isDragg = true;
t = parseFloat(bar.css('top'));
pageY = e.pageY; $doc.bind("mousemove.slimscroll", function(e){
currTop = t + e.pageY - pageY;
bar.css('top', currTop);
scrollContent(0, bar.position().top, false);// scroll content
}); $doc.bind("mouseup.slimscroll", function(e) {
isDragg = false;hideBar();
$doc.unbind('.slimscroll');
});
return false;
}).bind("selectstart.slimscroll", function(e){
e.stopPropagation();
e.preventDefault();
return false;
});
}

翻页追加新内容的时候,我们需要重新初始化该插件,初始化的过程中会重新计算滚动条的top值,下拉翻页时由于鼠标一直是按下的状态,在追加新内容后t值和pageY值记录的一直是按下状态时刻(未追加新内容时刻)的。所以当追加完新内容后,再触发mousemove事件时,currTop又会被计算得到翻页之前的值(滚动条的top值也是之前的值了),而此时的内容高度已经变化了,所以内容会跳跃。(不知道有没有解释清楚啊)

针对问题的解决之道

通过上面的分析我们知道由于在翻页追加新内容后未获取到最新的滚动条的top值和最新的e.pageY值,针对这个问题我在源码中添加了以下一些代码:

// scroll content by the given offset
scrollContent(offset, false, true); // 以下是我添加的内容
//追加新内容后强制解绑之前的鼠标事件,不使用翻页之前记录的值
$(document).unbind('mousemove.slimscroll');
//解绑后为了能继续下拉滚动条,需重新绑定鼠标事件
//记录最新的滚动条的top值和鼠标位置
var pageY, t = parseFloat(bar.css('top'));
$(document).bind("mousemove.slimscroll", function(e) {
//这里判断鼠标状态是为了区分滚动事件和拖动事件
//当鼠标左键是按下状态时,
if (e.buttons == 1) {
pageY = pageY || e.pageY
currTop = t + e.pageY - pageY;
bar.css('top', currTop);
scrollContent(0, currTop, false); // scroll content
}
return;
})

以上代码解决翻页追加新内容后,拖动滚动条存在的跳跃问题

function _onWheel(e) {
//...
var e = e || window.event; // 以下是我添加的内容
//取消拖动
$(document).unbind('mousemove.slimscroll'); //...
}

以上这段代码是为了解决翻页滚动后的点击事件被覆盖问题

这里为什么用e.buttons而不用e.button?

MouseEvent.buttons 可指示任意鼠标事件中鼠标的按键情况

MouseEvent.button 只能够表明在事件中通过按下或者放开一个按键,或者是多个按键同时按下时,哪一个按键被按下。因此,它对判断mouseenter, mouseleave, mouseover, mouseout or mousemove这些事件并不可靠。

修改源码之后的效果请猛击这里demo2

这里修改的代码仅仅是我一人之见,如果您有更好的方法,欢迎在评论中提出

参考文献:

MouseEvent.button

MouseEvent.buttons

针对模拟滚动条插件(jQuery.slimscroll.js)的修改的更多相关文章

  1. jQuery滚动条插件 – jquery.slimscroll.js

    jquery.slimscroll.js插件是一个支持把内容放在一个盒子里面,固定一个高度,超出的则使用滚动.jquery.slimscroll.js不仅可以定义高度.宽度,还可以定义位置.滚动条大小 ...

  2. jquery 滚动条插件 jquery.nanoscroller.js

    $(".listcontent .nano").nanoScroller();   $(".chatcontent .nano").nanoScroller({ ...

  3. 初探jquery.slimscroll.js和iscroll5.js

    网上关于实现各种滚动效果的插件不胜枚举,这里,我简单介绍一下自己用过的两款比较有代表性的插件: 1.jquery.slimscroll.js,需要先引入jquery类库,主要用于模拟传统的浏览器滚动条 ...

  4. jQuery插件 -- 表单验证插件jquery.validate.js, jquery.metadata.js

    原文地址:http://blog.csdn.net/zzq58157383/article/details/7718352   最常使用JavaScript的场合就是表单的验证,而jQuery作为一个 ...

  5. jQuery插件 -- 表单验证插件jquery.validate.js

    最常使用JavaScript的场合就是表单的验证,而jQuery作为一个优秀的JavaScript库,也提供了一个优秀的表单验证插件----Validation.Validation是历史最悠久的jQ ...

  6. 表单验证插件jquery.validate.js

    最常使用JavaScript的场合就是表单的验证,而jQuery作为一个优秀的JavaScript库,也提供了一个优秀的表单验证插件----Validation.Validation是历史最悠久的jQ ...

  7. 动态生成二维码插件 jquery.qrcode.js

    前段时间做项目,需要动态生成一个二维码,于是就在网上找了一下发现一个jquery插件jquery.qrcode.js,所以今天就简单说一下这个插件的使用: jquery.qrcode.js是依赖jqu ...

  8. jquery插件jquery.LightBox.js之点击放大图片并左右点击切换图片(仿相册插件)

    该插件乃本博客作者所写,目的在于提升作者的js能力,也给一些js菜鸟在使用插件时提供一些便利,老鸟就悠然地飞过吧. 此插件旨在实现目前较为流行的点击放大图片并左右点击切换图片的效果,您可以根据自己的实 ...

  9. jQuery响应式幻灯片插件jquery.glide.js(支持触摸&轻量级)

    找到一款好的幻灯片插件不容易,找到一款功能全并且使用很简单的幻灯片更不容易,今天为大家分享一款全能的幻灯片插件glide.js,也是我现在在使用的一款插件. jquery.glide.js是响应和触摸 ...

随机推荐

  1. 使用node.js如何爬取网站数据

    数据库又不会弄,只能扒扒别人的数据了. 搭建环境: (1).创建一个文件夹,进入并初始化一个package.json文件.  npm init -y (2).安装相关依赖:  npm install ...

  2. SeaweedFS上手使用指南

    SeaweedFS是基于go语言开发的高可用文件存储系统,主要特性 1.成存储上亿的文件(最终受制于你的硬盘大小)2.速度快,内存占用小 上手使用比fastDFS要简单很多,自带Rest API. S ...

  3. jenkins 集成钉钉机器人通知

    公司使用钉钉做为公司内部的通讯工具,所以想通过Jenkins发布完成以后通过钉钉来通知大家,研究发现钉钉提供机器人,所以我把机器人集成进来通知相关人员. 1.创建通知人群组,添加机器人(钉钉默认自带了 ...

  4. CentOS安装.NET CORE

    Add the dotnet product feed sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo ...

  5. SQL 必知必会·笔记<14>更新和删除数据

    1. 更新数据 基本的UPDATE语句,由三部分组成: 要更新的表 列名和它们的新值 确定要更新那些行的过滤条件 更新单列示例: UPDATE Customers SET cust_email = ' ...

  6. 转:Bash Shell常用快捷键

    转载:原文出处 移动光标 ctrl+b: 前移一个字符(backward) ctrl+f: 后移一个字符(forward) alt+b: 前移一个单词 alt+f: 后移一个单词 ctrl+a: 移到 ...

  7. SpringMVC redirect中文乱码问题

    在使用"redirect:xxx.do?param=中文"时会出现乱码问题,解决方案如下: 使用model.addAttribute来替代直接拼接参数.如下: @RequestMa ...

  8. 搭建oracle linux虚拟机报错解决

    sysctl -P 报错解决办法问题症状修改 linux 内核文件 #vi /etc/sysctl.conf后执行sysctl  -P 报错error: "net.bridge.bridge ...

  9. JavaWeb学习 (十六)————JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  10. Spark新手入门——3.Spark集群(standalone模式)安装

    主要包括以下三部分,本文为第三部分: 一. Scala环境准备 查看二. Hadoop集群(伪分布模式)安装 查看三. Spark集群(standalone模式)安装 Spark集群(standalo ...