js自定义的简易滚动条

 

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>原生JavaScript--简易滚动条--兼容各浏览器</title>
<style>
* { padding:0; margin:0;}
.cont_Ov { position:relative; top:100px; width:400px; border:2px solid #f00; margin:0 auto;}
.scool { position:absolute; top:0; right:0; z-index:99; width:5px; background-color:#000;}
.scool_An { position:absolute; top:0; right:0; z-index:999; width:5px; height:30px; background:url(un_bg_bar.gif) -33px 0px;}
</style>
</head>

<body>
<div id="cont_Ov" class="cont_Ov">
    <div style=" padding:20px; overflow:hidden;">
    hahawefa1<br />
    hahawefa2<br />
    hahawefa3<br />
    hahawefaae4<br />
    hahawefa5<br />
    hahawefa6<br />
    hahawefa7<br />
    hahawefaf8<br />
    hahawefa9<br />
    hahawefa10fa<br />
    awfawef-11<br />
    hahawefa-12<br />
    hahawefagag-13<br />
    hahawefa-14<br />
    hahawefa-15<br />
    hahawefa-16<br />
    hahawefaaf-17<br />
    hahawefa-18<br />
    hahawefaff-19<br />
    hahawefafffff-20<br />
    hahawefa1-21<br />
    hahawefa2-22<br />
    hahawefa3-23<br />
    hahawefaae-24<br />
    hahawefa-25<br />
    hahawefa-26<br />
    hahawefa-27<br />
    hahawefa-28<br />
    hahawefa-29<br />
    hahawefaf-30<br />
    hahawefa-31<br />
    hahawefafa-32<br />
    awfawef-33<br />
    hahawefa-34<br />
    hahawefagag-35<br />
    hahawefa-36<br />
    hahawefa-37<br />
    hahawefa-38<br />
    hahawefaaf-39<br />
    hahawefa-40<br />
    hahawefaff-41<br />
    hahawefafffff-42<br />
    1212121
    </div>
</div>
<script>
var get = {
    byId : function(id){
        return typeof id === "string" ? document.getElementById(id) : id;},//获取ID的元素?
    sty : function(obj,name){
        return obj.currentStyle ? obj.currentStyle[name] : getComputedStyle(obj, null)[name];},//获取元素样式
    obx_H : function(obj){
        var obj = obj.getBoundingClientRect();//http://www.51res.net/html/2004/0408/10771.html获取元素位置
        return obj.bottom - obj.top;},
    ScoTop : function(){
        return document.documentElement.scrollTop || document.body.scrollTop;}//滚动高度
    };

function enclose(con_Ov, con_Ov_H, con, con_H, scool,scool_H){//鼠标滚动事件绑定自定义方法wheelHandler
    var isFirefox = (navigator.userAgent.indexOf("Gecko") !== -1);
    if(document.onwheel !== undefined){
    con_Ov.onwheel = wheelHandler;
    }else if(document.onmousewheel !== undefined){
        con_Ov.onmousewheel = wheelHandler;
        }else if(isFirefox){
        con_Ov.addEventListener("DOMMouseScroll", wheelHandler, false);
        }
    
    function wheelHandler(e){//滚动方法
        var e = e || window.event,
        deltaY = e.wheelDeltaY || (e.wheelDeltaY===undefined && e.wheelDelta) || e.deltaY*-1 || e.detail*-1 || 0,//鼠标滚动事件判断滚动方向,deltaY =  e.wheelDelta || e.deltaY*-1 || e.detail*-1这样同样效果不知道为什么写那么多呢
        con_Top,// = parseFloat(get.sty(con,"top")),
        con_MaxH = con_H - con_Ov_H, //内容的最大滚动距离
        scool_MaxH =con_Ov_H - scool_H,//左侧最大滚动距离
        gd_Auto,//滚动设置的Interval对象
        star_Time = 0, //滚动开始时间
        now_Time = 0,//滚动结束时间
        step = 10; //每次滚动多少像素
        if(gd_Auto){clearInterval(gd_Auto);}
        star_Time = new Date().getTime();
        if(deltaY < 0){//下滚
            gd_Auto = setInterval(function(){
            con_Top = parseFloat(get.sty(con,"top")),
            now_Time = new Date().getTime();
                
            if(con_Top <= -con_MaxH){//滚到底了
            clearInterval(gd_Auto);
            con.style.top = - con_MaxH + "px";
            scool.style.top = scool_MaxH + "px";
            return;
            }
                
            con.style.top = con_Top - step +"px";//主题内容滚动每次10个像素,鼠标滚轮一次滚动触发好几次滚轮事件
            scool.style.top = Math.round(-(con_Top-step)/con_MaxH*scool_MaxH) + "px";
                
            if(con_Top - step <= -con_MaxH || now_Time - star_Time > 100){//前面是防止滚出最多高度,后面是防止一直滚动导致滚动延迟太大导致不流畅
            clearInterval(gd_Auto);
            con_Top - step <= -con_MaxH && (con.style.top = - con_MaxH + "px",scool.style.top = scool_MaxH + "px");    //当滚动超出后让其回位,程序运行的几毫秒内超出的距离,效果不大
            return;            
            }
        },20)
            
    }else if(deltaY > 0){//上滚
        gd_Auto = setInterval(function(){
        con_Top = parseFloat(get.sty(con,"top")),
        now_Time = new Date().getTime();
        if(con_Top >= 0){
            clearInterval(gd_Auto);
            con.style.top = 0 + "px";
            scool.style.top = 0 + "px";
            return;
            }
                    
        con.style.top = con_Top + step +"px";
        scool.style.top = Math.round(-(con_Top+step)/con_MaxH*scool_MaxH) + "px";
                    
        if(con_Top + step >= 0 || now_Time - star_Time > 200){
        clearInterval(gd_Auto);
        con_Top + step >= 0 && (con.style.top = 0 + "px",scool.style.top = 0 + "px");        
        return;    
        }                    
        },20)
            }else{
            alert("错误!");
            }
        
    if(e.stopPropagation) e.stopPropagation(); //禁止冒泡
            else e.cancelBubble = true;  
        if(e.preventDefault) e.preventDefault();
            else e.returnValue = false;   
    }
}

function drag(con_Ov, con_Ov_H, con, con_H, ele, ele_H, e){//鼠标拉动事件
    var e = e || window.event,
    scroll_T = get.ScoTop(),//当前浏览器滚动高度
    sc_H = con_Ov_H - ele_H,//内容的可视高度减去滚动条按钮的高度(即滚动条的可以滚动的高度)
        startY = e.clientY + scroll_T,//点击的鼠标在网页中的Y轴位置
        origY = ele.offsetTop,//滚动条按钮的TOP
        deltaY = startY - origY;//鼠标点击位置在滚动条按钮的Y轴位置
        
    if(document.addEventListener){
        document.addEventListener("mousemove", moveHandler, true);
        document.addEventListener("mouseup", upHandler, true);
        }else if(document.attachEvent){  // IE Event Model for IE5-8
        ele.setCapture();//鼠标捕获(setCapture)作用是将鼠标事件捕获到当前文档的指定的对象。可以让点击其他地方时这个元素也像被点击一样。这个对象会为当前应用程序或整个系统接收所有鼠标事件。
        ele.attachEvent("onmousemove", moveHandler);
        ele.attachEvent("onmouseup", upHandler);
        ele.attachEvent("onlosecapture", upHandler);//当元素失去鼠标移动所形成的选择焦点时触发的事件 
        }
        
    if(e.stopPropagation) e.stopPropagation(); //禁止冒泡
        else e.cancelBubble = true;
    if(e.preventDefault) e.preventDefault();//阻止默认事件
        else e.returnValue = false;

    function moveHandler(e) {//鼠标拖动滚动条的方法
        var e = e || window.event,
    ele_Top = Math.max(e.clientY + scroll_T - deltaY,0) && Math.min(e.clientY + scroll_T - deltaY,sc_H),//不就是拖动滚动条时,滚动条按钮的TOP和origY算法一样但是要重新获取拖动后的啊
    con_Top = -ele_Top/sc_H*(con_H - con_Ov_H);
    //内容滚动TOP,负负得正哦
        ele.style.top = ele_Top + "px";
    con.style.top = con_Top + "px";
        
        if(e.stopPropagation) e.stopPropagation();
        else e.cancelBubble = true;
    }

    function upHandler(e){//鼠标弹起不拖动时的方法
        var e = e || window.event;
        if(document.removeEventListener){
            document.removeEventListener("mouseup", upHandler, true);
            document.removeEventListener("mousemove", moveHandler, true);
        }else if(document.detachEvent){
            ele.detachEvent("onlosecapture", upHandler);
            ele.detachEvent("onmouseup", upHandler);
            ele.detachEvent("onmousemove", moveHandler);
            ele.releaseCapture();
            }
        if(e.stopPropagation) e.stopPropagation();
            else e.cancelBubble = true;
    }
}

function clickScroll(con,con_H,con_Ov_H,ele,ele_H,scool,e,kk,h){//点击滚动条非滚动按钮方法
    var e = e || window.event,
    scroll_T = get.ScoTop(),//当前浏览器滚动高度
    sc_H = con_Ov_H - ele_H,//内容的可视高度减去滚动条按钮的高度(即滚动条的可以滚动的高度)
        startY = e.clientY + scroll_T,//点击的鼠标在网页中的Y轴位置
        origY = ele.offsetTop,//滚动条按钮的TOP
        sool_T=kk+scroll_T,//滚动条距离页面顶部高度
        //deltaY = startY - origY;//鼠标点击位置在滚动条按钮的Y轴位置
        move_T=startY-sool_T;//鼠标点击在滚动条中的位置
        //alert(h);
        if(move_T>h){move_T=h};
        scool.style.top = move_T + "px";
        con.style.top =  Math.round(-move_T/sc_H*(con_H - con_Ov_H)) + "px";
}//赶着吃饭,下次再完善

function jsScroll(idName,height,clName01,clName02){
    var con_Ov = get.byId(idName),
    con_Ov_Height = parseFloat(get.sty(con_Ov,"height")),
    cont = con_Ov.getElementsByTagName("div")[0],
    cont_H = Math.round(get.obx_H(cont));

    if(!con_Ov_Height || con_Ov_Height == "auto" || con_Ov_Height>=height){//如果样式设置不对给重置
        con_Ov.style.height = height+"px";
        con_Ov.style.overflow = "hidden";
        con_Ov_Height = height;
        }    
    
    if(cont_H<=con_Ov_Height) return;//如果没超出就不加滚动条了//如果没超出就不加滚动条了,如果是隐藏的元素那么cont_H会一直等于0,要在弹窗显示后才触发,要限制第一次点击弹出才添加元素
    cont.style.position = "relative";//设置内容必要CSS样式;
    cont.style.top = "0px";
    cont.style.zIndex = "0";
            
    var scool = document.createElement("div"),scool_An = document.createElement("div");//添加滚动条
    if(clName01){
        scool.className = clName01;
        }else{
            scool.style.cssText = "position:absolute; top:0; right:0; z-index:99; width:10px; background-color:#ccc;";
            }
    scool.style.height = con_Ov_Height + "px";
    con_Ov.appendChild(scool);
    if(clName02){
        scool_An.className = clName02;
        }else{
            scool_An.style.cssText = "position:absolute; top:0; right:0; z-index:999; width:10px; height:30px; background-color:#999;";
            }
    con_Ov.appendChild(scool_An);
    
    var scool_AnH = parseFloat(get.sty(scool_An,"height"));
    scool_An.onmousedown = function(e){
        drag(con_Ov,con_Ov_Height,cont,cont_H,this,scool_AnH,e);//鼠标按下执行
        }
    enclose(con_Ov,con_Ov_Height,cont,cont_H,scool_An,scool_AnH);//鼠标没按下执行
    scool.onclick = function(e){//点击滚动条非滚动按钮执行
        var kk=scool.getBoundingClientRect().top,//滚动条相对页面的TOP
        h=scool.getBoundingClientRect().bottom-scool.getBoundingClientRect().top-scool_An.getBoundingClientRect().bottom+scool_An.getBoundingClientRect().top;//滚动条减去滚动条按钮的高度
        clickScroll(cont,cont_H,con_Ov_Height,this,scool_AnH,scool_An,e,kk,h);
        } 
}
jsScroll("cont_Ov",200,"scool","scool_An"); //如果元素是隐藏的就在元素显示后调用,而且只能调用一次
</script>
</body>
</html>

 

posted @ 2014-09-18 12:12  me春天  阅读(1037)  评论(0编辑  收藏  举报