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

    测试策略 描述测试工程的总体方法和目标:根据测试需求,描述在什么测试阶,依据什么测试要素和目标,进行什么种类的测试,使用什么样的测试方法和工具. 测试策略的制定主要包含如下内容: 确定测试过程要使用的 ...

  2. 关于@font-face的使用

    以前在写网页的时候,总是使用浏览器默认的字体,因此从未使用过@font-face,然而,最近在做官网的时候,UI规定了字体,要在所有浏览器下都展现同一效果.多番查询下,发现@font-face用起来是 ...

  3. C# DataGridView 在最左侧显示行号方法

    代码: private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) { Da ...

  4. Redis主从同步原理-SYNC【转】

    和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,下图为级 ...

  5. Windows系统环境下创建mysql主从数据库方法(双向主从复制)

    创建mysql主从数据库方法(双向主从复制) (一)Windows系统下的MySQL主从复制(单向复制) (1)环境说明: 1,Mysql版本:mysql5.7.20(主从机mysql版本必须一致) ...

  6. idea 中解决maven 包冲突的问题(maven helper)

    转:链接 一.冲突问题 比如项目中引用了两个 fastjson.jar的版本,分别为 fastjson:1.2.28fastjson:1.2.3 我们用到了1.2.28中的某个类, 比如 A类,在版本 ...

  7. JavaWeb学习(三十)———— 数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  8. [JZOJ5837] Omeed

    Description Solution 有两种做法 一种是线段树维护一次方程系数,一种是线段树维护矩阵 准备都写一写 维护系数 首先把式子推出来 \[CS=B\times \sum\limits_{ ...

  9. NABCD校园生活

    N(Need,需求) 在校师生得到的信息分散,极大的影响了师生的学习效率,所以就会有快速得到全面信息的需求,而我们的APP正是在解决这个问题. A(Approach,做法) 我们会在主页进行信息分类, ...

  10. mysql实践总结

    首先介绍mysql的安装和基本使用.进阶操作.讲解mysql的导入导出和自动备份,然后介绍安全模式修改密码和mysql的全文本搜索功能,最后记录了个人使用mysql中遇到的问题集,闲暇时我也会多看几次 ...