音量控制条demo,拖拽定位,点击定位

整体效果,可以输出音量大小的开关

三个事件,一个拖动周期

1.鼠标按下(mousedown,touchstart),标记开始,然后记录起始位置xy
2.鼠标移动(mousemove,touchmove),如果标记是开始状态,则根据移动状态位置,更新按钮新的定位
3.松开鼠标(mouseup,touchend),标记结束。

注意点:

is_mousedown = 0; 变量开关

1.标记开始与结束作态就像是做了一个开关,打开的时候,此时的移动才是有效数据,开关关闭此时的移动是无效的,这样就不会看到鼠标松开后按钮还会跟着鼠标移动的情况
2.关于事件绑定,鼠标按下是委托到按钮上面,剩余两个则是委托到document上面,这样,当鼠标移动的时候,不在按钮父元素上面的时候,按钮依然可以左右随着鼠标移动。
如下图所示:

更好的处理方式

html布局
<div class="bar" id="bar">
    <span class="btn" id="btn"></span>
</div>

可以避免事件重复被绑定

1. 鼠标按下的时候:委托鼠标移动和松开事件到document上面
//按下事件的回调
function down(e) {
    start_x = e.clientX;
    btn_start_left = btn.offsetLeft;
    /*按下时候委托,move 和 up 为各自的回调方法*/
    addListener(document,'mousemove',move); //注意是委托到document上面
    addListener(document,'mouseup',up);
}
addListener(btn,'mousedown',down);//按下事件绑定到btn上面
2. 鼠标松开的时候:将委托到document上的两个事件进行移除
function up(e) {
    /*松开解绑,move 和 up 事件*/
    removeListener(document,'mousemove',move);//解除document上面的委托
    removeListener(document,'mouseup',up); 
}

附加效果,优化

增加点击效果,绑定到bar上面
function click_move(e) {
    var target = e.target || e.srcElement.target,
        layer_x = e.layerX || e.offsetX ;
    if(target === bar){/*排除掉点击了btn的情况,只在点击了bar的情况下有效*/
        layer_x = e.layerX;
        btn.style.left = (layer_x - btn_w/2) +'px';
    }
}

如下图:

附加的添加事件方法,解绑相反
function addListener(btn,event,handler){
    if (btn.addEventListener){//DOM 2  三个参数,分别为:"事件名称", "事件回调", "捕获/冒泡"。true代表捕获事件,false代表冒泡事件
        btn.addEventListener(event, handler,false);
    }else if(btn.attachEvent){//DOM 2  IE8及其以下版本浏览器
        btn.attachEvent(event, handler);
    }else{//DOM 0
        btn['on'+event] = handler;
    }
}

猜你喜欢

转载自www.cnblogs.com/flora-dn/p/9104840.html