JavaScript DOM 鼠标拖拽

更新日期: 2020-04-03阅读: 2.1k标签: 鼠标
前端页面交互中,鼠标拖拽是一个体验良好的功能,实现鼠标拖拽需要了解鼠标行为坐标系和涉及到的许多兼容性写法。本文介绍鼠标位置的获取和、拽功能的实现以及拖拽函数的封装

鼠标行为坐标系

鼠标行为触发事件时,事件对象上会有一些属性提供鼠标的位置信息

属性功能兼容性
clientX/Y鼠标相对可视区域的坐标/
x/y与 clientX/Y 功能相同firefox 低版本不支持
pageX/Y鼠标相对整个文档的坐标兼容 IE9 及以上
layerX/Y与 pageX/Y 功能相同IE10 及以下同 clientX/Y
screenX/Y鼠标位置相对屏幕坐标/
offsetX/Y鼠标位置相对块元素的坐标(包含边框)safari 不包含边框

获取鼠标相对整个文档的坐标:pageX/Y 兼容性差,需要进行封装

鼠标相对整个文档的坐标 = 鼠标相对可视区域的坐标 + 滚动条滚动距离 - 文档偏移

document.documentElement.clientTop 获取文档偏移,在 IE 一些版本中为 undefined

function pagePos(ev) {
    var sTop = getScrollOffset().top,
        sLeft = getScrollOffset().left,
        cTop = document.documentElement.clientTop || 0,
        cLeft = document.documentElement.clientLeft || 0;
    return {
        X: ev.clientX + sLeft - cLeft,
        Y: ev.clientY + sTop - cTop
    }
}
// 封装的函数:获取滚动条滚动距离
function getScrollOffset() {
    if (window.pageXOffset) {
        return {
            top: window.pageYOffset,
            left: window.pageXOffset
        }
    }
    else return {
        top:document.body.scrollTop || document.documentElement.scrollTop,
        left:document.body.scrollLeft || document.documentElement.scrollLeft
    }
}

拖拽函数封装

拖拽效果基于鼠标事件:mousedown、mousemove、mouseup

分别为鼠标按下、鼠标移动、鼠标松开

原理:鼠标按下时,添加鼠标移动、鼠标松开的事件处理函数,鼠标移动时获取鼠标坐标,改变元素样式,鼠标松开时清除鼠标移动和鼠标松开的事件处理函数

<!doctype html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
    <style type="text/css">
        .box {
            position: absolute;
            top: 0;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: red;
        }
    </style>
</head>
<body>
<div class="box"></div>
<script>
    var box = document.getElementsByTagName('div')[0];

    box.onmousedown = function (ev) {
        var ev = ev || window.event,
            x = pagePos(ev).X - parseInt(getStyles(box)['left']),
            y = pagePos(ev).Y - parseInt(getStyles(box)['top']);

        document.onmousemove = function (ev) {
            var ev = ev || window.event,
                mPos = pagePos(ev);
            box.style.left = mPos.X - x + 'px';
            box.style.top = mPos.Y - y + 'px';
        }
        document.onmouseup = function () {
            this.onmousemove = null;
            this.onmouseup = null;
        }
    }

    // 封装的函数:获取鼠标相对整个文档的坐标
    function pagePos(ev) {
        var sTop = getScrollOffset().top,
            sLeft = getScrollOffset().left,
            cTop = document.documentElement.clientTop || 0,
            cLeft = document.documentElement.clientLeft || 0;
        return {
            X: ev.clientX + sLeft - cLeft,
            Y: ev.clientY + sTop - cTop
        }
    }
	// 封装的函数:获取滚动条滚动距离
    function getScrollOffset() {
        if (window.pageXOffset) {
            return {
                top: window.pageYOffset,
                left: window.pageXOffset
            }
        } else return {
            top: document.body.scrollTop || document.documentElement.scrollTop,
            left: document.body.scrollLeft || document.documentElement.scrollLeft
        }
    }

    // 封装的函数:获取元素样式的类数组
    function getStyles(elem) {
        if (window.getComputedStyle) {
            return window.getComputedStyle(elem, null);
        } else return elem.currentStyle;
    }
</script>
</body>
</html>

封装拖拽函数

var box = document.getElementsByTagName('div')[0];
elemDrag(box);

