0

HTML

<div class="pop-circle Cats"></div>

CSS

.pop-circle { width:8px;height:8px;border-radius:4px;background-color:#50377A; }

JS

$(".pop-circle").attr("title", "blah");

Works as expected. However, later on (after user interaction) if I .append(mydiv) several more divs (Cats, Dogs, etc.) that have the same "pop-circle" class, the title attribute isn't added to them. Which makes sense, there was no new event. So what would you do?

My first idea was to do this:

$("div.pop-circle").hover( function() {
    $(".Cats").attr("title", "cats");
    $(".Dats").attr("title", "dogs");
    // ...
});

I figure the hover should trigger even on divs that are appended after the page is loaded. However, this has a strange effect, the attribute isn't added, at least not the first few times I hover the div, or not at all. (Sorry I don't want to show a live example of the divs appending.)

I'm wondering if there's a more sensible way to do this.

PJ Brunet
  • 3,615
  • 40
  • 37

5 Answers5

2

Listeners are not attached to new dynamically created elements. You need to reregister any event listeners after you append code. It's generally helpful to collect them in a function and call them again.

function ActivateListeners() {
    $('div.pop-circle').hover(function() {
       //do something 
    });
}
ActivateListeners();

$('something').click(function() {
    $('body').append("<div class='pop-circle'>Stuff</div>");
    ActivateListeners();
});

EDIT: While this works, passionateCoder's answer (using .on()) is the proper way to handle this issue.

Patrick
  • 861
  • 6
  • 12
2

For such a situation like this, I'd say that writing a function which automatically adds title to the element is the best way there is.

Or if you want to make the hover work, you'd have to bind it to the document or a static parent and from there on delegate this event to the div elements.

$(document).on("mouseover", ".pop-circle", function () { //or instead of document use IMMEDIATE STATIC parent
    var title = $(this).attr("class").split(" ")[1]; //taking out the extra thing out of the class attribute - the animals
    $(this).attr("title", title);
});

Your HTML now looks like this :

<div class="pop-circle Cats"></div>
<br/>
<div class="pop-circle Dogs"></div>
<br/>
<div class="pop-circle Rats"></div>
<br/>
<div class="pop-circle Monkeys"></div>
<br/>
<button>Add more</button>
<input type="text" />

My code for adding an extra .pop-circle :

$("button").on("click", function () {
    var animal = $("input:text").val();
    $("input:text").val("");
    $(this).before("<div class= 'pop-circle " + animal + "' ></div>");
});

The reason the hover didnt work the way you coded it is because, when you bind the hover to the .pop-circle, it gets bound only to the existing elements and not to the future elements. To support future elements you'll have to bind this event to its parent, like document or "body".

Here's a demo : http://jsfiddle.net/hungerpain/zxfL2/1/

krishwader
  • 11,341
  • 1
  • 34
  • 51
2

Thanks @passionateCoder for the "bind this event to its parent"

Here's what I ended up using:

$("#content").on("click mouseover", ".pop-circle", function() {

    $(".Dogs").attr("title", "Dog Categories");
    $(".Cats").attr("title", "Cat Categories");
    // ...

});
PJ Brunet
  • 3,615
  • 40
  • 37
0

From my understanding, the attr() method in jQuery only gets the attributes as they are defined at load time and will not contain values changed by scripts. Version 1.6 of jQuery introduced the prop() method which reflects changes made to the DOM after a page has been loaded. Usage is identical.

EDIT: After re-reading your question I may be off course here. My apologies. Maybe prop() will come in handy some day though! :)

trnelson
  • 2,715
  • 2
  • 24
  • 40
  • I ended up reading about .prop() in the process of researching this, however it sounds like .attr() is the appropriate choice for setting HTML attributes, which is what I'm doing here, and .prop() is for object properties. How often you can use one or the other interchangeably, I don't know. I'm just scratching the surface here and I'm no expert, but I think .prop() was supposed to entirely replace .attr() at one point in time, then there was some backlash, and now I think .attr() is here to stay going forward. – PJ Brunet Jun 18 '13 at 17:43
  • @PJBrunet you might be right. My knowledge of it is somewhat limited. I did come across a well-received SO answer here which clarifies very well: http://stackoverflow.com/a/5876747/638087 – trnelson Jun 18 '13 at 18:35
0

You could add a data attr to the div then use that to create the title.

http://jsfiddle.net/pjdicke/53Yf9/1/

$("#output").on('mouseenter', '.pop-circle', function () {
    var type = $(this).data('type');
    $(this).attr('title', type);
    alert( $(this).attr('title') );
});

$('button').on('click', function () {
    var newItem = $('<div class="pop-circle" data-type="Dats"></div>');
    $(newItem).appendTo('#output');
});
pjdicke
  • 299
  • 2
  • 12