如何防止文本选择阻碍onmousemove事件



我正在实现"调整大小句柄"以更改左导航面板的宽度。这是一个接收onMouseDown()事件的div,计算必要的宽度并将其应用于随后呼叫的onMouseMove()中的正确元素。但是我有一些问题。

1(如果我在那里释放鼠标,则article元素在导航面板和处理的右侧,不会激活onMouseUp()。这是因为onMouseDown()在其他元素中激活吗?

2(如果我将鼠标快速移动到右边,我将无法选择article中的文本,甚至可以调用preventDefault()stopPropagation()等方法。

3(即使article中没有文本,调整大小也仅在我非常慢的鼠标移动时工作。如果鼠标在article元素上快速移动,则调整大小会停止,除非我释放鼠标按钮 - 在这种情况下,调整大小会顺利进行(表明这是文本选择的正在停止调整大小的大小,即使根本没有文本(。但是,如果我释放鼠标按钮,则调整大小应停止(请参阅第1点(。

我已经看到了使用CSS user-select: none的一些解决方案,但这将阻止在article中选择任何文本,这显然是过度的。

那么,当我将鼠标移到文档中的任何元素上时,如何在不选择任何文本的情况下使调整大小进行平滑?(当然,按下右div中的按钮。(

那是我的html:

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>CSS Template</title>
</head>
<body>
<header>Header</header>
<main>
    <nav id='nav'>
        <div class='navcont' onmousemove='handMm(event)' onmouseup='handMu(event)'>
            <p>nav 1</p>
            <p>nav 2</p>
        </div>
        <div class='handle' onmousedown='handMd(event)' onmousemove='handMm(event)' onmouseup='handMu(event)'>
        </div>
    </nav>
    <article id='article' onmousemove='handMm(event)' onmouseup='handMu(event)'>
    </article>
</main>
<footer>Footer</footer>
</body>
</html>

那是我的CSS:

html, body {
    height:100%;
    margin:0;
}
body {
    display:flex;
    flex-direction:column;
}
header {
    text-align:center;
}
main {
    flex:1;
    display:flex;
    min-height:0;
}
article {
    background:#CCC;
    width:auto;
    overflow:auto;
    padding:10px;
    flex-grow:1;
}
nav {
    width:300px;
    height:auto;
    overflow: hidden;
    display:flex;
}
.navcont {
    background:#8C8;
    width:auto;
    flex-grow:1;
}
.handle {
    background:#333;
    right:0px;
    width:30px;
    cursor:col-resize;
}
footer {
    text-align:center;
}

那是我的JavaScript:

var mx,px,moving=false;
function handMd(e) {
    mx = e.pageX;
    px = document.getElementById('nav').clientWidth;
    moving = true;
}
function handMm(e) {
    if (moving) {
        e.preventDefault();
        e.stopPropagation();
        e.cancelBubble = true;
        e.returnValue = false;
        var diff = e.pageX - mx;
        document.getElementById('nav').style.width = (px + diff)+'px';
        document.getElementById('article').style.width = (window.innerWidth-px-diff)+'px';
    }
}
function handMu(e) {
    moving = false;
}

这是一个工作示例:https://jsfiddle.net/45H7VQ7U/

另一个示例,包括瑞安·托伊(Ryan Tsui(的答案:https://jsfiddle.net/v1cmk2f6/1/(文本 - 选择已经消失了,但是DIV仍然不会顺利移动,但只有在速度向右移动时(。

使用您的首选方法(onMouseDownonMouseUp很好(捕获start movingfinish moving的事件。添加CSS类以在操作开始时指定移动状态。动作完成时删除CSS类。

在您的情况下,您可以尝试以下内容:

添加新的CSS类:

.moving {
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
}

扩展您的handMd()handMu()功能:

function handMd(e) {
    mx = e.pageX;
    px = document.getElementById('nav').clientWidth;
    moving = true;
    document.getElementById('article').classList.toggle('moving', true);  // Add this line. 'article' is the id of the element where you don't want the selection to occur.
}
function handMu(e) {
    moving = false;
    document.getElementById('article').classList.toggle('moving', false);  // Add this line. 'article' is the id of the element where you don't want the selection to occur.
}

分析了如何解决其他地方后,我来了以下更改。

html-只需要一个事件处理程序:

...
<main>
    <nav id='nav'>
        <div class='navcont'>
            <p>nav 1</p>
            <p>nav 2</p>
        </div>
        <div class='handle' onmousedown='handMd(event)'>
        </div>
    </nav>
    <article id='article'>
    </article>
</main>
...

JavaScript-附加并分离onMouseMove事件处理程序比每次鼠标移动时都打电话给onmousemove(仅在按下鼠标按钮时测试(。此外,该事件现在已连接到文档,而不是屏幕上的每个div:

var mx,px,minW = 200;
function handMd(e) {
    mx = e.pageX;
    px = document.getElementById('nav').clientWidth;
    document.addEventListener('mousemove',handMm);
    document.addEventListener('mouseup',handMu);
    document.getElementById('article').classList.toggle('moving',true);
    document.getElementById('nav').classList.toggle('moving',true);
}
function handMm(e) {
    var diff = e.pageX - mx;
    if (px+diff >= minW && window.innerWidth-px-diff >= minW) {
        document.getElementById('nav').style.width = (px+diff)+'px';
        document.getElementById('article').style.width = (window.innerWidth-px-diff)+'px';
    }
}
function handMu(e) {
    document.removeEventListener('mousemove',handMm);
    document.removeEventListener('mouseup',handMu);
    document.getElementById('article').classList.toggle('moving',false);
    document.getElementById('nav').classList.toggle('moving',false);
}

CSS-感谢Ryan Tsui的回答,我在调整大小时消除了不需要的文字选择:

.moving {
    user-select:none;
    -moz-user-select:none;
    -webkit-user-select:none;
    -ms-user-select:none;
}

我不知道如何停止选择,但是我可以告诉您一些帮助,当选择某物时触发的事件是onselect

最新更新