webkit支持对页面滑轮和滑道的自定义,但是那种自定义是有限的。比如:如果你想让滚轮滑道与页面的背景图片融合是不可能的,也不能让滑块有自行义的形状。
所以咱前一阵子强迫症爆发,在自己的应用中重新写了个滑道,案例的话请参考:https://github.com/DFLS/DAdolfans
自备less编译器,源码里的less浏览器nw是读不了的。
鼠标滑到页面右边缘的时候会出现滑块,拖动滑块页面就会滚。
注:再次强调此方法仅在webkit内核浏览器下生效,拿来实现个node-webkit的应用是可行的,不过别想着在页面里做……FF用户和IE用户会疯掉。
注2:本页面只讲纵向滚轮实现,一般页面也不会有奇葩的横向滚动需求,真有这方面需求自己看着代码改就行了。
在开始写自定义形状的滚轮前咱要提醒乃个事情,node-webkit的window API和所有window有关的DOM API执行都卡的一笔,想去实现个动画只有卡到不行一条路,所以我们在这里选择给页面做个warp,height和width都是100%,overflow设置成scroll-y:
overflow-y: scroll;
之后把这个warp的原生滚动条K掉:
#balabalabala::-webkit-scrollbar {
width: 0px;
}
ヾ(:3ノシヾ)ノシ 我是好好起名字会死星人。
接下来让我们做个热区,当鼠标滑动到热区内的时候显示滑块。按照我之前提的需求构建下滑块的HTML代码:
<div id="navigator_hotarea">
<div id="navigator_arror"></div>
</div>
其中#navigator_hotarea是热区的名字,鼠标滑到热区上的时候就会显示指针,#navigator_arror就是那个指针。 看下CSS代码:
#navigator_hotarea{
top:50px;
right:0;
width:34px;
height:-webkit-calc(100% - 50px);
position:fixed;
z-index:7;
#navigator_arror{
top:50px;
right:0;
width:34px;
height:28px;
margin-top:-14px;
background:url(../image/arrow.png);
position:fixed;
opacity: 0;
transition-property:opacity,right;
transition-duration:0.2s;
transition-timing-function:ease-in-out;
}
}
指针的图参见附件。
解释下这里面的margin-top:-14px是干啥,老思路,让y方向的容器原点变成指针的中心,省得一会做js的时候再算了。
别的都没啥难的,看看就好。
下一步开始写jS,先讲思路:
当鼠标滑入热区的时候要显示指针,同时指针要准确的指出页面的位置,滑道的高度是一定的,页面的高度是会变的。所以我们需要计算出来一个百分比,算出页面滚动了百分之多少。
算法如下:
$("#main_area").scrollTop() / ($("#main_area")[0].scrollHeight - $("#main_area").height())
这里是一道数学题,咱高考数学92,擦边过,所以……恩……,数学计算部分就不讲了……
这里用到了一个比较神棍的东西:JS和JQ的混用:
scrollHeight是JS的方法,直接在jQ选择器上用会报错的,所以要JS和JQ混用要在JQ的选择器后面加个[0]。
页面滚动百分比拿到之后去算指针的位置:
(($("#navigator_hotarea").height() - 50) * mainAreaScrollPositionPercent) + 50;
第一个减50像素是我想让滑轮距离页面底部有50px的位置,第二个50滑道距离页面顶部有50px的距离。
然后这部分的完整代码就出来了,是这样的:
$("#navigator_hotarea").on("mouseover", function() {
var mainAreaScrollPositionPercent = $("#main_area").scrollTop() / ($("#main_area")[0].scrollHeight - $(document).height());
var arrorPosition = (($("#navigator_hotarea").height() - 50) * mainAreaScrollPositionPercent) + 50;
$("#navigator_arror").css({"top": arrorPosition + "px", "opacity": "1", "right": "5px"});
//(σ′▽‵)′▽‵)σ我是长变量名星人
});
回调函数里最后一行是控制位置,顺便显示个动画,聪明的你一定看得懂ヽ(✿゚▽゚)ノ。
然后当鼠标从热区离开的时候我们的指针需要消失,没啥技术含量,上代码:
$("#navigator_hotarea").on("mouseleave", function() {
$("#navigator_arror").css({"opacity": "0", "right": "0px"});
});
接下来是第二部分:拖拽滚轮的时候页面滚动:
先来做一个能拖动的指针:
$("#navigator_arror").on("mousedown", function() {
$(document).on("mousemove", function(evt) {
screenPosition.y = evt.pageY;
if (screenPosition.y < 50)
arrowY = 50;
else if (screenPosition.y > $("#navigator_hotarea").height())
arrorY = $("#navigator_hotarea").height();
else
arrowY = screenPosition.y;
$("#navigator_arror").css("top", arrowY + "px");
// FLAG
});
});
也没啥解释的,当按下指针的时候监听鼠标移动的事件。
鼠标移动的事件里有个回调,pageY,就是你的鼠标相对页面左上角的坐标,为了不让你的指针跑出滑道用了两个if进行判断。当Y小于50的时候把指针限制在50,大于滑道宽的时候指针会被限制在滑道底部。
接下来计算你的指针位置,之后让页面也跟着跑。
FLAG位置插入下面的代码:
var arrorPositionPercent = ($("#navigator_arror").position().top - 50) / ($("#navigator_hotarea").height() - 50);
var arrorScrollPosition = ($("#main_area")[0].scrollHeight - $(document).height()) * arrorPositionPercent;
$("#main_area").scrollTop(arrorScrollPosition);
这样页面就会跟着滚了。
然后当鼠标松开的时候我们不能再让指针跟着我们跑了对吧,用这个:
$(document).on("mouseup", function() {
$(document).off("mousemove");
$("#navigator_arror").css({"opacity": "0", "right": "0"});
});
写到这里你会发现个问题,当你拖动滑块的时候鼠标移出了热区小箭头就会消失,这是个bug,怎么解决呢?
增加一个arrorDraging的变量就好了,用于判断我是不是在拖动这个指针是否在拖动,如果是拖动的,鼠标移出热区就不隐藏这个指针。
完整代码是这样的:
//绑定滑入热区事件
$("#navigator_hotarea").on("mouseover", function() {
var mainAreaScrollPositionPercent = $("#main_area").scrollTop() / ($("#main_area")[0].scrollHeight - $(document).height());
var arrorPosition = (($("#navigator_hotarea").height() - 50) * mainAreaScrollPositionPercent) + 50;
$("#navigator_arror").css({"top": arrorPosition + "px", "opacity": "1", "right": "5px"});
});
$("#navigator_hotarea").on("mouseleave", function() {
if (!arrorDraging)
$("#navigator_arror").css({"opacity": "0", "right": "0px"});
});
//这俩是滚针事件
$("#navigator_arror").on("mousedown", function() {
arrorDraging = true;
$(document).on("mousemove", function(evt) {
screenPosition.y = evt.pageY;
if (screenPosition.y < 50)
arrowY = 50;
else if (screenPosition.y > $("#navigator_hotarea").height())
arrorY = $("#navigator_hotarea").height();
else
arrowY = screenPosition.y;
var arrorPositionPercent = ($("#navigator_arror").position().top - 50) / ($("#navigator_hotarea").height() - 50);
var arrorScrollPosition = ($("#main_area")[0].scrollHeight - $(document).height()) * arrorPositionPercent;
$("#navigator_arror").css("top", arrowY + "px");
$("#main_area").scrollTop(arrorScrollPosition);
});
});
$(document).on("mouseup", function() {
arrorDraging = false;
$(document).off("mousemove");
$("#navigator_arror").css({"opacity": "0", "right": "0"});
});
怎么样,很简单吧(∫・ω・)∫
Comments
No comments here,
Why not write something?