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.
精彩评论