I want to hover all div under .wrapper div in order with a delay when the page is loaded. How can I do this with using jquery?
HTML
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</div>
Jquery
$('.wrapper').children().each(function(){
$(this).trigger('hover');
});
https://jsfiddle.net/drxvr1hn/
.trigger('hover') has been deprecated as it caused a great deal of maximum stack exceeded errors.
Deprecated in jQuery 1.8, removed in 1.9: The name "hover" used as a shorthand for the string "mouseenter mouseleave". It attaches a single event handler for those two events, and the handler must examine event.type to determine whether the event is mouseenter or mouseleave. Do not confuse the "hover" pseudo-event-name with the .hover() method, which accepts one or two functions.
Trying to trigger the hover state via jQuery is a very browser/cpu intensive process and a lot of re-rendering of a page to ensure that your call is correct. Therefore the ability was removed but is possible with some JS but will almost certainly cause speed issues and/or stack issues which can cause browser crashes.
A good alternative would be to use classes like below:
$(document).ready(function() {
$('.wrapper div').on('mouseover', function() {
$('.wrapper div').addClass('hover');
}).on('mouseleave', function() {
$('.wrapper div').removeClass('hover');
});
});
.wrapper > div {
width: 100%;
height: 20px;
margin-bottom: 20px;
}
.first {
background-color: #468966;
}
.second {
background-color: #FFF0A5;
}
.third {
background-color: #FFB03B;
}
.first.hover {
background-color: #B64926;
}
.second.hover {
background-color: #8E2800;
}
.third.hover {
background-color: #464A66;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</div>
you need to set the timeOut interval
$(window).scroll(function() {
$('. wrapper'). children().each(function(index){
var _this = this;
setTimeout( function(){ $(_this).trigger('hover'); }, 200*index);
});
});
Related
I'm trying to change the opacity of all elements on my document, except for the one I clicked (which has the highest z-Index).
Here is the code I'm using, am I accessing the z-Index's wrongly? When run, the opacity of the whole page changes (including those with a z-Index higher than 6).
allElements = document.getElementsByTagName("*")
for (let i = 0; i < allElements.length; i++) {
if (allElements[i].style.zIndex < 6)
allElements[i].style.opacity='0.7'
}
I would suggest a cleaner and more robust approach based on classes.
Basically use event listeners and toggle classes on your body and your highlightable items. The rest is just CSS as you would imagine.
resetAllHighlights = () => [...document.querySelectorAll('.item')].map(e => e.classList.remove('highlighted'));
toggleHighlightMode = (highlightMode) => {
if (highlightMode) document.querySelector('body').classList.add("highlight-enabled");
else document.querySelector('body').classList.remove("highlight-enabled");
return highlightMode = !highlightMode;
};
[...document.querySelectorAll('.item')].map(e => e.addEventListener('click', (e) => {
resetAllHighlights()
toggleHighlightMode(true)
e.currentTarget.classList.add('highlighted');
}));
.item {
height:100px;
width: 100px;
background-color: red;
margin: 5px;
opacity: 1;
}
body {
display: flex;
}
body.highlight-enabled .item:not(.highlighted) {
opacity: 0.5;
}
<body class="">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</body>
When you access an element's .style property, you will only have access to the styles that were established on the element via the HTML style attribute. If the styling was done via the class attribute or set with JavaScript, the .style property won't be able to access it. In those cases, you must use .getComputedStyle(), which doesn't care how or where the styling was set.
And speaking of how to set styles, it's always better to set styles using pre-made CSS classes and then just add or remove the class(es) as needed instead of setting individual styles. Using classes reduces duplication of code, is easier to manage, and scales better. You can easily access and add, remove or toggle classes with the .classList API.
Also (FYI), don't use .getElementsByTagName() as this is a legacy method that returns a "live node list", which can hurt performance. Instead, use .querySelectorAll()
So, here's an example similar to what you are doing:
let divs = document.querySelectorAll("div.opaque");
// Just set up one event handler at a common ancestor of
// all the elements that may trigger the event
document.addEventListener("click", function(event){
// Check to see if the event was triggered by
// an element you care to handle
if(event.target.classList.contains("opaque")){
// Loop over all the necessary elements
divs.forEach(function(div){
// Check the z-index using .getComputedStyle()
if(getComputedStyle(div).zIndex < 6){
// Instead of modifying a style directly,
// just add a pre-made class
div.classList.add("lightOpaque");
}
});
}
});
body { background-color: red; }
div { height:35px; border:1px dotted grey; position:relative; z-index:5; background-color:skyblue; }
.lightOpaque { opacity: .7; }
.special { position:relative; z-index:7; background-color:aliceblue; }
<div class="opaque">
</div>
<div class="opaque">
</div>
<div class="opaque special">
</div>
<div class="opaque">
</div>
<div class="opaque">
</div>
<div class="opaque">
</div>
I have a page with two areas. There are boxes in each area. If the user clicks on a box in the top area, it gets moved to the bottom and vice versa. This works fine for the first movement. Theoretically, I should be able to move them back and forth between sections as I please.
Box HTML:
<div id="top-area">
<div class="top-box" id="blue-box"></div>
<div class="top-box" id="yellow-box"></div>
<div class="top-box" id="green-box"></div>
</div>
<hr/>
<div id="bottom-area">
<div class="bottom-box" id="red-box"></div>
<div class="bottom-box" id="gray-box"></div>
</div>
I use jQuery.remove() to take it out of the top section and jQuery.append() to add it to the other. However, when I try to move a box back to its original position, the event that I have created to move them doesn't even fire.
jQuery/JavaScript:
$(".top-box").on('click', function ()
{
var item = $(this);
item.remove();
$(this).removeClass("top-box").addClass("bottom-box");
$("#bottom-area").append(item);
});
$(".bottom-box").on('click', function ()
{
var item = $(this);
item.remove();
$(this).removeClass("bottom-box").addClass("top-box");
$("#top-area").append(item);
});
I have verified that the classes I am using as jQuery selectors are getting added/removed properly. I am even using $(document).on() to handle my event. How come my boxes are not triggering the jQuery events after they are moved once?
Please see the Fiddle: http://jsfiddle.net/r6tw9sgL/
Your code attaches the events on the page load to the elements that match the selector right then.
If you attach the listener to #top-area and #bottom-area and then use delegated events to restrict the click events to the boxes, it should work like you expect. See .on: Direct and Delegated Events for more information.
Use the below JavaScript:
$("#top-area").on('click', '.top-box', function ()
{
var item = $(this);
item.remove();
$(this).removeClass("top-box").addClass("bottom-box");
$("#bottom-area").append(item);
});
$("#bottom-area").on('click', '.bottom-box', function ()
{
var item = $(this);
item.remove();
$(this).removeClass("bottom-box").addClass("top-box");
$("#top-area").append(item);
});
Alternatively:
You could also change .on() to .live(), which works for "all elements which match the current selector, now and in the future." (JSFiddle)
JSFiddle
Here's another way you could work it:
function toBottom ()
{
var item = $(this);
item.remove();
item.off('click', toBottom);
item.on('click', toTop);
$(this).removeClass("top-box").addClass("bottom-box");
$("#bottom-area").append(item);
}
function toTop ()
{
var item = $(this);
item.remove();
item.off('click', toTop);
item.on('click', toBottom);
$(this).removeClass("bottom-box").addClass("top-box");
$("#top-area").append(item);
}
$(".top-box").on('click', toBottom);
$(".bottom-box").on('click', toTop);
#top-area, #bottom-area {
height: 100px;
border: 1px solid black;
padding: 10px;
}
.top-box::before {
content: "Top";
}
.bottom-box::before {
content: "Bottom";
}
#blue-box, #red-box, #yellow-box, #green-box, #gray-box {
width: 100px;
cursor: pointer;
float: left;
margin: 0 5px;
text-align: center;
padding: 35px 0;
}
#blue-box {
background-color: blue;
}
#red-box {
background-color: red;
}
#yellow-box {
background-color: yellow;
}
#green-box {
background-color: green;
}
#gray-box {
background-color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top-area">
<div class="top-box" id="blue-box"></div>
<div class="top-box" id="yellow-box"></div>
<div class="top-box" id="green-box"></div>
</div>
<hr/>
<div id="bottom-area">
<div class="bottom-box" id="red-box"></div>
<div class="bottom-box" id="gray-box"></div>
</div>
This basically removes the listener that switched the object to bottom to a listener that switches the object to the top and viceversa.
In the webpage I'm working I have a lot of small images to wich I want to assign the same set of events. Instead of adding them one by one, I thought it would be more elegant if I could make that type of element inherit these events.
What comes to my mind is something like :
function InheritEvents(){};
InheritEvents.prototype.onmouseover = function(){...action a..};
InheritEvents.prototype.onmouseout = function(){...action b..};
var temp = originalHTMLElement.constructor; //(in this case img)
originalHTMLElement.prototype = new InheritEvents();
originalHTMLElement.constructor = temp;
a) Am I not disturbing the originalHTMLElement ?
b) Is it possible to name the custom object property, for example
".onmouseover" like in the classic way:
originalHTMLElement.onmouseover = function()... ?
c) More conceptual: Is it possible to mix your custom objects with HTML
elemenst / DOM nodes ?
I would strongly recommend against this. It probably wouldn't work anyway, but messing with the prototypes of host objects is, in general, a bad idea.
I don't think there should really be a problem with iterating through the target elements and attaching events to them, but if you don't like that, you can use event delegation:
window.onload = function() {
document.getElementById("images").onclick = function(e) {
if (e.target && e.target.classList.contains("clickable")) {
e.stopPropagation();
console.log("I've been clicked!");
}
}
}
#images div {
width: 40px;
height: 40px;
float: left;
margin: 5px;
background-color: blue;
}
#images div.clickable {
background-color: red;
}
#images + * {
clear: both;
}
<div>
<div id="images">
<!-- Pretend that these DIVs are your images -->
<div></div>
<div class="clickable"></div>
<div></div>
<div></div>
<div class="clickable"></div>
</div>
<div>
Click one of the red images above
</div>
</div>
Of course, if you're using jQuery, the .on() method can handle both the "add an event handler to all members of a set" option and the event delegation option in a single line.
I want to assign a .hover event to divs of a certain class that are within parent divs of a certain class only. Then I want a .click event to remove a class from the parent div so that the affected child div no longer responds to the .hover event.
Instead, the class is successfully removed yet the .hover event still fires.
JSFiddle: http://jsfiddle.net/DeNRG/
I think the answer is to do with using .on() but I can't work it out :(
Any help much appreciated as always :)
HTML:
<div class="container unclicked">
<div class="element">
<p class="content">Hello World!</p>
</div>
</div>
CSS:
.container {
background: #444;
padding: 20px;
}
.clicked {
border: 5px #bbb solid;
}
.unclicked {
border: 5px #222 solid;
}
.element {
cursor: pointer;
background: #f2bd2e;
padding 20px;
}
jQuery:
$(".element").click(function() {
$(".container").removeClass("unclicked");
$(".container").addClass("clicked");
});
$(".unclicked .element").hover(function() {
$(".content").css({"color":"#000"});
}, function() {
$(".content").css({"color":"#fff"});
});
And if you are hell bent on doing it in jQuery, here you go:
You need to unbind the event. Demo: Fiddle
$(".element").click(function() {
$(".unclicked .element").unbind("mouseenter mouseleave");
$(".container").removeClass("unclicked");
$(".container").addClass("clicked");
});
You may also do this using jQuery on:
$(".element").click(function() {
$(".unclicked .element").off("mouseenter mouseleave");
$(".container").removeClass("unclicked");
$(".container").addClass("clicked");
});
$(".unclicked .element")
.on("mouseenter", function() {
$(".content").css({"color":"#000"});
})
.on("mouseleave", function() {
$(".content").css({"color":"#fff"});
});
You will need to use CSS to accomplish this:
http://jsfiddle.net/DeNRG/2/
css:
.unclicked .content:hover
{
color: #000;
}
jquery:
$(".element").click(function() {
$(".container").removeClass("unclicked");
$(".container").addClass("clicked");
});
html:
<div class="container unclicked">
<div class="element">
<p class="content">Hello World!</p>
</div>
</div>
as epascarello said, your JQuery is being wired up correctly and does not change as your classes change.
Per your comment, if you truly need to change the hover behavior in jQuery, try to remove the event handler dynamically by unbinding it (as mentioned by LShetty).
So i'm learning some jQuery at the moment and got somewhat stuck with this .click function. I'm trying to "turn a light on and off", so to speak.
I am able to do so, but only once. Why is that, that my code only runs for one click event per item, and how should i improve it?
Link to my JSfiddle.
HTML
<div class="lightOn"></div>
<div class="lightOff"></div>
jQuery
$('.lightOn').click(function() {
$(this).removeClass('lightOn');
$(this).addClass('lightOff');
});
$('.lightOff').click(function() {
$(this).removeClass('lightOff');
$(this).addClass('lightOn');
});
CSS
.lightOn {
height: 90px;
width:90px;
background-color:yellow;
border-radius: 100%;
float:left;
margin:10px;
}
.lightOff {
height: 90px;
width:90px;
background-color:grey;
border-radius: 100%;
float:left;
margin:10px;
}
The issue is because you are removing the class you are selecting by, so for successive clicks the element no longer exists. Instead have a common class which remains, but add one to it to light up the object. Try this:
<div class="light"></div>
<div class="light"></div>
.light.on {
background-color:yellow;
}
.light {
height: 90px;
width:90px;
background-color:grey;
border-radius: 100%;
float:left;
margin:10px;
}
$('.light').click(function() {
$(this).toggleClass('on');
});
Example fiddle
This method has the benefit of being able to handle x number of .light elements wihtout having to amend the jQuery selector you use.
The problem is that you bind the functions to elements, not to selectors. That is to say, you bind a function that removes the class lightOn to the element that had that class originally. That function only ever removes the lightOn class and adds the lightOff class, even if that has already been done once.
There are two ways to fix this. One is with on and event delegation, which allows you to do something akin to binding to a selector. It attaches the handler to a parent element, and makes use of the fact that all ancestor elements are notified of events that originated on their descendents. So the function might be bound to document.body, but only elements that originated on an element matching the .lightOn selector will trigger the handler:
$(document.body).on('click', '.lightOn', function() {
$(this).removeClass('lightOn').addClass('lightOff');
}).on('click', '.lightOff', function() {
$(this).removeClass('lightOff').addClass('lightOn');
});
http://jsfiddle.net/lonesomeday/C6f7u/5/
Better, however, is to make use of jQuery's toggleClass function, which removes classes if the element currently has them and adds them if it doesn't.
$('.lightOn,.lightOff').click(function() {
$(this).toggleClass('lightOn lightOff');
});
http://jsfiddle.net/lonesomeday/C6f7u/2/
What about
$('.lightOn, .lightOff').click(function() {
$(this).toggleClass('lightOn lightOff');
});
Demo: Fiddle
You can try using toogleClass of jquery
http://api.jquery.com/toggleClass/
It's a good practice to attach your events to the parent element. In your case this is even mandatory, because you are changing the classes, which are used during the event binding. So, your HTML:
<div class="ligths">
<div class="lightOn"></div>
<div class="lightOff"></div>
</div>
JS:
$(".ligths").on("click", "div", function(e) {
var el = $(this);
if(el.hasClass("lightOn")) {
el.removeClass("lightOn").addClass("lightOff");
} else {
el.removeClass("lightOff").addClass("lightOn");
}
});
JSFiddle: http://jsfiddle.net/C6f7u/7/