marko-js-archive / marko-widgets

[LEGACY] Module to support binding of behavior to rendered UI components rendered on the server or client
http://v3.markojs.com/docs/marko-widgets/
MIT License
141 stars 40 forks source link

Add support for attaching DOM event listeners declaratively in the template #11

Closed patrick-steele-idem closed 9 years ago

patrick-steele-idem commented 9 years ago

Allow DOM events to be mapped to widget methods using a custom w-on*="<target_method>" attribute (e.g., w-onclick="handleClick"). When the DOM event is triggered in the DOM then the specified widget method will be invoked (with this being the widget instance) and two arguments will be provided to the widget method when invoked:

  1. event - The raw DOM event object
  2. el - The raw DOM element that the event listener was attached to (NOTE: This is not necessarily the same as event.target if the event bubbled up)

    Example Usage

template.marko:

<div w-bind="./widget"
    w-onclick="handleRootClick">

    <input type="text"
        w-onchange="handleInputChange"
        value="Hello world">
</div>

widget.js

function Widget() {

}

Widget.prototype = {
    handleRootClick: function(event, el) {
        // "this" will be the widget instance!
        this.setColor('red');
    },

    handleInputChange: function(event, el) {
        var value = el.value;
        // Do something with the element
    },

    setColor: function(color) {
        this.el.color = color;
    }
};

module.exports = Widget;

Event Delegation

For performance reasons, whitelisted events that bubble will be handled differently from events that do not bubble. For whitelisted events that bubble, a single DOM listener will be attached to the document.body for each event type. For events that are not whitelisted or do not bubble, a DOM event listener will automatically be attached directly to the DOM element when needed.

When a whitelisted event that bubbles makes it to document.body, Marko Widgets will walk up the DOM starting at event.target to determine if the DOM event is mapped to any widget methods. The walk up will stop once the containing widget is reached (or the root of the DOM is reached). Special data-w-on* attributes (e.g., data-w-onclick="handleClick" will be added to the DOM to record the mapping of DOM events to widget methods.

philidem commented 9 years ago

Very cool. Nice job! Going to start using this right away.

patrick-steele-idem commented 9 years ago

Coding is done, but adding tests. Be patient :)

patrick-steele-idem commented 9 years ago

Work completed. New version of marko-widgets published: marko-widgets@1.5.0