Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   settimeout pause/resume и mouseenter/mouseleave (https://javascript.ru/forum/events/46357-settimeout-pause-resume-i-mouseenter-mouseleave.html)

rtfl 07.04.2014 10:14

settimeout pause/resume и mouseenter/mouseleave
 
Задача: есть карта с маркерами (leaflet), необходимо что бы при наведении мыши на маркер появлялся попап, а так же при перемещении мыши внутрь попапа он оставался открытым.
Концепция: при mouseleave с маркера или попапа вызывается функция закрытия попапа по таймауту. При mouseenter на маркер или попап ставится пауза таймера.
Реализация: Переопределил функцию закрытия попапа следующим образом:
closePopup: function (t) {
        t = t || 300;
        if (this._popup) {
            var ths = this;
           ths._timer = new Timer(function () {
                    ths._popup._close();
            }, t);
        }
        return this;
    },

где Timer:
function Timer(fn, countdown) {
    var ident, complete = false;

    function _time_diff(date1, date2) {
        return date2 ? date2 - date1 : new Date().getTime() - date1;
    }

    function pause() {
        clearTimeout(ident);
        total_time_run = _time_diff(start_time);
        complete = total_time_run >= countdown;
    }

    function resume() {
        ident = complete ? -1 : setTimeout(fn, countdown);
    }

    var start_time = new Date().getTime();
    ident = setTimeout(fn, countdown);

    return { pause: pause, resume: resume };
}

Проблема: 1. При быстром премещении мыши на маркерах может возникнуть ситуация, когда курсор установлен на маркере, но попап закрывается, хотя должен открыться. 2. Если открыть попап, а затем попробовать быстро переместить курсор вовне и обратно на попап, а затем опять вовне, то попап не закроется.

Код целиком: http://jsfiddle.net/xwreT/

jsnb 07.04.2014 18:04

Так я не понял, ваш _timer навешивается только при закрытии попапа? Так получается что при заходе на метку он будет неопределен.

UPDATE:
При быстром движении мышью с попапа и назад в _removePopups не срабатывает closePopup, следовательно таймер не обнуляется и при втором resume таймер на закрытие не запустится.


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