0

I have the jQuery function below which alters the CSS on hover of a p element.

$("p").hover (
function() {$(this).addClass("choice"); } ,
function() { $(this).removeClass("choice");} );

The problem is that it will not function for the innerHTML of a div written with .html() or .append(), like so

$('#div').html('<p>content that needs to highlight on hover</p>');

Even if I try to insert the function itself to that innerHTML like so

$('#div').append('<script type="text/javscript">$("p").hover ( function() {$(this).addClass("choice"); } , function() { $(this).removeClass("choice");} );<'+'/script>');

it will still not function for the HTML content of that div.

What am I missing here? Thanks, any help would be much appreciated.

1
  • P.S. I hope you're not using "#div" in your real code because that could very easily confuse someone. Either use "div" or "#usefulname". Using id="div" is a recipe for confusion. Commented Jan 30, 2012 at 4:15

3 Answers 3

3

When you write $("p").hover, that does a one-time search of the current state of the document, finds all <p> tags and attached event handlers to them. It will not attach event handlers to <p> tags you add to the document in the future.

If you want to have event handlers for future <p> tags, then you need to use .delegate() (for pre-jQuery 1.7) or .on() (for jQuery 1.7+).

With jQuery 1.7+, it would work like this:

$(document.body)
  .on("mouseover", "p", function() {})
  .on("mouseout", "p", function() {});

You have to use mouseover and mouseout events because hover with two separate callback functions is not supported with .on() (at least it wasn't the last time I checked).

Ideally, you wouldn't use document.body in this code, but would use some common parent element that is not dynamic (it's already there and stays there) and is as close in the hierarchy to the <p> tags that you're monitoring as possible. This keeps too many events from having to bubble all the way up to the document level and helps with performance.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks everyone. This approach works, however the .on() did not work for some reason, but .live() did.
@Scott - .live() has been deprecated for all versions of jQuery. You should not use it. You should use .on() or .delegate(). If you show your actual HTML surrounding the <p> tags you're adding, we could help you with the exact jQuery for .on().
Well this is what I have now, I opted for CSS to deal with hover, I'd like to use the .on() for click event now, heres what works with .live(). $('.select').live("click",function(){ $('#results').find('.select').removeClass("choice"); $(this).addClass("choice");} ); and $('#results').append('<div class="select"><input type="radio" value=""/>label</div>');
The .on() equivalent to $('.select').live("click",function(){}) is this: $(document.body).on('click', '.select', function() {});. You can try this first to verify it works, but then you would get better performance if you pick a parent object besides document.body that is closer to the .select objects, but always present.
$(document.body).on('click', '.select', function() {}); is not working. Why would this be? I'm using jQuery 1.7.1.
|
1

I would actually solve this with CSS as opposed to javascript if possible using the :hover pseudo class.

p { /* some css */ }
p:hover { /* hover css */ }

If you have to use javascript then see jfriend00's answer. I originally had an answer similar to his here, but jfriend's was sooner and better. I will leave this up as a note though for others.

2 Comments

Good idea. If you can do it with pure CSS, that's nearly always better than coding JS.
Actually, I think this is what I'm going to do to deal with hover. Thanks for the reminder.
0

You need to use an on (jQuery 1.7) or live function, which will attach events to elements that have been created after the page load

$("p").on("hover", function()) {
....
}

1 Comment

That is equivalent to his code. When the selector is not passed to on it works the same as hover.

Your Answer

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.