I have been tying to perform hover operation on dynamically added input fields.
$( "body" ).delegate( "input", "hover", function(event) {
alert("ok");
});
Also tried using but works only for static fields.
$('input').hover(
function(event) {
alert("bring tooltip");
},
function(event) {
if (hasfocus) {
alert("Keep the tooltip");
}
}
);
Need suggestions.Thanks
Firstly, you should be using on().
Secondly, you shouldn't be using a hover event.
Thirdly, delegate to the document, not the body, or preferable just to the closest static parent element.
$(document).on({
mouseenter : function() {
},
mouseleave : function() {
if ( this === document.activeElement ) {
// has focus
}
}
}, 'input');
try this
$("input").on("hover",function(event){
alert("bring tooltip");
});
Related
I'm trying to select a div for a click event but not the inputs within said div. I thought this would do it but it does not work. here is a demo. Thank you
html
<div id = "test"><input></div>
js
$('#test:not(input)').click(function(){
alert();
});
You could check to see if the clicked element is an input element using !$(e.target).is('input')
Updated Example
$('#test').on('click', function (e) {
var $target = $(e.target);
if (!$target.is('input')) {
alert('clicked');
}
});
When you click on the input, the click event bubbles to the div above it.
You can stop this by calling stopPropagation or stopImmediatePropagation on the event object.
http://jsfiddle.net/t66f06oL/1/
$( '#test' ).on( 'click', function() {
alert();
} );
$( '#test' ).on( 'click', 'input', function( e ) {
e.stopImmediatePropagation();
} );
When you click on the input control your click event is actually caught by the parent div. You can fix this by changing your code to this:
$('#test:not(input)').click(function(){
alert();
});
$('#test').find('input').click(function(e){
e.stopPropagation();
});
I have tried sooooo many different methods of this that others have suggested, but I don't understand what i'm doing wrong and really need some help. I have tried using various combinations of hover, mouseenter/mouseleave, on/off, bind/unbind.
Basically, I can get things to unbind, but I can't get them to bind again afterwards.
I put together a jsfiddle with a basic example. If you click the "Hover Off" button, mouseenter is disabled like intended. But then if you click the "Hover On" button after, mouseenter does not enable again.
http://jsfiddle.net/770b5p8q/3/
Here is "hover" functionality:
$('.square').each(function(){
$(this).bind("mouseenter", function(){
$(this).addClass('active');
});
$(this).bind("mouseleave", function(){
$(this).removeClass('active');
});
});
Here is what should enable/disable it:
$('.hover_enabled').click(function(){
$('.square').each(function(){
$(this).bind("mouseenter");
$(this).bind("mouseleave");
});
});
$('.hover_disabled').click(function(){
$('.square').each(function(){
$(this).unbind("mouseenter");
$(this).unbind("mouseleave");
});
});
You should pass the function for binding and unbinding the handlers, something like:
var mouseEnterHandler = function () {
$(this).addClass('active');
}
var mouseLeaveHandler = function () {
$(this).removeClass('active');
};
$('.square').bind("mouseenter", mouseEnterHandler)
.bind("mouseleave", mouseLeaveHandler);
$('.hover_enabled').click(function () {
$(this).addClass('active');
$('.hover_disabled').removeClass('active');
// I need to bind hover here
$('.square').bind("mouseenter", mouseEnterHandler)
.bind("mouseleave", mouseLeaveHandler);
});
But the code becomes ugly and unmaintainable. You can use event delegation instead:
$(document).on('mouseenter mouseleave', '.square.hoverable', function(event) {
// toggle the class by checking the type of the event
$(this).toggleClass('active', event.type === 'mouseenter');
});
// caching the state changers
var $e = $('.hover_enabled, .hover_disabled').click(function () {
var $this = $(this).addClass('active'),
isHoverable = $this.hasClass('hover_enabled');
// exclude the clicked element from the set and remove the class
$e.not($this).removeClass('active');
$('.square').toggleClass('hoverable', isHoverable);
});
The above mouseenter mouseleave handler is only executed when the .square element has hoverable className. You can also remove the event handler and use CSS for styling.
.square.hoverable:hover {
}
http://jsfiddle.net/bztec1f4/
Once you rebind it back you need to pass function as well.
$('.hover_enabled').click(function(){
$('.square').each(function(){
$(this).bind("mouseenter", function(){
$(this).addClass('active');
});
$(this).bind("mouseleave", function(){
$(this).removeClass('active');
});
});
});
I have a draggable <div> with a click event and without any event for drag,
but after I drag <div> the click event is apply to <div>.
How can prevent of click event after drag?
$(function(){
$('div').bind('click', function(){
$(this).toggleClass('orange');
});
$('div').draggable();
});
http://jsfiddle.net/prince4prodigy/aG72R/
FIRST attach the draggable event, THEN the click event:
$(function(){
$('div').draggable();
$('div').click(function(){
$(this).toggleClass('orange');
});
});
Try it here:
http://jsfiddle.net/aG72R/55/
With an ES6 class (No jQuery)
To achieve this in javascript without the help of jQuery you can add and remove an event handler.
First create functions that will be added and removed form event listeners
flagged () {
this.isScrolled = true;
}
and this to stop all events on an event
preventClick (event) {
event.preventDefault();
event.stopImmediatePropagation();
}
Then add the flag when the mousedown and mousemove events are triggered one after the other.
element.addEventListener('mousedown', () => {
element.addEventListener('mousemove', flagged);
});
Remember to remove this on a mouse up so we don't get a huge stack of events repeated on this element.
element.addEventListener('mouseup', () => {
element.removeEventListener('mousemove', flagged);
});
Finally inside the mouseup event on our element we can use the flag logic to add and remove the click.
element.addEventListener('mouseup', (e) => {
if (this.isScrolled) {
e.target.addEventListener('click', preventClick);
} else {
e.target.removeEventListener('click', preventClick);
}
this.isScrolled = false;
element.removeEventListener('mousemove', flagged);
});
In the above example above I am targeting the real target that is clicked, so if this were a slider I would be targeting the image and not the main gallery element. to target the main element just change the add/remove event listeners like this.
element.addEventListener('mouseup', (e) => {
if (this.isScrolled) {
element.addEventListener('click', preventClick);
} else {
element.removeEventListener('click', preventClick);
}
this.isScrolled = false;
element.removeEventListener('mousemove', flagged);
});
Conclusion
By setting anonymous functions to const we don't have to bind them. Also this way they kind of have a "handle" allowing s to remove the specific function from the event instead of the entire set of functions on the event.
I made a solution with data and setTimeout. Maybe better than helper classes.
<div id="dragbox"></div>
and
$(function(){
$('#dragbox').bind('click', function(){
if($(this).data('dragging')) return;
$(this).toggleClass('orange');
});
$('#dragbox').draggable({
start: function(event, ui){
$(this).data('dragging', true);
},
stop: function(event, ui){
setTimeout(function(){
$(event.target).data('dragging', false);
}, 1);
}
});
});
Check the fiddle.
This should work:
$(function(){
$('div').draggable({
start: function(event, ui) {
$(this).addClass('noclick');
}
});
$('div').click(function(event) {
if ($(this).hasClass('noclick')) {
$(this).removeClass('noclick');
}
else {
$(this).toggleClass('orange');
}
});
});
DEMO
You can do it without jQuery UI draggable. Just using common 'click' and 'dragstart' events:
$('div').on('dragstart', function (e) {
e.preventDefault();
$(this).data('dragging', true);
}).on('click', function (e) {
if ($(this).data('dragging')) {
e.preventDefault();
$(this).data('dragging', false);
}
});
You can just check for jQuery UI's ui-draggable-dragging class on the draggable. If it's there, don't continue the click event, else, do. jQuery UI handles the setting and removal of this class, so you don't have to. :)
Code:
$(function(){
$('div').bind('click', function(){
if( $(this).hasClass('ui-draggable-dragging') ) { return false; }
$(this).toggleClass('orange');
});
$('div').draggable();
});
With React
This code is for React users, checked the draggedRef when mouse up.
I didn`t use click event. The click event checked by the mouse up event.
const draggedRef = useRef(false);
...
<button
type="button"
onMouseDown={() => (draggedRef.current = false)}
onMouseMove={() => (draggedRef.current = true)}
onMouseUp={() => {
if (draggedRef.current) return;
setLayerOpened(!layerOpened);
}}
>
BTN
</button>
I had the same problem (tho with p5.js) and I solved it by having a global lastDraggedAt variable, which was updated when the drag event ran. In the click event, I just checked if the last drag was less than 0.1 seconds ago.
function mouseDragged() {
// other code
lastDraggedAt = Date.now();
}
function mouseClicked() {
if (Date.now() - lastDraggedAt < 100)
return; // its just firing due to a drag so ignore
// other code
}
When I user either jQuery's .hover() or Javascript's mouseenter(), the event triggers not only when the mouse enters the element, but also when the mouse crosses any element within that element. How can I stop this so that it only triggers when the mouse enters or exits that element, with the elements children having no effect on the event?
$(document).ready(function(){
introAnimation();
$('#nav-item1').hover(function() {
$('#createSub').slideDown(300);
});
$('#nav-item1').mouseout(function() {
$('#createSub').slideUp(300);
});
$('#nav-item2').hover(function() {
$('#manageSub').slideDown(300);
});
$('#nav-item2').mouseout(function() {
$('#manageSub').slideUp(300);
});
$('#nav-item3').hover(function() {
$('#storeSub').slideDown(300);
});
$('#nav-item3').mouseout(function() {
$('#storeSub').slideUp(300);
});
});
Hover has a method for unhovering. No need for the mouseout event, which gets fired when you mouse over a nested child element:
$(document).ready(function(){
introAnimation();
$('#nav-item1').hover(function() {
$('#createSub').slideDown(300);
},function() {
$('#createSub').slideUp(300);
});
$('#nav-item2').hover(function() {
$('#manageSub').slideDown(300);
},function() {
$('#manageSub').slideUp(300);
});
$('#nav-item3').hover(function() {
$('#storeSub').slideDown(300);
},function() {
$('#storeSub').slideUp(300);
});
});
add this within the handler:
if( ev.target !== this ){ return; }
ev.target is what the mouse event triggers on. this is what you bound the event to
I would like an event to fire whenever something other than a DOM element is clicked, and a separate event when an image is clicked.
Right now I have:
$( document ).click( function() { /*do whatev*/ } );
and in another place:
$( "img" ).click( function( e ) {
e.stopPropagation();
/*do whatev*/
} );
it does not work. both events are fired. any other ideas?
Simple and concise:
jQuery(document).click(function(event) {
if (jQuery(event.target).is('img'))
{
alert('img');
}
else
{
// Reject event
return false;
}
});
If the user clicks on an img element 'img' is alerted, otherwise the click event is stopped.
something like this:
$('*').click(function(ev) {
ev.stopPropagation();
if ($(this).is('img')) alert('img');
else if($(this).is('div')) alert('div');
else alert('something else');
});
http://www.jsfiddle.net/U2Szn/ ?
This should work, but just img isn't enough. It could be triggering from the img container. I think you'd need a selector like $('p,div,img,a,input,textarea,span,ul,ol,dl,li,dd,dt,table,tr,td') and any other tag you can think of to pull it off. This might have performance issues.
If you want an event to fire when the html and/or body is clicked or an img is clicked something like this should work: Live Example
$(document).click(function(e) {
if($(e.target).is('html')){
alert('this is the html element');
}else if($(e.target).is('body')){
alert('this is the body element');
}
});
$("img").click(function(e) {
e.stopPropagation();
alert('img')
});