2
\$\begingroup\$

I have taken a look at several answered questions on Stack Overflow about jQuery's new (since 1.9.1 upgrade)

.on('click','',function(){}

and that you need to delegate. However, in each one, it just provides the solution to fix the issue, but I need a bit more finest or an explanation to why it must be done like that.

Here is my code segment which I have already made it working. My question will follow after the code.

jQuery(document).ready(function($){
 /* Shopping Cart Items */
 $(".header-shopping-cart div .toggle-items").on('click', function(){ // Show/Hide Shopping Cart Items
 if ($(".header-shopping-cart-items").css("display") == "none" && $("#items-amount").html() > 0) {
 $(".header-shopping-cart-items").fadeIn();
 $(this).find("i").removeClass("icon-angle-right").addClass("icon-angle-down");
 }
 else {
 $(".header-shopping-cart-items").fadeOut();
 $(this).find("i").removeClass("icon-angle-down").addClass("icon-angle-right");
 }
 return false;
 });
 $(document).on('click','.header-shopping-cart-items .item a', function(){
 var amount = $("#items-amount").html();
 if (amount > 0) {
 $("#items-amount").html(amount - 1); // Dicrease the amount of SC items
 $(this).parent().slideUp(); // Hide this item
 if (amount - 1 == 0) {
 $(".header-shopping-cart-items").fadeOut(); // When there's no any items in the cart, hide the items block
 $(".header-shopping-cart div .toggle-items i").fadeOut();
 }
 }
 return false;
 });
});

The short end of the code basically have two purpose: one the toggle makes it so that when press a drop down opens up.

The second one (which is where I have confusion on) enables a way to remove (or delete) a row from the drop down.

My questions:

  1. When the HTML used to be static, I can do both the operation of toggling the HTML and the deletion of the row without issues. However when I now append the row, I could no longer remove the row by hitting the second on('click'). So I had to modify it with $(document) and then shift the .header-shopping-cart-items .item a into the delegation position. I don't know why it is that.

  2. Must I use the document as the starting point of the delegation? Is it because these rows are not statically there at first and were actually generated later via an event.

  3. If I want to omit

    jQuery(document).ready(function($){
    //code
    });
    

    I should have done IIFE instead - however is there a "trap" in doing so. Trap as in must I start changing the code structure around in order to achieve the same effect.

Please note that I read this in order to fix my JavaScript up to achieve the current code which works.

asked Apr 3, 2014 at 3:09
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I'm not sure this question really fits into the site but I'm going to answer it anyway.

  1. Since the elements don't exist when the page is loaded you can't add a click event to it (yet). If you try to attach the event handler directly to the elements at this time it won't do anything since the elements don't exist. So instead you attach the click element to the document element (which does exist) and then when the click handler is fired (with a click anywhere on the document) it looks to see if the click event was done on an object that matched the selector you entered at that point. If it was then the click handler is fired.

    That was confusing even to me. Let me try a different way.

    Option 1

    Attempt to attach the event handler to the actual element on page load using the selector.

    $('.class-name').on('click', function(){})
    

    The element does not exist yet so this does nothing.

    Option 2

    Attach the event handler to a static element and provide a delegated selector to test for when the item is clicked.

    $(document).on('click','.class-name', function(){})
    

    This event handler is successfully added to the document object. Now when any click happens within the document, the selector is tested and if a match the function is fired.

  2. No, but you need to use a static element. I used the document but it could be any static element as long as all dynamic elements will be contained within. In your case it might be something like $('.header-shopping-cart-items').on('click', '.item a', function() {}) provided the .header-shopping-cart-items container were static (always there).

    Another option, although much more difficult and probably not worth the effort would be to attach the event handler directly to the item row when you inject it. I wouldn't recommend that approach.

  3. You could look into putting this into a module and calling that module when needed. But I don't know that you would be gaining anything by putting this into a IIFE. And I wouldn't say that IIFEs are preferred over the jQuery.ready function. That said, this whole code could probably be put into a IIFE without any changes. You would just need to put it at the bottom of the document.

answered Apr 3, 2014 at 5:20
\$\endgroup\$
4
  • \$\begingroup\$ #2) So I could have attached myself to any close static element (a div even) rather than a dom? #3) is a question: I'm basically asking to convert from a document.ready into a non document.ready (since that is the prefered practice) what are the kind of pitfall or if there isn't any really. \$\endgroup\$ Commented Apr 3, 2014 at 5:36
  • \$\begingroup\$ #2) Any static element that is a container of all the items you will need to handle with the event handler. \$\endgroup\$ Commented Apr 3, 2014 at 5:38
  • \$\begingroup\$ I put my notes on #3 in an edit to my answer. \$\endgroup\$ Commented Apr 3, 2014 at 5:44
  • \$\begingroup\$ My pleasure, I hope it was helpful. \$\endgroup\$ Commented Apr 3, 2014 at 17:22

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.