:hover selector doesn't work with jQuery 1.4 - javascript

Googled about it - found nothing.
I'm talking about CSS :hover, not jQuery .hover().
So, the code:
$('#something a:hover').css({'something': 'thomesing'});
works fine with 1.3, but not with 1.4. How to fix it?

Follow the rules
This is a superb example of why we must always code according to the documentation, and not according to the possibilities. Hacks, or mere oversights like this, will eventually be weeded out.
The proper jQuery (plain css is better) way to do this follows:
$("#something a").hover(
function() {
// $(this).addClass("hovered");
$(this).css("color", "red");
},
function() {
// $(this).removeClass("hovered");
$(this).css("color", "black");
}
);
The $.fn.hover method takes up to two arguments and serves as syntactic sugar for more explicit pointer (mouse) events. In fact, the hover method in jQuery 2.1.0 was nothing but this:
function( fnOver, fnOut ) {
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
}
Understand your code, and be concise
As you can see, the fnOver function is called when you enter the element, and again when you exit (if no other method is provided). With this understanding, we can setup simpler instructions:
$("#something a").hover(function () {
$(this).toggleClass("hovered");
});
Native almost always wins
Ultimately, vanilla CSS is the way to go. The :hover pseudo-class has been around for a long time, and works with targeting not only the element to which it belongs, but nested elements as well:
#something a:hover {
background: red;
}
#something a:hover .icon {
animation: 2s rotate ease-out;
}
With something as broadly-supported as :hover, I can think of no good reason to avoid it.

:hover is not a documented pseudoclass selector.
Try this:
$('#something a').hover(function(){
$(this).css({'something': 'thomesing'});
},
function(){
$(this).css({'something': 'previous'});
});
Although, you'd be better to use CSS classes:
$('#something a').hover(function(){
$(this).toggleClass("over").toggleClass("out");
},
function(){
$(this).toggleClass("over").toggleClass("out");
});
http://docs.jquery.com/Events/hover
EDIT:
In respose to BlueRaja's comment below, the following would be more suitable:
$('#something a').hover(function(){
$(this).addClass("over").removeClass("out");
},
function(){
$(this).removeClass("over").addClass("out");
});

hover changed in 1.4 and funny no one here seems to have bothered checking the jQuery docs...
$("#something a").hover(
function () {
$(this).toggleClass("active")
}
);
Change the colors via css.
Note:
Calling $(selector).hover(handlerInOut) is shorthand for:
$(selector).bind("mouseenter mouseleave",handlerInOut);

:hover is not supported in jQuery (see docs).
It doesn't really make sense either: jQuery selectors are used to select elements. What would ":hover" select?
I'm surprised it even works in 1.3

I don't think it does work in 1.3. As Philippe mentioned, it doesn't make sense.
:hover is an event, not an attribute. So I don't see how that selector could work.
You could either use the hover function as antpaw mentioned - http://docs.jquery.com/Events/hover#overout
or you could set a css style rule. e.g.
$('head').append("<style type='text/css'>#something:hover{foo: bar}</style>");

you can use .hover() function or even better plain css

To me, that selector doesn't make much sense, because it depends on an event by the user. Selectors are more about static content, where as the function hover() can track an event. The user would have to have his mouse on top of the content when you made the call.
There might be some cases that it would be useful, but in the case you mentioned, Jonathon Sampson has the right answer. Use $("#something a").hover(function() {$(this).css("something","thomesing");}); instead.

How jQuery works is that it parses selectors (whether css or regular ones) and then returns the jQuery object. As of today , jQuery doesn't support ':hover' selector.
It might work in Chrome or FF or Safari, but will definitely fail in IE6, 7 and 8.
Great workaround would be to either use jQuery's hover() method.
In more complex cases you want to register mouseenter and mouseleave event handlers on container that you want to select with ':hover', and add/remove '.hover' class.
Once the regular 'hover' class is there, you can easily access that container element from anywhere in the code using '#container.hover' selector.
Let me know if you need help coding this...

Related

Jquery $(this) not working inside function

