New class keeps old class behaviour - javascript

I'm taking by first babysteps in jQuery and stumbled upon a problem I can't seem to get around.
I couldn't find an article that quite described what my problem was, so I would like to try to get an answer this way.
I don't understand why my objects keep behaving like their former class.
When I setup a hover action for a class, and change the class of the object by clicking, jQuery keeps doing the animation for the new class.
I used toggleClass() and removeClass/ addClasswithout any result:
https://jsfiddle.net/biest9160/f0na6sro/
var wide = function() {
$(this).animate({ 'width': '120px' }, 200);
}
var normal = function() {
$(this).animate({ 'width': '100px' }, 200);
}
$(document).ready(function() {
$('.class1').hover(wide, normal);
$('.class1').click(function() {
$(this).toggleClass('class1 class2');
})
})
div {
width: 100px;
height: 100px;
border: 1px solid #000;
margin: auto;
}
.class2 {
background: #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box1" class="class1">box1</div>
<div id="box1" class="class1">box2</div>
<div id="box1" class="class1">box3</div>
<div id="box1" class="class1">box4</div>
I don't understand why the the hover action is triggered while the object has a new class.

Initialy you attach the event to the element with the class name. After the class is changed the event remains on the element.
To remove the event you can use .unbind. To remove .hover event you can check this answer.
A working example using .unbind to remove the event and after to reattach it will look like in the snippet (basically is toggle hover event):
var wide = function(){
$(this).animate({'width':'120px'},200);
}
var normal = function(){
$(this).animate({'width' : '100px'},200);
}
$(document).ready(function(){
$('.class1').hover(wide,normal);
$('.class1').click(function(event){
var $this = $(this);
$this.unbind('mouseenter mouseleave'); // remove hover
if( $this.hasClass('class2'))
{
$this.hover(wide, normal); // reattach hover
}
$this.toggleClass('class1 class2');
})
})
div{
width:100px;
height:100px;
border: 1px solid #000;
margin: auto;
}
.class2{
background: #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box1" class="class1">box1</div>
<div id="box1" class="class1">box2</div>
<div id="box1" class="class1">box3</div>
<div id="box1" class="class1">box4</div>

Use .on() menthod to bind the event which will actually bind the event on the parent of the class.
Here is the example:
$(document).on("click", '.class1', function(){
$(this).toggleClass('class1 class2');
});
This will defiantly work...

Related

Add a class on hover remove class on second hover

I want to add a class on hover but not remove it when mouse leaves. Instead it must be removed on the second mouse hover. So on mouse hover add class. Mouse leaves class remains. Mouse hovers again class is removed.
This code adds the class but if the mouse leaves the class is removed which is not what I'm trying to achieve.
jQuery('.menuButton').hover(function(){
jQuery('.mainMenuDrop').addClass('show')
}, function() {
jQuery('.mainMenuDrop').removeClass('show')
});
To achieve your requirement of add on first entry and remove on second entry, you can change your existing code:
jQuery('.menuButton').hover(function(){
jQuery('.mainMenuDrop').addClass('show')
}, function() {
jQuery('.mainMenuDrop').removeClass('show')
});
to use .toggleClass
jQuery('.menuButton').hover(function(){
jQuery('.mainMenuDrop').toggleClass('show')
}, function() {
// nothing here
});
As jquery .hover binding is just syntax for mouseenter and mouseleave and you don't need mouseleave, this can be simplified to:
jQuery('.menuButton').on("mouseenter", function() {
jQuery('.mainMenuDrop').toggleClass('show');
});
div { border: 1px solid black; padding: 20px; width: 100px; }
.show { background-color: pink; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='menuButton'>point at me</div>
<div class='mainMenuDrop'>changes here</div>

How can I prevent parent element event execution from code inside children event

My question in the title probably looks vague. And I sketched an example for the question:
container.onclick = () => {
alert(0);
};
content.onclick = () => {
alert("how can I prevent here appearance alert(0) from parent element event?");
//how can I prevent parent event by content clicked?
};
#container{
height: 100px;
background-color: gray;
}
#content{
height: 50px;
width: 150px;
background-color: green;
}
<div id="container">
<div id="content"></div>
</div>k
This is a simple example. In a real project, I can't combine these two events into one, because the first one is programmatically assigned somewhere in the bowels of my framework and it shouldn't be removed from the EventListener after clicking on content
In General, is it possible to somehow interrupt the execution of the call chain event by clicking in the DOM layers? I tried to do this:
content.onclick = () => {
alert("how can I prevent here appearance alert(0) from parent element event?");
e.preventDefault();
return false;
//how can I prevent parent event by content clicked?
};
But this, of course, was not successful
You should pass the event by dependency injection to the specific method (content.onclick) and then stop the propagation of it.
container.onclick = () => {
alert(0);
};
content.onclick = (e) => {
e.stopPropagation();
alert("VoilĂ , this prevent that appears alert(0) from parent element event.");
};
#container{
height: 100px;
background-color: gray;
}
#content{
height: 50px;
width: 150px;
background-color: green;
}
<div id="container">
<div id="content"></div>
</div>
For this, you can use stop propogation of js like this
<div id="container">
<div id="content" onclick="event.stopPropagation();">
</div>
</div>
So when you click on content it will not trigger container event only.

