0

I am trying to do this:

  1. Get ID from data-status attribute of .addlink and store it as post_id.
  2. Clicking on .mar-post_id will toggle .finished-reading from #statusfor-post_id

I have the following code but it does not work. What could I be doing wrong?

jQuery(".addlink").click(function(){
    var post_id = jQuery(this).attr("data-status");
    jQuery(".mar-"+post_id).click(function() {
        jQuery("#statusfor-"+post_id).toggleClass( "finished-reading" );
    });
});

The following is the HTML markup.

<div class="simple-card" id="statusfor-12">
<div class="simple-card-actions">
<span class="wpfp-span">
<a class="addlink mar-12" href="#" data-status="12">Click me to toggle</a>
</span>
</div>
</div>
Sam
  • 329
  • 1
  • 6
  • 21

1 Answers1

1

I have created a fiddle from your code to test this out and it works as you'd expect.

But there could be a problem if you have different html structure, i.e. if .mar-* is nested inside .addlink. The problem in this case is that you add new click event every time, so if you click .mar-*, you'll trigger .addlink's click event, adding new click event listener, so the toggle will trigger multiple times.

It's hard to guess how to fix this without seeing full page structure, best thing that I can suggest is take a look at .one().


After question update:

Here's a dirty hack, which adds only one listener to the element: jsfiddle. Keep in mind that _data works in jQuery 1.8+, prior to that it was available as .data (source).

I wouldn't recommend to use this, as _data is private property, so this might break in future.

You could also use vanilla JS addEventListener, without useCapture attribute.

Better approach:

One thing that comes to mind is changing structure of your elements or change when you add click events. It's a bad practice to add an event every time you click something, I would recommend you to add all click listeners as soon as the element is added to page (on domready/window load or when you receive data from ajax call) and then don't change the events after that.

Community
  • 1
  • 1
Marko Gresak
  • 7,950
  • 5
  • 40
  • 46
  • Exactly, `.mar-*` is inside .addlink. I will take a look at `.one()`. Thank you! – Sam Dec 27 '14 at 15:03
  • Mind that `.one` executes only once, so only first click will work and then it will be disabled. Only way for inner click function to be called again is adding `.one` listener again. – Marko Gresak Dec 27 '14 at 15:05
  • I've updated my question, I hope this is more helpful to you. – Marko Gresak Dec 27 '14 at 15:32
  • it works nicely but as you can see, first click is required for the `post_id` to get stored and only then the toggle works. – Sam Dec 27 '14 at 15:35
  • I know that, that's why I've recommended you to add click events as soon as you create elements, not after user clicks inside `.addlink` – Marko Gresak Dec 27 '14 at 15:36
  • OK, I think I'd rather shuffle the markup as that is the easiest approach. So, I'll mark this as an answer! – Sam Dec 27 '14 at 15:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/67760/discussion-between-maremp-and-sam). – Marko Gresak Dec 27 '14 at 15:45