4

The goal

A good and definitively way to recall functions after something happened.

The problem

I'm working with some functions that must to be recalled when something happens. A simple example is a button like Twitter's following button.

Until here, all good. But, I do not know how to recall. Actually, I've already tried to use $.getScript of jQuery, but it causes many requests to the server and I do not feel comfortable with this behavior.

To illustrate the problem, I made this jsFiddle. When you hover the button for the first time, its style changes. When you click on it and click again, the "hover behavior" disappears.

I really do not know how to proceed.

$.getScript it is the best solution for this?

Someone have any suggestion?

The code (if jsFiddle down)

The Knockout on the code is just an example and it is irrelevant. I want to do this with ajax calls and everything what is possible.

HTML:

<div class="container">
    <!-- ko if: isAdded -->
    <button class="btn primary" data-bind="click: add">Add Xbox 360</button>
    <!-- /ko -->

    <!-- ko ifnot: isAdded -->
    <button class="btn btn-success primary remove" data-bind="click: remove">Xbox 360 already added</button>
    <!-- /ko -->
</div>

JavaScript:

$("button.remove").hover(function() {
    $(this)
    .removeClass("btn-success")
    .addClass("btn-danger")
    .text("Click here to remove");
}, function() {
    $(this)
    .removeClass("btn-danger")
    .addClass("btn-success")
    .text("Xbox 360 already added");
});

ViewModel = function() {
    var self = this;

    self.isAdded = ko.observable(false);

    self.add = function(item) {
        item.isAdded(false);
    };

    self.remove = function(item) {
        item.isAdded(true);
    };
};

ko.applyBindings(new ViewModel());
Travis J
  • 81,153
  • 41
  • 202
  • 273
Guilherme Oderdenge
  • 4,935
  • 6
  • 61
  • 96
  • recalled? You mean run/executed again? How does getScript get involved? It is not even in the fiddle – epascarello Jul 11 '13 at 19:34
  • I really don't see what the problem is here. – Bram Vanroy Jul 11 '13 at 19:34
  • 1
    This is about event handlers. Not sure what `$.getScript` is supposed to have to do with this. – Šime Vidas Jul 11 '13 at 19:34
  • I would either use event delegation, or a function that i can call when i need to bind the hover event to it again. or maybe even bind the hover effect on state change from add to it's been added – Kevin B Jul 11 '13 at 19:35
  • possible duplicate of [Event binding on dynamically created elements?](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Travis J Jul 11 '13 at 19:42

3 Answers3

5

You are going to need to use delegated events, which will stay bound as you add/remove/modify elements on the page. See the documenation for jQuery's on() function for more information about event delegation.

Note that this means you will need to use the mouseenter and mouseleave events instead of the hover() convenience method (which is just a wrapper for attaching listeners for mouseenter and mouseleave)

$(document).on('mouseenter', "button.remove", function() {
    $(this)
    .removeClass("btn-success")
    .addClass("btn-danger")
    .text("Click here to remove");
}).on('mouseleave', 'button.remove', function() {
    $(this)
    .removeClass("btn-danger")
    .addClass("btn-success")
    .text("Xbox 360 already added");
});

Working Demo

cfs
  • 10,610
  • 3
  • 30
  • 43
2

You need to use event delegation so the handler is bound for current and future elements:

$('.container').on('mouseenter', 'button.remove', function() {
    ...
}).on('mouseleave', 'button.remove', function() {
    ...
});

http://jsfiddle.net/2KUp8/5/

Read more about event delegation here.

jbabey
  • 45,965
  • 12
  • 71
  • 94
0

You can use on method for dynamically added elements

$(document).on("mouseover", "button.remove", function(e) {
    $(this)
    .removeClass("btn-success")
    .addClass("btn-danger")
    .text("Click here to remove");
});

$(document).on("mouseleave", "button.remove", function(e) {
    $(this)
    .removeClass("btn-danger")
    .addClass("btn-success")
    .text("Xbox 360 already added");
});

FIDDLE

Khawer Zeshan
  • 9,470
  • 6
  • 40
  • 63