Adding and removing classes on mouse enter and leave on canvas shape

I'm trying to add a class to a element when mouse hovers over it and then remove it when mouse leaves. It works currently only with giving it direct style in js.
As shown below I tried various ways to do this, all had some problems. Only the direct style change worked. On mouse leave I do the same but remove the class. The mouse over and leave checks canvas element.
poly.on('mouseover', function () {
this.opacity(1);
layer.draw();
$('.' + this.name()).css({ backgroundColor: "#ffcc00" });
//$('.' + this.name()).classList.add("textboxhighlight");
//$('.' + this.name()).className += " textboxhighlight";
//$('.' + this.name()).addClass("textboxhighlight");
//$('.' + this.name()).setAttribute("class", "textboxhighlight");
});
I'm not sure what the problem is as I tired various methods in adding class all of them with different problems. Using just this.addClass wont work as it needs to start with $('.' + this.name()) or nothing works in the code not even forcing the style part. $('.' + this.name()) refers to a class name in element with the same name as poly.
In css:
.textboxhighlight {
background-color: #ffcc00;
}
Thanks for any help.
May be you have to use in your css class background-color: #red !important. See working example here
It would be easier if you provided more code to work with. The example below will illustrate on how to add a class on hover and remove a class on leaving the element.
$('#element').hover(function(e) {
$(this).addClass('selected');
}, function(a) {
$(this).removeClass('selected');
});
.selected {
background-color: green;
}
<div id='element'>
element
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Hard to say what is wrong with your code when you don't show the mouseenter/leave parts of your code. But here is an example with classes:
https://codepen.io/andeersg/pen/MOGqPQ
$('.el').mouseenter(function() {
$(this).addClass('el-hover');
});
$('.el').mouseleave(function() {
$(this).removeClass('el-hover');
});
You can use toggleClass on hover event
$(".hoverclass").hover(function () {
$(this).toggleClass("hoverclass_toggle");
});
.hoverclass {
height: 72px;
width: 100%;
border: 1px solid #000;
}
.hoverclass_toggle {
background-color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hoverclass">
<div class="item">
<div id="item1"> <i class="icon"></i>Test</div>
</div>
<div>
Otherwise you can do that type :
$(".hoverclass").hover(
function () {
$(this).addClass("result_hover");
},
function () {
$(this).removeClass("result_hover");
}
);
.hoverclass {
height: 72px;
width: 100%;
border: 1px solid #000;
}
.result_hover {
background-color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hoverclass">
<div class="item">
<div id="item1">
<i class="icon"></i>Test
</div>
</div>
<div>

Mouseout and click

When a user mouses over a div it should change to the color red, when they mouse out it should change back to transparent. When they click on the div, it should change to color red.
For some reason, the mouse out event listener is conflicting with the click event listener. Can someone help? When I click on the div, it doesn't change to red.
div$.on('mouseover', function () {
$(this).css('background-color', 'red');
});
div$.on('mouseout', function () {
$(this).css('background-color', 'white');
});
div$.on('click', function () {
$(this).css('background-color', 'red');
});
Note, I have to apply a background image dynamically to each element, so using CSS classes to add the background image is out of the question (because I don't know it before hand).
You could set a boolean variable to confirm that the click has occurred and then only run the mouseout code if the variable is false like this:
var is_clicked = false;
div$.on('mouseover', function () {
$(this).css('background-color', 'red');
});
div$.on('mouseout', function () {
if(!is_clicked) {
$(this).css('background-color', 'white');
}
});
div$.on('click', function () {
$(this).css('background-color', 'red');
is_clicked = true;
});
Note: For multiple div elements user multiple is_clicked variables
You can always do a CSS implementation with :hover; just make sure to add a specifying class to each element you would like this effect on.
1. :hover and jQuery
var div$ = $('.redHover'); // name the class whatever you like
div$.on('click', function () {
$(this).css('background-color', 'red');
});
div {
display: inline-block;
}
.redHover {
height: 100px;
width: 100px;
border: 1px solid black;
}
.redHover:hover {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='redHover'></div>
<div class='redHover'></div>
<div class='redHover'></div>
2. :hover and vanilla JS
var els = document.querySelectorAll('.redHover');
for (var i = 0; i < els.length; ++i) {
els[i].addEventListener('click', function() {
this.style.backgroundColor = 'red';
});
}
div {
display: inline-block;
}
.redHover {
height: 100px;
width: 100px;
border: 1px solid black;
}
.redHover:hover {
background: red;
}
<div class='redHover'></div>
<div class='redHover'></div>
<div class='redHover'></div>
Instead use mouseenter insead of mouseover see why.
The best thing you can go with would be the following notes:
To those elements with hover effect add a class like hoverable.
Hover effect is only applied to those elements having this class.
HTML:
<div class="hoverable"></div>
CSS:
.hoverable:hover{
background-color: red
}
JavaScript:
div$.on('click', function () {
$(this).css('background-color', 'red');
});
In this way, you can simply decide whether an element should be hover-able or not by adding or removing hoverable class. Also hover effect is applied in CSS level not JavaScript, which is more acceptable.
As far as I understand you really want to change picture in the div, not just background color which is relatively easy. Try this:
<div class="hoverable">
<img src="myImg.jpg" />
</div>
//css
.hoverable img{visibility:hidden;}
.hoverable:hover img{visibility:visible;}
.clicked img{visibility:visible!important;}
//JS
$('.hoverable').click(function(){
$(this).addClass('clicked');
});

.on('hover') won't work on appended elements

I'm appending some text onto a div using a button, and want something to happen when you hover over it (after it's been appended). I tried using .on('hover' '.class') but so far haven't been able to get it to work. Any help would be appreciated.
Here's an example of what I'm talking about (I want something to happen when you hover YOU CLICKED ME!).
var text = "YOU CLICKED ME"
$(".button").click(function () {
$(".receiver").append('<a class="appendage">'+text+'</a>');
});
$('.receiver').on('hover', '.appendage', function(){
$(".tooltip").append('<a class="tooltip">'+text+'</a>');
});
.receiver {
height:300px;
border: 1px solid black;
}
.tooltip {
height:300px;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='button'>CLICK ME</div>
<div class='receiver'></div>
<div class='tooltip'></div>
The 'hover' pseudo-event is obsolete and removed since jQuery 1.9. Use 'mouseenter mouseleave' instead, or just 'mouseenter' as may be preferable.
Excerpt from jQuery.on documentation:
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.
Working Example:
var text = "YOU CLICKED ME"
$(".button").click(function () {
$(".receiver").append('<a class="appendage">'+text+'</a>');
});
$('.receiver').on('mouseenter mouseleave', '.appendage', function(){
$(".tooltip").append('<a class="tooltip">'+text+'</a>');
});
.receiver {
height:300px;
border: 1px solid black;
}
.tooltip {
height:300px;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='button'>CLICK ME</div>
<div class='receiver'></div>
<div class='tooltip'></div>
Use mouseover or mouseenter instead of hover. .on('hover') was deprecated in jQuery 1.8, and removed in 1.9.
$('.receiver').on('mouseover', ...
http://api.jquery.com/on/
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.
var text = "YOU CLICKED ME"
$(".button").click(function () {
$(".receiver").append('<a class="appendage">'+text+'</a>');
});
$('.receiver').on('mouseenter','.appendage', function(){
$(".tooltip").append('<a class="tooltip">'+text+'</a>');
});
.receiver {
height:300px;
border: 1px solid black;
}
.tooltip {
height:300px;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='button'>CLICK ME</div>
<div class='receiver'></div>
<div class='tooltip'></div>

Categories