1

html

<span><a class="like-Unlike" href="">Like</a></span>

my.js

$(".like-Unlike").on('click',function (e) {

        if ($(this).html() == "Like") {
            $(this).html('Unlike');
        }
        else {
            $(this).html('Like');
        }
        return false;
    }
);

Problem is : the Like button doesn't work as a toggle button without error message, but after I return all the above javascript into console, it works.

ming
  • 409
  • 1
  • 4
  • 13
  • What error? And what do you mean "after I return all the above javascript into console"? – Carcigenicate May 06 '17 at 15:11
  • Are the elements generated dynamically? – Mr. Alien May 06 '17 at 15:12
  • @Carcigenicate there is no error message. I copied and entered the whole js snippet into chrome F12 console – ming May 06 '17 at 15:15
  • @ming Ahh, I see. Then I'd say you should answer Mr. Allen's question. You might be trying to toggle the element before it's been loaded. Add everything into a `document.onload` callback and see if it works. – Carcigenicate May 06 '17 at 15:16
  • Sorry, but I VTC this question as _This question was caused by a **problem that can no longer be reproduced** or a **simple typographical error**._, I tested and it works great. if you're adding the elements dynamically then it would be a duplicate of one of the many "**event delegation**" questions on SO – Alon Eitan May 06 '17 at 15:16
  • @Mr.Alien yes! they are – ming May 06 '17 at 15:17
  • Are you executing the JS inside a $(document).ready() statement? – granch May 06 '17 at 15:18
  • @ming [Read this](https://learn.jquery.com/events/event-delegation/) to learn more about event delegation (Basically this `$("span").on('click', ".like-Unlike", function (e) {`should work) – Alon Eitan May 06 '17 at 15:18
  • @MatiasCerrotta doesn't matter.. piece of code will invoke onclick only and not onload :) – Mr. Alien May 06 '17 at 15:44

2 Answers2

2

As you confirmed that the elements are appended dynamically, these appended elements do not have the click handler attached to them. To make this work, you need to use event delegation. Instead of you attaching the event handler to the button, you bind it to the parent element, or say body, and modify the on like

$('body').on('click', '.like-Unlike', function(e) {
  e.preventDefault(); //don't use return false; has nothing to do with the issue though

  var elm = $(this); //cache the element
  (elm.text() == 'Like') ? elm.text('Unlike') : elm.text('Like'); //keeping it short
});

For more on event delegation

Community
  • 1
  • 1
Mr. Alien
  • 140,764
  • 31
  • 277
  • 265
2

A couple of things:

  1. When strings get larger checking of the exact match of the string will not be fun, so I decided to add in some .data's. I didn't use global variables to avoid naming conflicts and so your code can support more than one button.
  2. I added in event delegations so even if you add it dynamically (via JS) it will still work.
  3. Finally, for JavaScript-based links you should either do e.preventDefault or set the href to # or javascript:void(0);

$(document.body).on('click',".like-Unlike",function (e) {
  var $el = $(this);
  if ($el.data("liked")) {
    $el.html('Like');
  } else {
    $el.html('Unlike');
  }
  $el.data("liked",!$el.data("liked"))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span><a class="like-Unlike" href="javascript:void(0)">Like</a></span>
Neil
  • 13,042
  • 2
  • 26
  • 48