DOM not updating after jQuery removeClass function - javascript

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).

Related

Usin jquery how to make an element clickable only once?

I have the following code in my JS file:-
var $html = $('<div class="chat self" style="justify-content: flex-end;">' +
'<p class="chat-message" style="cursor: pointer;">' +
'message' +
'</p>' +
'</div>'
);
$html.find('p').click(() => cast_vote(url, option_position, vote_count));
The click function gets called all the times when the element is clicked.
How do i make the element to be clicked only once?
Use jQuery's one() handler. According to the API, "The .one() method is identical to .on(), except that the handler for a given element and event type is unbound after its first invocation."
You're using click() which is shorthand for .on( "click", handler ). Change your code to:
$html.find('p').one('click', () => cast_vote(url, option_position, vote_count));
you could add a class like "disabled" to the element on click, then check if the element has that tag before you run the cast_vote function again.
You can add a class to the element after clicking it, and check each time one of the elements is clicked to see if it has this class.
The example below shows you how you can do this.
Demo
// Add click event to wrapping .message_box
$(".message_box").on("click", ".message", function() {
// Check if the clicked message has the clicked class
// If it doesnt, run script
if (!$(this).hasClass("clicked")) {
// Add clicked class to message
// This means no further click events will run the code below
$(this).addClass("clicked");
console.log("Clicked");
}
});
.message {
padding: 4px;
border: 1px solid grey;
border-radius: 4px;
width: auto;
clear: both;
margin: 4px;
}
.clicked {
border-left-color: blue;
}
.user1 {
float: left;
}
.user2 {
float: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="message_box">
<div class="message user1">
Hello
</div>
<div class="message user2">
Hi!
</div>
<div class="message user1">
How are you?
</div>
<div class="message user2">
Good thanks
</div>
<div class="message user2">
and you?
</div>
</div>

Hover on a link and change the background-image of a div - JQuery

I'm having trouble making a div's background-image change when hovering over a link the code looks fine to me so I'm at a loss here is the code:
Javascript:
$('#hover-01').on('mouseover', function(){
$('#hover-change').css('background-image', 'url("images/1.jpg")');
});
$('#hover-01').on('mouseout', function(){, function(){
$('#hover-change').css('background-image', 'url("images/5.jpg")');
});
HTML:
<div class="open-project-link">
<a id="hover-01" class="open-project"
href="project3.html">Bowman Clay</a>
</div>
<div class="responsive-section-image" id="hover-change"
style="background-image: url(images/5.jpg);">
<div class="overlay"></div>
</div>
jQuery version: v2.1.1
Any idea's or advice?
Edit: the code does work however it was a problem with a 3rd party plugin (I assume) so I fixed it with normal javascript and not jQuery
'mousein' isn't an event handler that you can use. You should use mouseover and mouseout, or mouseenter and mouseleave. See jQuery mouse events here.
You also need to give a width/height to your container that will hold the image, since it has no contents. Also, you have two function() declarations in your mouseout function, I fixed it in the following code sample:
$('#hover-01').on('mouseenter', function(){
$('#hover-change').css('background-image', 'url(http://www.w3schools.com/css/trolltunga.jpg)');
});
$('#hover-01').on('mouseleave', function(){
$('#hover-change').css('background-image', 'url(https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4)');
});
#hover-change {
width:1000px;
height:300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="open-project-link">
<a id="hover-01" class="open-project"
href="project3.html">Bowman Clay</a>
</div>
<div class="responsive-section-image" id="hover-change">
<div class="overlay"></div>
</div>
Use this fiddle:
JS:
$('#hover-01').on('mouseenter', function(){
$('#hover-change').css('background-image', 'url("images/1.jpg")');
});
$('#hover-01').on('mouseout', function(){
$('#hover-change').css('background-image', 'url("images/5.jpg")');
});
You can use jQuery's toggleClass() method to solve your problem like this:
$(document).on('ready', function() {
$('#link').on('mouseover', function() {
//alert('sadasd');
$('body').toggleClass('colored');
});
$('#link').on('mouseleave', function() {
//alert('sadasd');
$('body').toggleClass('colored');
});
});
body.colored {
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<a id="link" href="#">This is a Link</a>
</div>
Hope this helps!
You can use the CSS :hover ~ to change the hover-change div when hover-01 is hovered over as follows:
#divToHover:hover ~ #divToChange {
/*your code here*/
}
#change {
height: 300px;
width: 300px;
background-image: url("//www.google.com/favicon.ico");
}
#hover {
height: 40px;
width: 40px;
background-color: green;
}
#hover:hover ~ #change {
background-image: url(/favicon.ico);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div id="hover">hover</div>
<div id="change"></div>
Try the following code. Make sure to set height and width for the div for which you want the background change.
Issue was with your event name used. Refer here for list of mouse events
$('#hover-01').on('mouseover', function() {
$('#hover-change').css('background-image', 'url("https://placehold.it/350x150/ffff00")');
}).on('mouseout', function() {
$('#hover-change').css('background-image', 'url("https://placehold.it/350x150/ff0000")');
});
.responsive-section-image {
height: 150px;
width: 350px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="open-project-link">
<a id="hover-01" class="open-project" href="project3.html">Bowman Clay</a>
</div>
<div class="responsive-section-image" id="hover-change" style="background-image: url('https://placehold.it/350x150/ff0000')">
<div class="overlay"></div>
</div>

How can I hover multiple elements in order with using jquery?

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);
});
});

How can I access a DOM element with jQuery that I have "moved" around the page?

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.

How should i improve my jQuery click funciton?

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/

Categories

Resources