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

    git使用过程中,经常遇到这样的问题,已经git push 了,但是,由于冲突或者push的分支不对,导致远程的和本地的不一致. 这就需要提交后查看一下远程的是否ok. 查了一下资料,找到了一些方法, ...

  2. OC学习1——基本数据类型

    1.OC是在C语言的基础上进行扩展的一种面向对象的编程语言.很多基础知识都和C语言中的非常类似.首先介绍一下OC中的基本数据类型,整体框架如下图: 2.自动数据类型转换顺序:short --> ...

  3. django-pure-pagination实现分页

    django-pure-paginations是一个第三方的分页插件 安装 django-pure-pagination pip install django-pure-pagination 在set ...

  4. 从零开始学 Spring Boot

    1.下载 spring-tool-suite https://spring.io/tools3/sts/legacy 2.解压运行 sts-bundle\sts-3.9.7.RELEASE\STS.e ...

  5. 安装CDH5 hadoop2.3.0 NodeManager 没有启动

    今天在安装hadoop后,启动start-yarn.sh后,nodemanager起不起来,后来查看DN节点的日志,报了以下一个错误: FATAL org.apache.hadoop.yarn.ser ...

  6. OkHttp3 任务队列

    OkHttp3 有两种运行方式: 1.同步阻塞调用并且直接返回: 2.通过内部线程池分发调度实现非阻塞的异步回调; 下面讲的是非阻塞异步回调,OkHttp在多并发网络下的分发调度过程,主要是Dispa ...

  7. 从架构演进的角度聊聊Spring Cloud都做了些什么

    1.从架构演进的角度聊聊Spring Cloud都做了些什么?2.中小型互联网公司微服务实践-经验和教训3.Spring Cloud在国内中小型公司能用起来吗?

  8. static和fianl修饰变量的区别

    参考:http://hllvm.group.iteye.com/group/topic/37682 http://blog.csdn.net/javakuroro/article/details/68 ...

  9. Django 学习笔记(五) --- Ajax 传输数据

    人生苦短 ~ Tips:仅适用于 Python 3+(反正差别不大,py2 改改也能用).因为据 Python 之父 Guido van Rossum 说会在 2020 年停止对 Python 2 的 ...

  10. [转]在Node.js中使用RabbitMQ系列一 Hello world

    本文转自:https://www.cnblogs.com/cpselvis/p/6288330.html 在前一篇文章中可伸缩架构简短系列中提到过关于异步的问题.当时推荐使用RabbitMQ来做任务队 ...