Windless
订阅/Feed
稗田千秋(i@wind.moe)

原生JS拖拽实现

稗田千秋
Feb.10 2016 code

这两天更新了音乐面板,懒得使用@media查询来适配分辨率,于是便想起了拖拽这个方法,鉴于以前实现过,便记下来水一篇(×,记得点击右上的音乐按钮然后随意玩耍哦~(雾

Update 2017-04-05 音乐面板已移动至右下角的菜单按钮中。

基本逻辑

function drag(obj){
    //鼠标按下 开始计算相对位置
    document.onmousedown = function(e){
        var oEvent = e,
        disX = oEvent.clientY - obj.offsetLeft;
        disY = oEvent.clientY - obj.offsetTop;
        //鼠标拖动 计算拖动距离并进行拖拽
        document.onmousemove = function(e) {
            var oEvent = e;
            left = oEvent.clientX - disX,
            top = oEvent.clientY - disY;
            obj.style.left = left + 'px';
            obj.style.top = top + 'px';
        },
        //鼠标松开 结束拖放
        document.onmouseup = function(e) {
            document.onmousemove = null;
            document.onmouseup = null;
        }
    }
}

鼠标位置

鼠标位置是由MouseEvent事件取得的,查阅文档发现Client兼容性较好,此外如果移动的元素的属性position不是absolute/relative的话,可能在长页面需要加上 scrollTop 等相关属性来计算偏移。

document.onmousedown = function(e){
    ...
    disX = document.documentElement.scrollLeft + oEvent.clientY - obj.offsetLeft;
    disY = document.documentElement.scrollTop + oEvent.clientY - obj.offsetTop;
}

边界条件

有些情况下,比如图片裁剪,裁剪的范围是不能超出图片本身范围的,因此我们需要增加一个边界条件来限定拖动的范围

也就是先获得四个边界的实际距离,Top和Left直接取0,然后Buttom和Right则使用文档长度减去对象本身的长度

document.onmousemove = function(e) {
    ...
    //边界判定
    left < 0 ? left = 0 : left > document.documentElement.clientWidth - obj.offsetWidth && left = document.documentElement.clientWidth - obj.offsetWidth;
    top < 0 ? top = 0 : top > document.documentElement.clientHeight - obj.offsetHeight && (top = document.documentElement.clientHeight - obj.offsetHeight);
    ...
}
引用

--END--
文章创建于 2016-02-10 22:40:08,最后更新 2016-02-10 22:40:08
Comment
尝试加载Disqus评论, 失败则会使用基础模式.
    • play_arrow

    About this site

    version:1.02 Alpha
    博客主题: Lime
    联系方式: i@wind.moe
    写作语言: zh_CN & en_US
    博客遵循 CC BY-NC-SA 4.0许可进行创作

    此外,本博客会基于访客的Request Headers记录部分匿名数据用于统计(Logger的源码见Github),包含Referer, User-Agent & IP Address.个人绝不会主动将数据泄露给第三方