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

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>

Related

Refer to self with CSS selector when binding dynamic elements with jQuery?

This code is used to bind events to dynamic elements with jQuery.
The #selfID element has body as its parent.
However, body has multiple children besides #selfID.
The goal is to narrow the binding and only bind to mousedown events of #selfID and any of its children with childClass1 and childClass2 as classes. (Siblings of #selfID may also have childClass1 and childClass2 children.)
#selfID is static and not created dynamically.
Thus, the code works for dynamically created childClass1 and childClass2 elements, but it doesn't work for mousedown events on #selfID itself.
Can #selfID refer to itself in the selector statement? Otherwise, it seems like the only other option is to create a separate binding statement just for #selfID?
$("#selfID").on("mousedown", ".childClass1, .childClass2, #selfID", function(event) {
// Do stuff
});
As written in the documentation:
A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.
Since #selfID is static, you can try to use a parent element like below:
$("#selfID").parent().on("mousedown", "#selfID .childClass1,#selfID .childClass2, #selfID", function(event) {
// Do stuff
});
So you do the logic on an upper element where you can add the needed element.
$("#selfID").parent().on("mousedown", "#selfID .someclass, #selfID", function(event) {
$(this).toggleClass('target');
event.stopPropagation()
});
#selfID {
background:red;
width:100px;
height:100px;
}
.someclass {
width:50px;
height:50px;
background:blue;
}
.target {
border:5px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="selfID">
<div class="someclass"></div>
</div>
<div class="someclass"></div>
We can optimize it by adding a condition inside the function to be able to reduce the selector:
$("#selfID").parent().on("mousedown", ".someclass1,.someclass2, #selfID", function(event) {
if($(this).closest('#selfID').length) {
$(this).toggleClass('target');
event.stopPropagation()
}
});
#selfID {
background:red;
width:120px;
height:120px;
}
.someclass1 {
width:50px;
height:50px;
background:blue;
}
.someclass2 {
width:50px;
height:50px;
background:green;
}
.target {
border:5px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="selfID">
<div class="someclass1"></div>
<div class="someclass2"></div>
</div>
<div class="someclass1"></div>
<div class="someclass2"></div>

How to temporarily add an outline to :hover elements

I'm creating a bookmarklet that displays some information on the first element you click on after running the bookmarklet. I would love to have it so the element you are hovering over has an outline, but only before you click. After you have selected an element, the outline would no longer appear when hovering (except if it already did so before my bookmarklet).
To get the clicked element, this works fine for me:
function getClickedElement(e) {
document.removeEventListener("click", getClickedElement);
e.preventDefault();
clickedElement = e.target || e.srcElement;
// Some code that displays information on clickedElement...
}
document.addEventListener("click", getClickedElement);
But I don't know how to do the CSS. It would work like all elements gain this CSS:
:hover {
outline: 1px solid black;
}
while selecting an element, but that stops once an element has been selected. Hope that all made sense.
Small example with the principle explained!
If the user clicks on the element, add a specific class.
CSS Rule adds outline-border only if the element does not match the selector inside the :not pseudo class!
document.addEventListener('click', function(evt) {
var target = evt.target || evt.source;
if(!target.classList.contains('element')) return;
if(target.classList.contains('selected'))
target.classList.remove('selected');
else
target.classList.add('selected');
}, true);
div.element {
width:100px;
height:100px;
background-color:silver;
display:inline-block;
}
.element.selected {
background-color:black;
}
.element:not(.selected):hover {
outline: 1px solid red;
}
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>

New class keeps old class behaviour

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

jQuery mouseenter() is not firing

So I have this simple HTML
<div class="song">
<img src="http://o.scdn.co/300/40e3ec60c92513f724f47ce71baad1e496627107">
</div>
And this simple jQuery
$(".song").on( "mouseenter", function() {
$(this).css( "background-color", "red" );
alert('bla');
});
And the event does not fire.
Although
$(".naujienuKategorija").on( "mouseenter", function() {
$(this).css( "background-color", "red" );
});
Works just fine on
<p class="naujienuKategorija">Apklausa</p>
Which is on the same page.
.song has the following css
.song {
padding-bottom: 12px;
margin-bottom: 15px;
border-bottom: 1px solid #E0E0E0;
overflow: hidden;
}
I am obviously missing something... obvious.
In order for an event to be bound to an element, the element has to be ready and found. A general way to do this is to put your event bindings inside of $(document).ready because it ensures original elements on the page can be accessed. So use this:
$(document).ready(function () {
$(".song").on( "mouseenter", function() {
$(this).css( "background-color", "red" );
alert('bla');
});
});
Another option is to put your event binding on the page at any time after the target elements, either immediately or right before the </body>. For example:
<div class="song"></div>
<div class="song></div>
<script type="text/javascript">
$(".song").on("mouseenter", function () {
});
</script>
It might've been working with the .naujienuKategorija elements because you were using the second method above, but weren't with the .song elements.

change border/color onFocus

I tried to make script which changes color of border-bottom of div after having focus on
<input type="text">
and then changing back to default color after clicking somewhere else.
This is what i tried:
Css:
.div1 {border-bottom:1px solid #ccc;}
Javacript:
function inputFocus(){ $(".div1").css("border-bottom","1px solid #ffba00"); };
Html:
<input type="text" onFocus="inputFocus();">
The first part (changing color on focus) works fine, however after clicking somewhere else (not having focus on input) it doesnt change back to normal style as set in css file.
any idea what im doing wrong?
I'd suggest:
$('input').focus(
function(){
$(this).css('border-bottom','1px solid #000');
}).blur(
function(){
$(this).css('border-bottom','1px solid #ccc');
});​
JS Fiddle demo.
Though if you're amenable to CSS:
input:focus,
input:active {
border-bottom: 1px solid #000;
}
JS Fiddle demo.
$('input').focus(function(){
$(this).css('border-bottom-color','#ffba00');
});
$('input').blur(function(){
$(this).css('border-bottom-color','#ccc');
});
You shold add a function to onBlur event to rollback your change
You have to use onBlur event.
JavaScript:
function inputBlur() {
$(".div1").css("border-bottom","1px solid #ccc");
}
HTML:
<input type="text" class="div1" onFocus="inputFocus();" onBlur="inputBlur();">
However, the better option will be using class toggling.
HTML:
<input type="text" class="myinput">
CSS:
.myinput {
border-bottom:1px solid #ccc;
}
.myinput.active {
border-bottom:1px solid #ffba00;
}
JavaScript:
$(function() {
$(".myinput").on("focus", function() {
$(this).addClass("active");
}).on("blur", function() {
$(this).removeClass("active");
});
});
instead of calling a function in html you can try this:
.border {border-bottom:1px solid #ccc;}
$("input[type='text']").focus(function(){
$(this).addClass("border")
})
$("input[type='text']").blur(function(){
$(this).removeClass("border");
})
this happens because the changed css is not reverted after losing focus from control.
This would help:
<input type="text" onFocus="inputFocus();" onblur="inputBlur();">
function inputFocus(){ $(".div1").removeAttr('style'); };
You shouldn't be using JavaScript to do this. CSS has a :focus selector that is much more appropriate for this.
.div1 {border-bottom:1px solid #ccc;}
.div1:focus {border-bottom:1px solid #ffba00;}

Categories