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

时间:2017-06-05 03:49:12

标签: javascript html css preventdefault

我正在实施“调整大小手柄”以更改左侧导航面板的宽度。收到div事件的onMouseDown()onMouseMove(),计算必要的宽度并将其应用于后续article调用中的正确元素。但是我遇到了一些问题。

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

2)如果我将鼠标快速向右移动,我无法阻止preventDefault()中的文字被选中,即使调用stopPropagation()article等方法也是如此。 / p>

3)即使article中没有文字,只有我非常慢地移动鼠标才能调整大小。如果鼠标在user-select: none元素上快速移动,则调整大小停止,除非我释放鼠标按钮 - 在这种情况下调整大小顺利(表明正在停止调整大小的文本选择,即使没有文本在所有)。但是如果我释放鼠标按钮,调整大小应该停止(参见第1点)。

我见过一些使用CSS article的解决方案,但这会阻止在div内选择任何文字,这显然是一种过度杀伤。

那么,当我将鼠标移动到文档中的任何元素上时,如何在不选择任何文本的情况下平滑调整大小? (当然,按下右侧<!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> 按钮后。)

这是我的HTML:

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;
}

那是我的CSS:

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;
}

这是我的Javascript:

test = [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5] ;
test_unique = unique(test) ;
A = zeros(5,3) ;
for i = 1:size(A,1)
    A(i,:) = randsample(test_unique,3) ;
end

这是一个有效的例子:https://jsfiddle.net/45h7vq7u/

另一个例子,包括Ryan Tsui的回答:https://jsfiddle.net/v1cmk2f6/1/(文本选择已经消失,但div仍然不会顺利移动,但只有当快速移动到右边时)。

3 个答案:

答案 0 :(得分:1)

使用您首选的方法(start movingfinish moving抓住onMouseDownonMouseUp的事件。添加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.
}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

在分析了解决方法somewhere else之后,我做了以下更改。

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;
}