I am trying to use waypoints.js to have elements fadein when scrolling to hit the elements.
I have
$(document).ready(function(){
$('.card').waypoint(function(down) {
console.log('hit element');
$(this).addClass('card-fadeIn');
}, { offset: '100%' });
});
What this does is adds the class 'card-fadeIn' which is opacity 1 and an ease in animation.
When I change it to
$('.card').addClass('card-fadeIn');
It works fine, but adds opacity 1 to every card class and ruins the fadein effect. I was trying to use $(this) instead but it wont fadein, nor will it give an error in the console. Any ideas why?
You have to use
$(this.element)
in a Waypoint handler. So,
$(this.element).addClass('card-fadeIn');
should do what you want.
$(this) works inside jQuery callbacks because jQuery is designed for things to work that way. There's nothing magic about it, however, so if this doesn't refer to a DOM element, you'll get a jQuery object that won't do anything (and which won't report any errors, because, again, that's just how jQuery works). The Waypoint library binds this to its own context object, and that exposes a reference to the DOM element involved in the callback as the "element" property.
Have you tried this.element?
$(document).ready(function(){
$('.card').waypoint(function(down) {
console.log('hit element');
$(this.element).addClass('card-fadeIn');
}, { offset: '100%' });
});

JQuery / Live is deprecated, well okay… But is not replaced

