JSFiddle - React, Tailwind, and code Playground

Pet-a-bunny! Explain YUI event subscription and event delegation in DOM nodes and operations.

by David Iglesias

HTML

<h1>Pet-a-bunny!</h1>
<p>
    <!-- Add new bunnies ("AJAX" request) -->
    <button class="adder" data-bunny-class="regular" data-bunny-name="Fluffy-looking">+ regular</button>
    <button class="adder" data-bunny-class="killer" data-bunny-name="Vicious-looking">+ killer</button>
    <!-- get all new bunnies ("AJAX" request) -->
    <button id="reset">Reset</button>
</p>

<div id="bunny-box">
    <ul>
        <!-- initial dataset (coming from the server) -->
        <li class="regular">Thumper</li>
        <li class="killer">Fangs</li>
        <li class="regular">Fluffy</li>
        <li class="killer">Bloodlust</li>
    </ul>
</div>

<p id="output"></p>

CSS

body { font-family: "Arial", sans-serif; }
h1 { font-size: 2em; font-weight: bold; margin: 1em 0px;}
p, ul { margin-bottom: 1em; }
ul { padding-left: 1em; }
ul li { cursor: pointer; padding: .5em; }
ul li.regular { border-left: 4px solid #090; }
ul li.killer { border-left: 4px solid #900; }
em { color: #090; }
strong { color: #900; }

JavaScript

YUI().use('node-event-delegate', function(Y) {
    // Attach behavior to the click of a single button
    Y.one('#reset').on('click', function(ev) {
        Y.one('#output').empty();
        Y.one('#bunny-box').empty().append(generateBunnies(1, 10));
    });

    // Attach behavior to ALL buttons with class "adder"
    Y.all('button.adder').on('click', function(ev) {
        var bunnyClass = ev.currentTarget.getAttribute('data-bunny-class'),
            name = ev.currentTarget.getAttribute('data-bunny-name');
        item = '<li class="' + bunnyClass + '">' + name + '</li>';
        Y.one('#bunny-box ul').append(item);
    });

    // Attach behavior to ANY element that has class="killer"
    // inside the "#bunny-box" container        
    Y.one('#bunny-box').delegate('click', function(ev) {
        var name = ev.currentTarget.getContent();
        Y.one('#output').append('<strong>' + name + ' KILLED YOU!</strong><br />');
    }, '.killer');

    // Attach behavior to ANY element that has class="regular"
    // inside the "#bunny-box" container        
    Y.one('#bunny-box').delegate('click', function(ev) {
        var name = ev.currentTarget.getContent();
        Y.one('#output').append('<em>' + name + ' loved you!</em><br />');
    }, '.regular');

    /**
     * Auxiliary function to generate random good and bad bunnies
     * @param min {Number} Minimum number of bunnies
     * @param max {Number} Maximum number of bunnies
    * @return {String} A <ul> filled with random <li> bunnies
     */
    var generateBunnies = function(min, max) {
        var numBunnies = Math.floor(Math.random() * (max - min + 1)) + min,
            output = "<ul>";
        for (var i = 0; i < numBunnies; i++) {
            var isEvil = (Math.floor(Math.random() * 2) % 2 == 0);
            output += "<li class='" + (isEvil ? "killer" : "regular") + "'> " + (isEvil ? "Hungry-looking" : "Nice-looking") + "</li>";
        }
        return output + "</ul>";
    };

});