13/14 explanation why we can't use $('.item').click


#1

Hi guys,
in the description of the task there is a:
$('.item').click(function() {
$(this).remove();
});

where say that is not a good idea to use it. I have tried and it work. Can someone give me more detail why this solution is not good?

Thank you.


#2

Hi Zoran,

$('.item').click(...); doesn't work for me, and I'm pretty sure not for anyone else. .on('click', '.item') listens for clicks anywhere on the page, and if they happen to be on an element with the .item class, it runs the code. $('.item').click() checks the page for elements with the .item class, and if one of them gets clicked, it runs the code.
The difference is that on() is listening for clicks everywhere on the page, and only runs the code if the element is what you're looking for, but click() checks just once if there are any .items, on page load. If there are, it listens for clicks on them. And if there aren't, it does nothing.

So click() doesn't remove the items because there are none on page load.


When you say it works for you, do you mean you're being passed by the lesson, or that you can actually remove items with click()?


#3

Great explanation, this is exactly what I needed to know. Thank you!


#4

Hello Guys,

I'd like to add just a couple of examples to show what @soulskybg may have tested. These are based on @zystvan's explanation (which is super cool). So here it is a brief recap of the main difference between:

    $('.item').click(function() {
        Do something!
    });

and

$(document).on('click', '.item', function() {
    Do something!
});
  • The former checks just once if there are any .items elements on the loaded page. If so, then the event handler .click() listens for clicks on them. Upon clicking on such elements, the handler will run the "Do Something!" code. Otherwise, it does nothing.

  • The latter listens continuously and anywhere on the loaded page for clicks. When it gets a click, then it checks if it was on an element with the .item class. If so, then it runs the code "Do something!" (in our particular case, it will remove the just added item). Otherwise ,again, it does nothing.

To see with your eyes a practical example of this difference, make the following changes:

  • In the index.html tab, add one or more <div class="item">Write Anything</div> within <div class="list"></div> (which is basically what you would do by clicking on the Add button)

  • In the script.js tab, inside your $(document).ready(), but after and outside your $('#button').click(), add the first suggested alternative to remove an item from the list. That is:

    $('.item').click(function() { $(this).remove(); });

Once the test window will parse all your new changes at runtime, you should see one or more items already entered in the list. Now here there are a couple of test that you could do:

  1. The most basic one, try to click on the item/s. As you will notice you are able to remove them, even though we are using the first code solution. The answer is explained above, when I recap the main difference described by @zystvan.

  2. Second test: make the page reload the item/s you manually entered as html element (that is, refresh to the initial html output). Then start adding new items with the Add button (tip: give them a unique name so to be able to distinguish the ones added via the button from the ones manually entered). Afterwards, start clicking randomly on the list's items. You will notice that the ones manually entered can be removed, whereas the ones added via button cannot be deleted.

I hope that with the given examples above, now it should be easier to understand why, as explained by the codecademy exercise itself, you won't be able to remove items only entered via the Add button with the $('.item').click(function() { $(this).remove(); }); implementation.

Cheers!


#5

@nooneknows88 Good post! To clarify this bit:

I may be misunderstanding what you meant (although I think you do understand how it works), but on('click', '.item') listens for clicks, not .items, and when it gets a click, then it checks if it was on an element with the .item class, rather than continuously checking for .items that might be appearing on the page & attaching event listeners to them, like your post seems to indicate :)


#6

@zystvan Yep, you're right. It could be misleading. I corrected it. Thanks for the clarification :smile: