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