// 封装的拖拽函数
function elemDrag(elem) {
    var x,
        y;
    addEvent(elem, 'mousedown', function (ev) {
        var ev = ev || window.event;
        x = pagePos(ev).X - parseInt(getStyles(elem)['left']);
        y = pagePos(ev).Y - parseInt(getStyles(elem)['top']);
        addEvent(document, 'mousemove', mousemove);
        addEvent(document, 'mouseup', mouseup);
        cancelBubble(ev);
        preventDefaultEvent(ev);
    });

    function mousemove(ev) {
        var ev = ev || window.event;
        elem.style.left = pagePos(ev).X - x + 'px';
        elem.style.top = pagePos(ev).Y - y + 'px';
    }

    function mouseup(ev) {
        var ev = ev || window.event;
        removeEvent(document, 'mousemove', mousemove);
        removeEvent(document, 'mouseup', mouseup);
    }

}
// 绑定事件处理函数
function addEvent(elem, type, fn) {
    if (elem.addEventListener) {
        elem.addEventListener(type, fn);
    } else if (elem.attachEvent) {
        elem.attachEvent('on' + type, function (ev) {
            fn.call(elem, ev); // call 兼容性比 bind 好
        });
    } else {
        elem['on' + type] = fn;
    }
}
// 解绑事件处理函数
function removeEvent(elem, type, fn) {
    if (elem.addEventListener) {
        elem.removeEventListener(type, fn);
    } else if (elem.attachEvent) {
        elem.detachEvent('on' + type, fn);
    } else {
        elem['on' + type] = null;
    }
}
// 获取鼠标在整个文档中的坐标
function pagePos(ev) {
    var sTop = getScrollOffset().top,
        sLeft = getScrollOffset().left,
        cTop = document.documentElement.clientTop || 0,
        cLeft = document.documentElement.clientLeft || 0;
    return {
        X: ev.clientX + sLeft - cLeft,
        Y: ev.clientY + sTop - cTop
    }
}
// 获取滚动条滚动距离
function getScrollOffset() {
    if (window.pageXOffset) {
        return {
            top: window.pageYOffset,
            left: window.pageXOffset
        }
    } else return {
        top: document.body.scrollTop || document.documentElement.scrollTop,
        left: document.body.scrollLeft || document.documentElement.scrollLeft
    }
}
// 获取元素样式的类数组
function getStyles(elem) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(elem, null);
    } else return elem.currentStyle;
}
// 阻止冒泡
function cancelBubble(ev) {
    if (ev.stopPropagation) {
        ev.stopPropagation();
    } else ev.cancelBubble = true; // 兼容 IE8 及以下
}
// 阻止默认事件
function preventDefaultEvent(ev) {
    if (ev.preventDefault) {
        ev.preventDefault();
    } else ev.returnValue = false; // 兼容 IE8 及以下
}   

作者: pgjett
出处: https://pgjett.cnblogs.com

链接: https://www.fly63.com/article/detial/8538

CSS 鼠标样式

设置鼠标指针放在一个元素边界范围内时所用的光标形状,需要对元素的css属性cursor进行设置。cursor属性可能的值:要实现鼠标移上去显示手形、需要在你的提交按钮上增加css cursor属性,并将它的值设置为pointer;

计算鼠标移动的精确速度

要达到无论在什么机器上,算出来的速度是一样的。计算两次mousemove之间的位移和时间,就可以算出精确的速度,不要将onMousemove的调用时间间隔看成是均等的,事实上也不是均等的

JS中鼠标左右键以及中键的事件

有时候需要判断鼠标的事件,除了使用的click事件,只有鼠标左键有效,而右键无效。而对于onmousedown、onmouseup的时候鼠标的事件左键/右键有效。以下总结鼠标三个按键操作:

three.js鼠标控制物体旋转

当我们需要固定场景背景,固定摄像机的时候。移动旋转物体可以使用Three.js提供的OrbitControls.js,也可以手动写控制器。原理:获取鼠标点击的位置与移动的距离,根据移动的距离计算出大概旋转的角度。

获取鼠标位置(区分event对象中的 clientX、offsetX、screenX、pageX )

作用:都是用来获取鼠标的位置;client直译就是客户端,客户端的窗口就是指游览器的显示页面内容的窗口大小(不包含工具栏、导航栏等等)。event.clientX、event.clientY就是用来获取鼠标距游览器显示窗口的长度

javascript如何判断鼠标是否在div区域内?

JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML

javascript如何判断鼠标左键是否被按下?

怎么在javascript中判断鼠标左键是否被按下?下面本篇文章就来给大家介绍一下使用javascript判断鼠标左键是否被按下的方法。在javascript中,可以通过Event 对象的button事件属性来判断鼠标左键是否被按下。

鼠标指针怎么换样式?

我们在DIV CSS布局时候,我们会遇到对对象内鼠标指针光标进行控制,比如鼠标经过指针变为手指形状等样式,接下来我们介绍鼠标指针样式cursor控制。

javascript 鼠标事件总结

mousedown事件与mouseup事件可以说click事件在时间上的细分,顺序是mousedown => mouseup => click。因此一个点击事件,通常会激发几个鼠标事件。

CSS如何改鼠标样式?

在css中,可以通过cursor属性来改鼠标样式。下面本篇文章就来给大家介绍一下cursor属性,希望对大家有所帮助。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!