4

Any emulation or alternative of live jquery function ?

I need to use an alternative of the live function without JQuery and JQuery.Live.

Especialy that i need to use addEventListner for future elements on the page.

Any alternative?

Thanks

2 Answers2

2

Something like the following should work:

var live = function(elm, eventType, callback) {
    document.addEventListener(eventType, function(event) {
        if(event.target === elm) {
            callback.call(elm, event);
        }
    });
};

You would then use it like follows:

var element = document.getElementById('test');
live(element, 'click', function() {
  // handle click event here
});

EDIT: Excellent comments below. Here is a revised version:

var live = function(selector, eventType, callback) {
    document.addEventListener(eventType, function(event) {
        var elms = document.querySelectorAll(selector),
            target = event.target || window.event.srcElement;
        for (var i=0; i<elms.length; i++) {
            if (elms[0] === target) callback.call(elms[i], event);
        }
    });
};

Use it with css selectors

live('#test', 'click', function() {
    // handle click event here
});

jsFiddle: http://jsfiddle.net/49aJh/2/

Rob Johnstone
  • 1,704
  • 9
  • 14
  • 1
    It's close, but won't target elements properly. Look at the link from the comments on the OP: http://stackoverflow.com/questions/9198771/how-to-apply-live-like-feature-for-javascript-appended-dom-elements . If you are looking for a specific element, but the event happened in a nested element within it, this won't work. For example, if you wanted to target a `
      `, you could click on a nested `
    • `, and the condition would fail. Also, your code assumes the `#test` element is available at all times - you can't do a DOM element reference check - you have to use attributes
    – Ian May 22 '13 at 14:39
  • 1
    It doesn't work for FUTURE elements created after the Document load. We need a kind callback function that add a listner for any future auto-created elements. – Mohamed Hédi Lassoued May 22 '13 at 14:51
  • 1
    @Ian - thanks for your (entirely correct) observations. I think the revised version should work better – Rob Johnstone May 22 '13 at 14:59
  • Target is : Adding event listeners to current and future elements. – Mohamed Hédi Lassoued May 22 '13 at 14:59
  • 1
    @MohamedHédiLassoued The revised version works for both current and future elements as requested – Rob Johnstone May 22 '13 at 15:06
  • It will add the click listner to all of document elements. Here is an exemple that will popud an alert for all documents clicks but i need to track just google.com link clicks. var live = function(selector, eventType, callback) { document.addEventListener(eventType, function(event) { var elms = document.querySelectorAll(selector); for (var i=0; i – Mohamed Hédi Lassoued May 22 '13 at 16:26
  • 2
    @MohamedHédiLassoued - fixed error and added a jsFiddle to confirm it works – Rob Johnstone May 22 '13 at 18:17
  • 3
    Why does it say `if (elms[0] === target)`? Shouldn't it be `if (elms[i] === target)`? – Xeoncross Jul 10 '14 at 18:31
1

You can emulate the .on() functionality with this code:

HTMLElement.prototype.on = function (type, selector, func) {
    var attach = window.addEventListener ? "addEventListener":"attachEvent",
      elements = this.querySelectorAll(selector);
    this[attach](type, function (e) {
        var target = e && e.target || window.event.srcElement,
           success = false;
        while(target != this){
            console.log("searching"+ target);
            if (contained()){
                success = true;
                break;
            }
            target = target.parentNode;
        }
        if(success){func()}
        // helpermethod
        function contained(){ for (var i=elements.length;i--;){ if(elements[i] == target) return true; } }
    });
};

document.querySelector("div").on("click", "span", function() {
    console.log("gotcha!");
});

Should work in all browser down to IE8.

Example

Christoph
  • 50,121
  • 21
  • 99
  • 128
  • Also beware you shouldn't extend the DOM: http://perfectionkills.com/whats-wrong-with-extending-the-dom/ – Ian May 22 '13 at 15:11
  • Also note this doesn't work: http://jsfiddle.net/RJgaE/1/ – Ian May 22 '13 at 15:15
  • 1
    @Ian I know that article, and I know the caveats but I didn't want to provide a whole wrapper just for demonstration's purposes. – Christoph May 22 '13 at 15:16
  • I understand, I was just providing it as a reference for anyone who sees this – Ian May 22 '13 at 15:17
  • @Ian but valid point with your second comment, need to check parentElements too... – Christoph May 22 '13 at 15:18
  • Just trying to help get a solid answer :) If it helps, http://stackoverflow.com/questions/9198771/how-to-apply-live-like-feature-for-javascript-appended-dom-elements basically does it – Ian May 22 '13 at 15:19
  • I found the solution here : – Mohamed Hédi Lassoued May 22 '13 at 17:00
  • 1
    @Ian please have a look at the revised solution;) – Christoph May 22 '13 at 17:03
  • @Mohamed I see no link? Have a look at my revised version. – Christoph May 22 '13 at 17:04
  • This post contain the solution but fire another issue (privacy, External iFrames, ++): http://stackoverflow.com/questions/16699484/addeventlistner-to-an-iframe-from-different-domain Origin Post: http://stackoverflow.com/questions/9198771/how-to-apply-live-like-feature-for-javascript-appended-dom-elements – Mohamed Hédi Lassoued May 22 '13 at 21:37