开发者

Route events from one dom node to another WITHOUT JQUERY

My question is totally like: How do I pass javascript events from one element to another? except for the fact that I need a raw JS solution.

I've got a webos app whose UI features a layering of elements that scroll in conjunction with eachother on a page. Basically I have what amounts to an iframe (not quite, but in principle), and a floating header that lives in a z-layer above it. When I scroll the elements in the iframe, it also moves the floating header up.

However, I also need to scroll the underlying doc when the header is dragged.

This is a touchscreen interface, so I'm trying on开发者_如何学JAVAmousemove and ontouchmove events.

I've got the following code, but it doesn't seem to do anything:

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");
    }

I'm using dispatchEvent to forward the event, per: https://developer.mozilla.org/en/DOM/element.dispatchEvent

I've tried this with either touchmove and mousemove events by themselves, toggling prevent default, and also changing the bubbling behavior with the true/false flags.

In all cases I see the log print out, but the events are never passed to the underlying element. What am I doing wrong? Is it even possible to pass the events around this way?


So this is the right way to route events. Looks like the widget I'm talking to needed a mousedown event before receiving the touchmove events. For maximum compatibility, I added listeners for both mouse and touch, for testing in browser and on device.

I came up with the following:

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;
    },

In the general browser case, you can test such forwarding with with two buttons, routing the click event from one to the other works as expected through dispatchEvent(...).

ie:

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);

clicking button1 will fire the handler of button2.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