On is not working as a replacement for live; as the new ON is NOT working for future elements. No problems in my implementations; I'm used to use live and I definitely know when something works or not with jquery.
haml part :
.field
%label Select a file
= file_field_tag 'post[image]', :class => :dashed
%span.adder + add another file
coffe part :
$("span.adder").on "click", (e) ->
new_field = $(this).closest(".field").clone()
$(new_field).insertAfter( $(this).closest(".field") )
Why the new span.adder added does not have the jquery behaviour attached to their class ?
Something like this shoudl work in that case.
Why the JQuery guys did remove it ?
I don't get it.
UPDATE
$("span.adder").on("click", function(){ });
Will not work as live.
It has to be
$(document).on("click", "span.adder", function(){ });
(thanks for everyone's answers.)
To work with future elements you must use on document like this
$(document).on('click', 'span.adder', function(){
//Code here
});
Before .on() ever came around, .live() was already considered an inefficient way to handle event binding, Because of that for future use you have to use .on()
e.g:-
$(document).on('click', '#yourElement', function() {
// your functions here
});
There is a better explanation here
It is a replacement. The direct translation would be:
$(document).on('click', '.my-selector', function() {});
They deprecated and remove it because they had better implementation. You see the documentation of .on()
$(ancestor).on(event, element, function);
You should use that as ancestor which is near to that element. There are some performance issues.
Upgrade jQuery version also.
On works asdelegate` used to do, not exactly as .live; you have to use it on a parent and then specify the event and the children that triggers it; something like.
$(window).on("click", ".button", function(){
alert("You clicked the button... and I hate alerts");
});

jQuery 1.8: unsupported pseudo: hover

The following code raises the error unsupported pseudo: hover on jQuery 1.8, while it works perfect on jQuery 1.7.2:
if(!$(this).parent().find('ul').first().is(':hover')) {
$(this).parent().parent().removeClass('open');
}
Does anyone know what's going on?
Unfortunately, while we all wish that our code were future proof, your $('foo').on( 'hover, ... function(){ //do stuff } code is deprecated in jQuery 1.8. I wish I had better news for you, but your code is broken because of a core change to jQuery 1.8. You now have to use the syntax
$('.selector').on( 'mouseenter mouseleave', function() {
$(this).toggleClass('hover');
}
);
if(!$(this).parent().find('ul').first().hasClass('hover')) {
$(this).parent().parent().removeClass('open');
}
Wish I had better news for you, but deprecation happens :/ ... jQuery 1.8 doesn't like your shortcut and they've deprecated the hover event handler from .on() and also the pseudo-selector :hover, so it can't be used that way any more.
Old question, but for anyone googling:
A workaround for this is to go the other way round:
$(":focus, :active").filter($(".your-element"));
…because .filter() also accepts jQuery objects, this will match any elements with the pseudos :focus and :active that also have the class .your-element.
In other words, if .your-element isn't hovered or active, this selection matches no elements.
weird - for me, .is(":hover") is still working in 1.8, but broken in 1.9.1.
Anyway, here is a fix
function mouseIsOverWorkaround(what){
var temp = $(what).parent().find(":hover");
return temp.length == 1 && temp[0] == what;
}
then call above function on the "naked" (non jQuery-wrapped) element. In your case,
if(!mouseIsOverWorkaround($(this).parent().find('ul').first()[0]) {
$(this).parent().parent().removeClass('open');
}
(don't forget the [0])
the above-mentioned (comment to orig question) fiddle http://jsfiddle.net/nnnnnn/Tm77a/ does not work in jQuery 1.9.1
fiddle with this one http://jsfiddle.net/mathheadinclouds/BxL4w/

"#button_1" isn't affected by .click() or .hover()

Probably a rookie mistake, but my #button_1 ID isn't affected by the click() or hover() jQuery effects.
If someone could take a quick look at my JSFiddle, it would be greatly appreciated.
It's probably pretty obvious, but I want #button_1 to act as every other button. :)
Again, I suspect it's a pretty stupid mistake, something that I've overlooked.
Don't repeat so much code , try this and its working
Try line by line , its throwing error in somewhere in the code and breaking the bind events.
you have some error in hover or so , remove everything and have bind events, they are work.
You know this right ,when line 1 breaks in documentready , all bindings below may not get binded.
$(document).ready( function () {
$('#button_1,#button_2').click(function() {
alert('Handler for .click() called.');
});
});
Might I suggest condensing that code a little, to something closer to:
$('a div[class^="button"]').click(
function(e){
e.stopPropagation(); // prevent the click bubbling to the parent 'a' element
$('.button_active')
.removeClass('button_active')
.addClass('button_normal');
$(this).addClass('button_active').removeClass('button_normal');
});
JS Fiddle demo.
Edited in response to question from the OP:
Just to add, [the Fiddle updated by the OP to include the above code] actually sets "button_hover" as the class instead of "button_active", any idea why that would be?
Yep; that's in response to the specificity of the CSS selectors, I add and remove classes as needed in response events (rather than repeatedly checking for whether or not button_hover is set). As the element ends up with class="button_normal button_hover", and the order of the css (I think) places greater emphasis on the later-declared class, button_hover is maintained. It's late, and I'm a bit tired, but that's sort of (in a nutshell) what's happening.
The following demo incorporates everything (I think) that you need, and, coupled with revised CSS selectors, should do as you want:
$('a div[class^="button"]').hover(
function(){
$(this).addClass('button_hover').click(
function(e){
e.preventDefault();
$('.button_active')
.addClass('button_normal')
.removeClass('button_active');
$(this).addClass('button_active').removeClass('button_hover');
});
},
function(){
$(this).removeClass('button_hover');
});
CSS:
.button_active,
.button_normal.button_active { background: #000; }
.button_normal.button_hover { background: #ff0; }
.button_normal { background: #d89; }
JS Fiddle demo.
References:
attribute-begins-with (^=) selector.
e.stopPropagation().
removeClass().
addClass().

jquery - why do i need live() in this situation?

I have a somewhat odd situation. I understand the premise of the live() and bind() functions, yet in a situation where i believe i dont need them, i seemingly do. I will explain.
I made an autosuggest in jquery. I included autosuggest.js at the top of my page. I then have an input field.
The basis of the JS works around:
$(".autosuggest").keyup(function()
{
}
This works - on keyup, my function executes etc as expected - i dont need to use live() or bind() as the input field is on the page from the get go...
Now.. I have also made a 'star rater' esque script.
I have various elements (which are styled), and on hover they are restyled...
$('.rating li').mouseover(function() {
}
does NOT work, YET
$('.rating li').live('mouseover',function() {
}
DOES.
Why do i need to use 'live' in this situation, when i dont in the case of the autosuggest?
Thanks
The only thing I can imagine that would cause this is a lack of a domready event. This should work:
$(function () {
$('.rating li').mouseover(function() {
}
});
the .ratings li isn't parsed yet when you have .mouseover() not working.
You can wrap it in $(document).ready(function() {...}); or use .live() (which creates the binding for any currently parsed at that point in the script and any elements added in the future).
Did you put $('.rating li').mouseover(function() {
}
in $(document).ready(function() {....} ?
Even if you include a .js file, if the elements in the page ('rating li') are not loaded, the bind will not be made.
Without seeing more of you code, it's difficult to say for sure. But my guess would be that your script is running before the pageload completes. try wrapping your bindings (and anything else that depends on particular dom elements to exist) with a call to $(document).ready(...).
something like this:
$(document).ready( function() {
$('.rating li').mouseover(function() {
// whatever
});
$(".autosuggest").keyup(function() {
// whatever else
});
});
If that's not it, then post more of your code, and we'll dig in further.
good luck.

Categories