Css "hover" selector applys a temporary style to an element, but it isn't definitive:
div:hover {
background-color: red;
}
I can do the same thing with javascript but it is a bit complicate and impossible for several elements:
var elem = document.getElementsByTagName ("div")[0];
elem.onmouseover = function () {
this.style.backgroundColor = "red";
}
elem.onmouseout = function () {
this.style.backgroundColor = "transparent";
}
Is there a better way ? Something like this:
document.getElementsByTagName ("div")[0].ontemporarymouseover = function () { // LoL
this.style.backgroundColor = "red";
}
Thanks
No, there is no way to apply styles that go away by themselves.
Eventhough the CSS contains only one definition, it actually corresponds to the two state changes that triggers onmouseover and onmouseout. When the pointer enters the element, the :hover pseudo class is added to it making the CSS rule apply. When the pointer leaves the element, the :hover pseudo class is removed making the CSS rule no longer apply.
In JavaScript this behaviour can only be handled by listening to the mouseover and mouseout DOM events, as you did in your second example. However it is recommended to handle hovering styles with CSS, as in your first example.
// jQuery 'Temporary mouseevents'
$("element").bind
({
mouseover:
function ()
{
},
mouseout:
function ()
{
}
});
$("element").unbind('mouseover mouseout');
I hope this is a good approach for what you need.
I believe that if you use the jQuery JavaScript framework, you can do this:
$('div:first').hover(function(){
$(this).css('background-color','red');
},function(){
$(this).css('background-color','white');
});
Related
I'm working on a pricing table with some hover.
You can see it right here: http://lhit.nl/lucid/
As you see, when you hover on a pricing table all the divs toggle the classes.
And thats not what I want. I want it to be seprate ofcourse.
My jQuery:
$('.package').hover(function(){
$('.name').toggleClass('name-hover')
$('.price-container').toggleClass('price-hover')
$('.price').toggleClass('white-hover')
$('.month').toggleClass('white-hover')
});
The css is just to overwrite current colors:
.package .price-hover {
background: #008ed6;
}
.package .white-hover {
color: #fff;
}
I already tried to use $(this) but it doesn't work.
$('.package').hover(function(){
$(this).find('.name').toggleClass('name-hover')
$(this).find('.price-container').toggleClass('price-hover')
$(this).find('.price').toggleClass('white-hover')
$(this).find('.month').toggleClass('white-hover')
});
This can be simply achieved just by css. Why to add Js for this ?
package:hover .price-container{
background: #008ed6;
}
You could use each():
$('package').each(function() {
var _this = this;
$(this).hover(function() {
$(_this).find('.name').toggleClass('name-hover')
$(_this).find('.price-container').toggleClass('price-hover')
$(_this).find('.price').toggleClass('white-hover')
$(_this).find('.month').toggleClass('white-hover')
});
})
First you need to use find to only change the classes for elements
inside the currently hovered over .package, otherwise it will
change classes for all these elements.
Secondly, hover event takes
2 functions, one when mouse enters the hover area, second when cursor
exits the hover area. The way you are handling hover event, it toggles the classes twice, once on hover in, once on hover out, so in the end leaving it same as before.
Try this code:
$('.package').hover(function(){
$(this).find('.name').addClass('name-hover');
$(this).find('.price-container').addClass('price-hover');
$(this).find('.price').addClass('white-hover');
$(this).find('.month').addClass('white-hover');
}, function(){
$(this).find('.name').removeClass('name-hover');
$(this).find('.price-container').removeClass('price-hover');
$(this).find('.price').removeClass('white-hover');
$(this).find('.month').removeClass('white-hover');
});
$(".package").hover(function() {
$this = $(this);
$this.find(".name").toggleClass("name-hover");
$this.find(".price-container").toggleClass("price-hover");
$this.find(".price,.month").toggleClass("white-hover");
});
#Spartak Lalaj As of jQuery 1.4 the .hover() may have one parameter. See https://api.jquery.com/hover/
How can I apply something to all elements now and in the future which have a title attribute set?
The reason why I want to achieve this is simple:
I have a footer in a webapp where, like many apps, I'd like to have some information written on hovering some elements.
I'd like to set this information in the title attribute of the elements I want to display information for.
So every element with a title should trigger a function on hover. Even elements that are added dynamically.
I found this to have something work on mouse enter+leave that is suposed to work for added elements:
$(document).on(
{
mouseenter: function()
{
//stuff to do on mouseover
},
mouseleave: function()
{
//stuff to do on mouseleave
}
}
, "*[special-selector]");
what's the special selector supposed to be?
Secondary question: How can I acces the $(this).attr('title') attribute from within the scope of these 2 anonymous functions?
Any Idea? or maybe better solutions? I want too keep the html as simple as possible and avoid using the onmouseover attributes within the elements as there are LOT of them..
Target an element with the attribute selector:
$(document).on(
{
mouseenter: function(e)
{
//stuff to do on mouseover
var domNode = this,
$object = $(domNode),
title = domNode.title;
$object.addClass('hover');
console.log(title);
},
mouseleave: function(e)
{
//stuff to do on mouseleave
var domNode = this,
$object = $(domNode),
title = domNode.title;
$object.removeClass('hover');
console.log(title);
}
}
, "[title]");
(Simple) JS Fiddle demo.
References:
on().
I have a task here that requires heavy DOM manipulation. Because this can have a bad impact on the performance, I clone the element, make the changes there and replace the clone with the original.
After replacement, the elements have a hover function.
Because I want faded transition, I do the change like this:
myElement.fadeOut(500, function(){
myClone.hide();
myElement.replaceWith(myClone);
myClone.fadeIn(500);
});
This is working, but after that the hover functionality does not work anymore. When I remove the callback from fadeOut, I can hover again but the timed transitions does not look good anymore.
What can I do about it? Why do the elements lose their hover-functionality when using the callback?
i have a different solution for you. CSS approach:
You can set one of your element's position;
#myElement { top:100px; left:200px; }
#myElement, #myClone { position:absolute; }
jQuery:
$(document).ready(function() {
var myElement = $('#myElement');
var myClone = $('#myClone');
var myEleTop = parseInt(myElement.css('top'));
var myEleLeft = parseInt(myElement.css('left'));
myClone.hide();
myClone.css({'top':myEleTop+'px','left':myEleLeft+'px'});//sets position here
myElement.mouseenter(function() {
myElement.fadeOut(500, function(){
myClone.fadeIn(500);
}
});
myElement.mouseleave(function() {
myClone.fadeOut(500, function(){
myElement.fadeIn(500);
}
});
});
or you can just use appendTo() and remove() methods, i am not really experienced with these methods but try this:
myElement.mouseenter(function() {
myElement.fadeOut(500, function(){
myElement.remove();
myClone.appendTo($('.container'));
myClone.fadeIn(500);
}
});
myElement.mouseleave(function() {
myClone.fadeOut(500, function(){
myClone.remove();
myElement.appendTo($('.container'));
myElement.fadeIn(500);
}
});
When an object is cloned, the clone will no longer have event listeners attached to it. One way to fix it is to attach the event handlers using "on":
$("my-clone-container").on("hover", "my-clone-selector", myHoverHandler);
This way, whenever you add a clone, it will automagically handle hover events as you want it to. See the docs for 'on'.
I made some sticky notes in javascript for fun.
When there are multiple sticky notes on the screen, I want the one that is selected to be brought forward. IE. raise the z-index to be higher then the other sticky notes.
Currently I am doing this with CSS using :hover, which is kind of annoying. I want to do it in javascript/jquery. I tried to do addClass/removeClass with focus() and blur()
This is what I have so far
$('.darkYellow').click(function() {
$(this).focus(function() {
$(this).addClass("index");
});
});
$('.darkYellow').blur(function() {
$(this).removeClass("index");
});
Updated and Working thanks to Christoph
http://jsfiddle.net/EnigmaMaster/aQMhk/6/
Class selectors start with a . character, class names do not (well, they can, but that way lies madness).
$(this).addClass("index")
for addClass there is no need to include '.'
Simply
$(this).addClass("index");
http://api.jquery.com/addClass/
Though at the moment I don't know, why .on() does not work (this shoud be the preferred method!), the following code should work:
$('.darkYellow').live("click", function() {
$(".index").removeClass("index");
$(this).addClass("index");
});
This is all you need.
live event handler on click ( use of on() should be preferred )
look for index note and remove class
add Class to current "clicked" element
DEMO
You're calling $('.darkYellow').click() before the sticky notes actually exist. .click() will add an event to each element that matches the selector at the time of calling. What you want is something like .live() which will handle all elements, present and future E.g.
$('.darkYellow').live('click', function() {
$(this).focus(function() {
$(this).addClass("index");
});
});
UPDATE
Try:
$('.darkYellow').live('click', function() {
$(this).addClass("index");
});
$('.darkYellow').live('blur', function() {
$(this).removeClass("index");
});
As someone else pointed out, the call to .focus() should be unnecessary.
Here's a toggleFocus() function I recently wrote, it's designed to add a .is-focused class the parentNode on focus/blur events.
CodePen Demo
function toggleFocus(e) {
setTimeout(() => {
e.addEventListener('focus', ({path}) => {
path[2].classList.add("is-focused");
}, true);
e.addEventListener('blur', ({path}) => {
path[2].classList.remove("is-focused");
}, true);
}, 0);
}
const items = document.getElementById('items');
const itemsArray = items.querySelectorAll(".item");
[].forEach.call(itemsArray, (item) => {
toggleFocus(item)
});
I have an onClick event to change style. How to change style back when a user clicks elsewhere of an item?
Both prototype and scriptaculous libraries included.. many of the below answers doesn't work with them... Also ID of an element is UNDEFINED so it can't be used for reference in javascript.
Thanks, Yan
I have not tested this in all browsers, but if you don't want to introduce any new js framework, this solution only use CSS:
<ul>
<li tabindex="1">First</li>
<li tabindex="2">Second</li>
</ul>
The property tabIndex makes the li element focusable. And the css:
li { color: #F00; }
li:focus { color: #0F0 }
This is of course very basic styling, probably want to put it in classes or whatever.
Great question! You can use "event bubbling", which means that instead of the onclick event on your element, you define an event handler on a higher object (say, document or a table), and there you say something like:
if (event.target === myElement) {
changeStyle();
} else {
changeStyleBack();
}
More here (and elsewhere): http://www.southsearepublic.org/tag/Javascript%20Event%20Bubbling/read
When an item is clicked on it, it gains focus. When something else is clicked on it will lose focus, triggering the onblur event. May not work for all elements, but it would work for, say, <input> elements.
You want the onblur event: "The onblur event occurs when an object loses focus".
You can bind an onClick event on the body and assign the function that restore the style to that event.
There's a live example at http://jsbin.com/oxobi3
I would use jQuery live event and bind click event using :not selector
Maybe try onclick="function1()" onblur="function2()" or onfocus="function1()" onblur="function2()" in the tag.
Here's how you could do it in jQuery:
$(document).click(function(e) {
if ($(e.target).is("#specialItem")) {
$(e.target).addClass("specialClass");
} else {
$(#specialItem").removeClass("specialClass");
}
});
If you're not using jQuery, you can still use the basic model -- apply the onclick event logic at the document level. This will work for items that don't respond to the blur event.
It's been quite a long time since I've used prototype but I hope this helps you (in the non-jQuery sense.)
$(window).observe('click', respondToClick);
function respondToClick(event) {
var element = event.element();
if(!($(this) == element)){
element.addClassName('active');//or do your stuff here
}
}
My approach
var elsewhere = 1;
$(myelement).bind('hoverin',function(){
elsewhere = 0;
});
$(myelement).bind('hoverout',function(){
elsewhere = 1;
});
$('screenarea').click(function(){
if(elsewhere){
change-style-back();
} else{
change-style();
}
});
this will make sure that when you click somewhere on screen and its not on your element, then the style will change back