Identify event that triggered the function - javascript

How can I get the event that triggered a function using jQuery?
$(document).on("click touchstart", "#element", function() {
if( EVENT IS TOUCHSTART ) {
// DO THIS SINCE EVENT WAS TOUCHSTART
}
});

Also you can specify event and handler as object in on() method
$(document).on({
"touchstart": function() {
// DO THIS SINCE EVENT WAS TOUCHSTART
},
"click": function() {
// DO THIS SINCE EVENT WAS CLICK
}
}, "#element");

There is type property for events
$(document).on("click touchstart", "#element", function(event) {
if(event.type == "touchstart") {
// DO THIS SINCE EVENT WAS TOUCHSTART
}
});

Related

How to stopPropagation of touch event on overlay GoogleMap

You can find out code here. I tried with global & local event both
event.preventDefault()
event.stopPropagation()
event.returnValue = false
event.cancelBubble = true;
above code working fine for mouse click events but for touch event map still receives click events.
You can add a listener to touchend event, so you can stop the propagation of this event:
google.maps.event.addDomListener(div, "click", function(e) {
console.log("over click");
e.preventDefault();
e.stopPropagation();
clickOverlay();
})
google.maps.event.addDomListener(div, "touchend", function(e) {
console.log("over touchend");
e.preventDefault();
e.stopPropagation();
clickOverlay();
})
Here is your fiddle updated: https://jsfiddle.net/beaver71/xx1ycd7L/

Creating an event that triggers a second event

I'm trying to create a jQuery event that triggers a second event. The first event is clicking on the emoji id which refers to an image. The second is a mousemove event which moves the image around the page. The third event stops this event when the mouse click happens again anywhere in the body of the page and places the image at that absolute position. I was able to get the second and the third events to work but I can't get the first event to work with the second. Here is what I have so far for my jQuery:
var mouseTracker = function(event) {
console.log(event.pageX, event.pageY, !!event.which)
$('#emoji').css('top', event.pageY);
$('#emoji').css('bottom', event.pageY);
$('#emoji').css('left', event.pageX);
$('#emoji').css('right', event.pageX);
}
var begin = function() {
$('body').on('mousemove', mouseTracker);
$('body').css('cursor', 'none');
}
var stop = function() {
$('body').off('mousemove', mouseTracker);
$('#emoji').css('postion', 'absolute')
$('body').css('cursor', 'default');
}
$('#emoji').on('click', begin);
$('body').on('click', stop);`
Initialize the event from within the first event call.
$('#emoji').on('click', function() {
begin();
$('body').on('click', stop);
});
During the click on #emoji the body click even is also triggered.
That leads to calling stop(). The propagation of that event to body can be blocked by event.stopPropagation() (or equivalent return false from begin()). The propagation should be manually stopped even if body on click handler is attached in begin().
You may want one-time usage of some events. That can be done by binding using .one(). In that case the handler is detached after the first usage without manual .off():
var begin = function (event) {
$('body').on('mousemove', mouseTracker);
$('body').one('click', stop);
$('body').css('cursor', 'none');
return false; // event.stopPropagation();
}
var stop = function () {
$('#emoji').one('click', begin);
$('body').off('mousemove', mouseTracker);
$('#emoji').css('postion', 'absolute')
$('body').css('cursor', 'default');
}
$('#emoji').one('click', begin);

jquery transitionend function kiks in every time I repeat my click

How To prevent openContent(); to kick the $("#load-content").on("transitionend each time I click .show-content ???
I'm not sure how to stop this transitionend to be kicked! Please heeeelp
$('.show-content').on('click', function (e) {
e.preventDefault();
openContent();
});
$('#load-content').on('click','.prev',function (e){
e.preventDefault();
closeContent(this);
});
function openContent(){
$('#load-content').load('../views/product-page.html');
$('.container').addClass('loaded');
$("#load-content").on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () {
$(this).addClass('animate');
var body = $("body,html");
body.animate({
scrollTop: 0
}, 800);
});
}
function closeContent(ele){
var Loaded = !$(ele).closest('.container').hasClass('loaded');
if (!Loaded) {
$('.animate').removeClass('animate');
$("#load-content").on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () {
$('.loaded').removeClass('loaded');
$('#show-content').remove();
});
}
}
generally you should namespace the event and the off the event after being fired
$el.on('transitionend.mynamespace' function(){
$el.off('transitionend.mynamespace')
});
Example:
$dropdown.on('transitionend.fadein' function() {
// some function to be called on transitionend
doSomething();
// event will not be called again
$dropdown.off('transitionend.fadein')
});
UPDATE
adapted to your code
(you are also using way too many transitionend hendlers)
I created a namespace with e subnamespace
so now you can say
.off('transitionend.loadcontent ')
.off('transitionend.loadcontent.open ')
.off('transitionend.loadcontent.close ')
Try which one will do what you need
You should generallly read this: http://api.jquery.com/event.namespace/
Also the code doesn't look too amazing.
You should consider a more consequent codingstyle and cache selectors to improve readability and performance. E.g. I replaced all " with ' since you were using mixed quotes.
Maybe run jsHint in your editor and cache all elements that are needed more than once.
But that's not really important for this thing to work.
$('.show-content').on('click', function(e) {
e.preventDefault();
openContent();
});
$('#load-content').on('click', '.prev', function(e) {
e.preventDefault();
closeContent(this);
});
function openContent() {
$('#load-content').load('../views/product-page.html');
$('.container').addClass('loaded');
$('#load-content').on('transitionend.loadcontent.open webkitTransitionEnd.loadcontent.open', function() {
$(this).addClass('animate');
var body = $('body,html');
body.animate({
scrollTop: 0
}, 800);
$('#load-content').off('transitionend.loadcontent.open webkitTransitionEnd.loadcontent.open');
});
}
function closeContent(ele) {
var Loaded = !$(ele).closest('.container').hasClass('loaded');
if (!Loaded) {
$('.animate').removeClass('animate');
$('#load-content').on('transitionend.loadcontent.close webkitTransitionEnd.loadcontent.close', function() {
$('.loaded').removeClass('loaded');
$('#show-content').remove();
});
$('#load-content').off('transitionend.loadcontent.close webkitTransitionEnd.loadcontent.close');
}
}
you might need
$ele.one('click',function(){...})
which allows you to bind the event only one time. after being fired, this event listener will unbind itself. check document here:https://api.jquery.com/one/

Prevent click event after drag in jQuery

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
}

Javascript hover issues

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

Categories