Маршрутизация событий от одного dom-узла к другому без JQUERY - PullRequest
3 голосов
/ 29 сентября 2011

Мой вопрос полностью похож на: Как передать события javascript от одного элемента к другому? за исключением того факта, что мне нужно сырое решение JS.

У меня есть веб-приложение, чей пользовательский интерфейс имеет многоуровневую структуру элементов, которые прокручиваются вместе со страницей друг друга. По сути, у меня есть то, что составляет iframe (не совсем, но в принципе), и плавающий заголовок, который находится в z-слое над ним. Когда я прокручиваю элементы в iframe, он также перемещает плавающий заголовок вверх.

Однако при перетаскивании заголовка мне также нужно прокрутить базовый документ.

Это интерфейс с сенсорным экраном, поэтому я пробую события onmousemove и ontouchmove.

У меня есть следующий код, но он, похоже, ничего не делает:

setupScrollFromHeader: function setupScrollFromHeader() {
            // webos enyo stuff. Don't worry about it. just know that I get the
            // raw dom elements through the this.$.elem.node syntax
        var body = this.$.body, header = this.$.mailHeaderUnit;
        if (!header.hasNode() && !body.hasNode()) {
            return;
        }
        body = body.node;
            // end enyo specific stuff

        header.node.addEventListener('touchmove', function(event) {
            console.log("### touch move");
            event.preventDefault();
            body.dispatchEvent(event);
            var touch = event.touches[0];
                console.log("Touch x:" + touch.pageX + ", y:" + touch.pageY);
            }, true);
        console.log("### set this stuff up");
    }

Я использую dispatchEvent для пересылки события, согласно: https://developer.mozilla.org/en/DOM/element.dispatchEvent

Я пробовал это с событиями touchmove и mousemove самостоятельно, переключая предотвращение по умолчанию, а также изменяя поведение всплывающих подсказок с флагами true / false.

Во всех случаях я вижу распечатанный журнал, но события никогда не передаются нижележащему элементу. Что я делаю неправильно? Можно ли вообще так проходить события?

1 Ответ

2 голосов
/ 29 сентября 2011

Так что это правильный путь для маршрутизации событий. Похоже, что виджет, с которым я разговариваю, нуждался в событии mousedown перед получением событий touchmove. Для максимальной совместимости я добавил прослушиватели как для мыши, так и для касания, для тестирования в браузере и на устройстве.

Я придумал следующее:

setupScrollFromHeader: function setupScrollFromHeader() {
        if (setupScrollFromHeader.complete) {
            return;
        }
        var body = this.$.body, header = this.$.mailHeaderUnit;
        if (!header.hasNode() && !body.hasNode()) {
            return;
        }

        var header = header.node;
        var forwarder = function forwarder(event) {
                body.$.view.node.dispatchEvent(event);
            };

        ['mousedown', 'mousemove', 'touchstart', 'touchmove', 'touchend'].forEach(function(key) {
            header.addEventListener(key, forwarder, true);          
        });

        setupScrollFromHeader.complete = true;
    },

В общем случае браузера вы можете протестировать такую ​​пересылку с помощью двух кнопок, перенаправляя событие click с одной на другую, как и ожидалось, с помощью dispatchEvent (...).

есть:

var button1 = document.getElementById('button1');
var button2 = document.getElementById('button2');

button1.addEventListener('click', function(event) {
            button2.dispatchEvent(event);
}, true);

button2.addEventListener('click', function(event) {
    alert("Magnets. How do they work?");
}, true);

нажатие кнопки 1 вызовет обработчик кнопки 2.

...