Javascript-форум (https://javascript.ru/forum/)
-   Javascript под браузер (https://javascript.ru/forum/css-html/)
-   -   Чудеса с mousemove в chrome (https://javascript.ru/forum/css-html/72022-chudesa-s-mousemove-v-chrome.html)

eugenk 31.12.2017 03:00

Чудеса с mousemove в chrome
 
Приветствую многоуважаемый All, с наступающим !
Дело такое. Захотел я сделать раздвижные окна, разделяемые сплитером. Всё стандартно. Наводим мышку на сплитер, жмём левую кнопку, перетаскиваем и отпускаем. Окна перестраиваются. Работает это так. Окна и сплитер это div-ы. На сплитер вешаем событие mousedown, устанавливающую в true переменную, обозначающую что сплитер захвачен. На подложку всего этого безобразия - события mousemove, по которому передвигается сплитер и mouseup, по которому сплитер отпускается и окна перестраиваются. Всё просто. Однако я наткнулся на следующее чудо. Иногда захваченный сплитер перестаёт двигаться. И начинает двигаться при отпускании кнопки мыши ! Вообще-то проект у меня на dart. Но я минимизировал эффект до 40 с небольшим строк на чистом javascript. Вот код:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Slider</title>
</head>
<body>
<div id="root" style="position: absolute; background: #ffffff">
<!-- Тут можно закомментировать left и right -->
    <div id="left" style="position: absolute; background: #ff0000"></div>
    <div id="right" style="position: absolute; background: #0000ff"></div>
<!---->
    <div id="split" style="position: absolute; background: #000000; cursor: ew-resize"></div>
</div>
<script type="text/javascript">
    var rat=0.5;
    var gap=7;
    var drag=false;
    var W=window.innerWidth, H=window.innerHeight;
    var root=document.getElementById("root");
    var left=document.getElementById("left");
    var right=document.getElementById("right");
    var split=document.getElementById("split");
    window.onresize=resize;
    split.onmousedown=function(ev) {drag=true;}
    root.onmousemove=function (ev) {if(drag) split.style.left=px(ev.clientX);}
    root.onmouseup=function (ev) {drag=false; rat=split.offsetLeft/W; resize();}
    resize();
    function px(n){return ""+n+"px"}
    function resize() {
        W=window.innerWidth; H=window.innerHeight;
        root.style.left=px(0); root.style.top=px(0);
        root.style.width=px(W); root.style.height=px(H);
        split.style.left=px(W*rat); split.style.top=px(0);
        split.style.width=px(gap); split.style.height=px(H);
        if(left) {
            left.style.left=px(0); left.style.top=px(0);
            left.style.width=px(W*rat); left.style.height=px(H);}
        if(right) {
            right.style.left=px(W*rat+gap);right.style.top=px(0);
            right.style.width=px(W-W*rat-gap);right.style.height=px(H);}
    }
</script>
</body>
</html>


Испытывал я его в chrome и firefox. "Чудеса" происходят только в chrome. Далеко не всегда, где-то одна попытка из пяти. В firefox всё работает нормально. Если Вы закомментируете div-ы left и right, сплитер будет двигаться нормально и в chrome. Я довольно плотно поигрался с этим кодом, вставляя отладочную печать, и пришел к выводу, что в chrome события mousemove иногда почему-то "перестают проходить" через лежащие сверху элементы. Впервые обнаружил я это в dartium (50.0.2661.108 (64-bit) linux). Но этим же страдает и chrome 60.0.3112.113 (Официальная сборка), (64 бит) linux. Понятно что глюк броузера. Но я был бы очень благодарен, если бы добрые люди подсказали мне, как с этой напастью бороться. Я сам что-то совсем уже иссяк.

Хорошего всем праздника и удачи в будущем году !

рони 31.12.2017 09:09

eugenk,
фото до и после, полноэкраннная версия

eugenk 31.12.2017 09:33

Спасибо ! Вроде бы это работает без глюков. Буду разбираться. Удачи и отличного настроения в новом году !

eugenk 31.12.2017 10:19

Еще раз спасибо тебе, добрый хороший человек ! Разобрался. Дело оказалось в вызове preventDefault(). Сделал событие mousemove вот так:
root.onmousemove=function (ev) 
{
      ev.preventDefault(); 
      if(drag) split.style.left=px(ev.clientX);
}

и чудеса прекратились. По крайней мере мотал сплитер по окну в chrome пока не надоело, и добиться чуда так и не удалось. Вот же блин, век живи, век учись ! :lol:

рони 31.12.2017 10:24

eugenk,
:dance:

Aetae 31.12.2017 12:42

Это всё из-за нативного drag, вестимо. Мертворожденный стандарт, который вместо того чтобы решить проблему с перетягивание только добавил головной боли...


Часовой пояс GMT +3, время: 23:41.