Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 31.12.2017, 03:00
Аспирант
Отправить личное сообщение для eugenk Посмотреть профиль Найти все сообщения от eugenk
 
Регистрация: 14.05.2013
Сообщений: 47

Чудеса с 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. Понятно что глюк броузера. Но я был бы очень благодарен, если бы добрые люди подсказали мне, как с этой напастью бороться. Я сам что-то совсем уже иссяк.

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

Последний раз редактировалось eugenk, 31.12.2017 в 03:03.
Ответить с цитированием
  #2 (permalink)  
Старый 31.12.2017, 09:09
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

eugenk,
фото до и после, полноэкраннная версия
Ответить с цитированием
  #3 (permalink)  
Старый 31.12.2017, 09:33
Аспирант
Отправить личное сообщение для eugenk Посмотреть профиль Найти все сообщения от eugenk
 
Регистрация: 14.05.2013
Сообщений: 47

Спасибо ! Вроде бы это работает без глюков. Буду разбираться. Удачи и отличного настроения в новом году !
Ответить с цитированием
  #4 (permalink)  
Старый 31.12.2017, 10:19
Аспирант
Отправить личное сообщение для eugenk Посмотреть профиль Найти все сообщения от eugenk
 
Регистрация: 14.05.2013
Сообщений: 47

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

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

Последний раз редактировалось eugenk, 31.12.2017 в 10:23.
Ответить с цитированием
  #5 (permalink)  
Старый 31.12.2017, 10:24
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

eugenk,
Ответить с цитированием
  #6 (permalink)  
Старый 31.12.2017, 12:42
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,491

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



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Публикация в Chrome Web Store zbara Общие вопросы Javascript 2 02.03.2017 22:13
Подключение своих js скриптов в Chrome на любых сайтах avramch Opera, Safari и др. 5 28.07.2016 16:11
Проблема с onended для chrome С.Тарасов Events/DOM/Window 14 21.05.2012 18:55
Получить размеры рабочей области окна в Chrome unclechu Events/DOM/Window 1 13.09.2011 02:37
тег <audio> в Opera, Chrome, Firefox Magneto Javascript под браузер 12 25.11.2010 15:12