Using DOM Element Events in UWA

Assining an event to a DOM Element

Let's say that you would like to execute "pieceOfCode" function on an element when the user clicks on it.

The JavaScript/DOM way to describe that is: you would like to add "pieceOfCode" as a listener of the event "click" on a DOM node.

Definitely avoid the "old" way:

Create an anchor element with a "click" attribute

<a onclick="pieceOfCode(this);">My link</a>

It is no longer possible to do so in the UWA environment because the "pieceOfCode" function above would be require to set globally, like document.pieceOfCode(), which is not allowed in UWA (the document and window objects are not recommended for portability reasons).

Using UWA JS Runtime:

There are two ways to achieve this.

  1. Create the element with the event and inject it into the widget body
widget.createElement('a', {
    text: 'My link',
    events: {
        click: pieceOfCode
    }
}).inject(widget.body);
  1. Add the event to an existing element

Create the element inside the XHTML source of the widget with a class attribute to identify it.

<a class="myLink">My link</a>

Adding the listener pieceOfCode() to the event "click" using UWA.Event.addEvent

widget.getElement('myLink').addEvent('click', pieceOfCode);

Removing events from a DOM Element

You can remove a listener associated with a particular event using the <UWA.Element.removeEvent> method.

Example setup: Adding the event "click" using "clickHandler" listener on an element with the class "myElement".

var myElement = widget.getElement('.myElement'),
    clickHandler = function (event) {
        // Process your event behavior here
    };

myElement.addEvent('click', clickHandler);

Then remove only the "clickHandler" listener associated with "click" event:

Element.removeEvent('click', clickHandler);

Or remove all "click" event listeners associated with the element:

myElement.removeEvent('click');

Stopping the propagation and prevent the default of an event on DOM Element

You can stop the propagation and prevent the default of an event using UWA.Event.stop method.

Example usage: Adding the event "click" using the "clickHandler" listener on element with the class "myElement" then stop propagation and prevent the default inside the listener using UWA.Event.stop.

var myElement = widget.getElement('.myElement'),
    clickHandler = function (event) {

        // Stop propagation and prevent default
        UWA.Event.stop(event);

        // Process your event behavior here
    };

myElement.addEvent('click', clickHandler);

You may also want to use only UWA.Event.stopPropagation or UWA.Event.preventDefault if you wish to achieve a particular behavior.

Retrieving the cursor position of an event on a DOM Element

You can get the current position of the cursor or finger (for touch events) using the UWA.Event.getPosition method.

Example usage: Adding the event "click" using the "clickHandler" listener on an element with the class "myElement" then retrieving the event position inside the listener using UWA.Event.getPosition.

var myElement = widget.getElement('.myElement'),
    clickHandler = function (event) {

        // Get cursor/finger position
        var eventPos = UWA.Event.getPosition(event);

        // Process your event behavior here
    };

myElement.addEvent('click', clickHandler);

Retrieving the target element of an event

One of the useful methodologies in the JavaScript world is event delegation, and for good reason.

Event delegation allows you to avoid adding event listeners to specific nodes; instead, the event listener is added to one parent.

Let's say that we have a parent UL element with several child elements:

<ul class="items-list">
    <li class="item">Item 1</li>
    <li class="item">Item 2</li>
    <li class="item">Item 3</li>
    <li class="item">Item 4</li>
    <li class="item">Item 5</li>
    <li class="item">Item 6</li>
</ul>

Let's also say that something needs to happen when each child element is clicked.

You could add a separate event listener to each individual LI elements, but what if LI elements are frequently added and removed from the list?

Adding and removing event listeners would be a nightmare, especially if addition and removal code is in different places within your app.

The best solution is to add an event listener to the parent UL element. But if you do so, how will you know which element was clicked?

Simple, when the event bubbles up to the UL element, you get the target using UWA.Event.getElement to gain a reference to the actual clicked node.

Here is a very basic JavaScript snippet which illustrates event delegation:

// Get the element, add a click listener...
widget.getElement('.items-list').addEvent('click', function(event) {

    // Set eventTarget has the clicked element!
    var eventTarget = UWA.Event.getElement(event);

    // If it was a list item
    if(eventTarget && eventTarget.getTagName() === 'li') {
        eventTarget.addClassName('clicked');

        // Process your event behavior here
    }
});