滚动条美化实践(原⽣js,iscroll,nicescroll)
以前写的废话太多(插件直接引⽤nicescroll,兼容性好,涉及到iframe的情况下稍作修改即可,直接阅读);
近期需要改造项⽬中的滚动条,使原滚动条在三⼤浏览器下表现相同,分享⼀下⾃⼰的改造经历:
项⽬中的滚动条分布在⽹页的各个⼩窗⼝中,使⽤的是-webkit-scrollbar制作,在-webkit内核的浏览器下表现⾮常漂亮,但是在ie和⽕狐下⽆法兼容,还是⾮常丑的默认样式。
原计划使⽤css hack打个补丁美化⼀下,想到ie hack以后变⾊的默认滚动条,觉得浑⾝“蓝瘦⾹菇”。于是决定重写⼀下这个部分,反正以后⽤到的地⽅可以直接拿出来⽤。
第⼀次计划打算⾃⼰⼿写,反正逻辑挺简单的,设定个⽐例拖着⾛呗
简单代码如下:
/
/获取页⾯元素,有⽤的元素包括“视框”,“滚动内容”,“滚动条”,“滚动轨迹”
var box = ElementById("box");
var content = box.children[0];
var scroll = box.children[1];
var bar = scroll.children[0];
//⾸先要根据box和content的⼤⼩⽐例计算出bar的⾼
var bili = box.offsetHeight / content.offsetHeight;
//⽤scroll的⾼乘以⽐例
bar.style.height = scroll.offsetHeight * bili + "px";
//点住滚动条bar,计算⿏标在bar内的位置
var y = e.clientY - bar.offsetTop - box.offsetTop;
//开始拖动
//获取⿏标的新位置
var currentY = e.clientY - y - box.offsetTop;
//需要跟currentY设定上下限
if (currentY < 0) {
currentY = 0;
}
if (currentY > scroll.offsetHeight - bar.offsetHeight) {
currentY = scroll.offsetHeight - bar.offsetHeight;
}
//设置为bar的top值
p = currentY + "px";
//取消滚动时的⽂本选中
//让⽂本移动,⽐例换算。。
p = -currentY / bili + "px";
}
};
}
View Code
这样就完了?呵呵别天真了
滚动条的位置如图,滚动条在menu位置滚动是不受任何影响的,⼀旦移⼊右侧的ifarme嵌⼊的窗⼝就失效了,原因就是上述代码中绑定的document在iframe窗⼝中也存在。
如何解决这个问题,在⽹上了⼤半天没相关结果,结果⼀个qq⼩伙伴给了个⽹站,有了点想法,
主要的⼀点是到这个iframe,再给这
个ifame绑定上事件监听。
关键的⼀点 $("iframe").contents().find("body").mousemove(function(){  someting to do })
同理当⿏标抬起的时候也绑定到这个上⾯。
这⾥注意防⽌⿏标拖动和⿏标抬起的⽬标元素不⼀样导致的bug,要在根document和iframe⾥的document⾥⾯都绑定上事件监听。呵呵...感觉好傻(这⾥的代码已经
如果你只实现⼀个可以在iframe边缘拖动的滚动条现在已经可以了,但是领导说还要实现滚轮在menu列表上滚动,也可以调⽤滚动条,
想想还是⽤个插件,可以实现跟多的功能。
 到的第⼀款插件是 iscroll
 基本的使⽤在github上就可以看到,但是我当时没有发现设置样式(例如,颜⾊、宽⾼的功能)
 于是在源码中做了如下修改
  在1002和1009⾏做了如下修改
  加了⼀个参数  Style
el: createDefaultScrollbar('v', interactive, this.options.scrollbars, Style) //v 代表vertical
el: createDefaultScrollbar('h', interactive, this.options.scrollbars, Style)  //h 代表horizontal
  1662⾏加⼊了⼀个参数myStyle
function createDefaultScrollbar (direction, interactive, type, myStyle)
  1668⾏加⼊了这段代码
//    ⾃定义样式
if(myStyle){ //传⼊的是⼀个对象
var cssString = indicator.style.cssText;
var newCssString = '';
var arr = cssString.split(';');
var obj ={};
for    (var i=0; i<arr.length; i++){        //⽣成默认样式的对象形式
var tempArr = arr[i].split(':');
obj[tempArr[0]]=tempArr[1];
}
/*如果有新的属性替换原有属性,如果没有添加,默认使⽤原来的
* */
for(var k in obj ){
for(var j in myStyle){
if(j==k){
obj[k]=myStyle[j];
}else{
obj[j]=myStyle[j];
}
}
};
for(var k in obj){
newCssString += k + ':' +obj[k] +'\;' ;
}
indicator.style.cssText = newCssString;
}
  然后在公⽤组件的js加⼊如下代码
/*
* 初始化滚动条
* 需要依赖iscroll.js
* @param
* viewbox 滚动的部分外层的窗⼝使⽤querySelector就可以
* fadeScrollbars 是否需要显⽰/隐藏滚动条 true/false
* myStyle  ⽤于⾃定义样式,如果⾃定义了样式会覆盖默认样式,否则使⽤默认样式数据类型对象->{'background-color':'red'}
*
* */
//绘制滚动条
function scrollInit(viewbox,fadeScrollbars,myStyle){js控制滚动条
function loaded (viewbox,fadeScrollbars,myStyle) {
var  myScroll = new IScroll(viewbox, {
scrollbars: true,
mouseWheel: true,
interactiveScrollbars: true,
shrinkScrollbars: 'scale',
fadeScrollbars: fadeScrollbars,  //不激活状态下是否隐藏滚动条
myStyle:myStyle
});
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
loaded(viewbox,fadeScrollbars,myStyle);
}
  然后在列表数据渲染后再调⽤scrollInit⽅法就可以了。
  但是同样到这⾥还是⽆法解决滚动条在iframe边缘的问题,但是这次的表现是在iframe上拖动滚动条可以移动,在menu区域拖动没有办法移动。
  做到这⾥我放弃了这个插件,为什么?因为项⽬要兼容到ie8,⼀不⼩⼼看到了⼀个transfrom translate属性在控制滚动条的位置,呵呵,以后⼀定好先看好兼容性。
  查看css的兼容性最好的⽹站
 第⼆个插件jQuery.nicescroll
  看到这个插件的滚动条的位置使⽤position控制,我就放⼼了
  nicescroll⽀持设置css样式,所以对于我的需求只要满⾜在iframe边缘不存在影响就好了
  于是对源码做出如下改动
  在1760⾏绑定事件的地⽅,加⼊如下代码即可
if(parent.document){
self.bind((cap.hasmousecapture) ? self.win : parent.document, "mouseup", useup);
self.bind(parent.document, "mousemove", usemove);
};
  同时将⼯具库⾥的代码替换成这个
  加⼀个preViewbox的原因是,滚动条部位的数据会随着页⾯操作局部刷新,但是绘制代码要跟随执⾏,防⽌重复绘制,进⾏⼀次判断
  同其他⼯具⼀样,都挂到jQuery上。
//绘制滚动条
var preViewbox = null;
$.scrollInit = function(viewbox,color,hidden){
if(viewbox == preViewbox){
$('div[class^=nicescroll]').remove();    //如果以前绘制过将以前的移除
}
preViewbox = viewbox;
$(viewbox).niceScroll({
cursorcolor: color,//#CC0071 光标颜⾊
cursoropacitymax: 1, //改变不透明度⾮常光标处于活动状态(scrollabar“可见”状态),范围从1到0
touchbehavior: false, //使光标拖动滚动像在台式电脑触摸设备
cursorwidth: "5px", //像素光标的宽度
cursorborder: "0", // 游标边框css定义
cursorborderradius: "5px",//以像素为光标边界半径
autohidemode: hidden //是否隐藏滚动条
});
}
  然后在想绘制滚动条的部位调⽤scrollInit就可以了。
  看似简单的⼀次改动,踩了不少坑,还是⾃⼰对iframe嵌套后与原页⾯的关系没有理清,分享⾃⼰的逗逼经验,希望能帮到需要的⼈。
  菜鸟⽇记,⼤神轻喷....

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。