I'm trying to skip a delay event in JavaScript. Say( If I mouse wheel for 4 times continuously the first one ill get fired followed by the second, third and fourth one. In my scenario if the first event fired and when the second/third/fourth events are in delay or slow I want to speak the second and third event getting fired and must directly fire the final event (say fourth event))
Is this possible using JS/Jquery! And can anyone suggest me some sample for it if possible!
Sorry if I don’t make much sense, I am a beginner here.
It sounds like you're describing a debounce function, which will fire on the first event but merge subsequent events within a defined timeframe.
This plugin should achieve what you're looking for: http://benalman.com/projects/jquery-throttle-debounce-plugin/
This question and answer may also be helpful.
Based on the autocomplete example on this page, http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/, the final (4th in your example) event should be fired, but any intermediate events that happen in quick succession will be skipped.
Here is a Stackblitz example, debouncing a mousewheel event to every 0.1s. You simply need to include the plugin and then do:
$(document).ready(function () {
$('body').bind('mousewheel', $.debounce(100, debounceEvent));
function debounceEvent(event) {
// Process mouse wheel event here
console.log(event);
}
});
If you do a quick scroll, only the last event should be emitted.
Related
Im confuse on how the event methods/functions related to each other when they are use at the same time.
For Example:
$("#searchInput").blur(function(e) {
var isClicked = false;
$("#sresult").click(function(e) {
isClicked = true;
});
if(isClicked) {
$("#sresult").show(150);
} else {
$("#sresult").hide(150);
}
});
The code above shows when I blur on the #searchInput, it will either show #sresult when you click it or hide it when when you did'nt click it.
But there is something wrong in my code that I don't know why it keeps hiding even if I clicked the #sresult.
Is it that maybe when you click the #sresult, the $("#searchInput").blur(function(e) is fast enough that he didnt want to wait in $("#sresult").click(function(e) to function? are event methods are waiting for each other? are they synchronize? correct me if im wrong.
Thanks in advance.
The Problem
It's important to understand what .blur() and .click() functions really do. They attach event listeners to a certain element. (Better use .on() btw)
The Explanation
To your code: blur fires, prepares a variable and attaches another event listener. as the if-else statement is also in the blur callback it's executed immediately and thus not waiting for the click, meaning isClicked will never be true.
Using nested event listeners is almost never a good idea, you just saw why in your own case.
The Solution
Am I right with the assumption you're trying to hide a search results field until the search button is clicked? If yes I could help you with code. Though, the easiest approach might be to simply attach a listener for the button and then .toggle() the results.
This is a bit of an abstract question, but I've been pondering its usefulness, and maybe it's either already been solved or inspires someone to do something based on it.
Well recently I ran across an issue whereby three browser events were fired, all as the result of a single user interaction: click, blur and focus. When the user clicks from one input to another, these events occur; and a similar set occur when the user tabs from one to another.
The trouble I had was that they fired in this order: blur, focus, click. It meant that, if the blur event caused DOM changes, the click event could be affected. I really wanted click, blur, focus - but that's not what the browser gave me.
I figured a general utility could be produced, capturing and cancelling browser events, then synchronising them and firing a single handler for all three. Perhaps extending the Event class so that the event could be reinstated.
Is there a more abstract design pattern I can use here? Something that will allow me to set up an arbitrary number of event listeners, and then fire a single event when all are complete? Does it have an implementation already? All advice welcome.
Dont need to break head around this! you can always trigger these events Programmatically
Note: object referenced here is any element selected using javascript selector.
Initially onBlur & onFocus do event.preventDefault which allows onClick to do its job first
var clicked=false;
object.onblur = function(e) {
if (!clicked) {
e.preventDefault
}
};
object.onfocus = function(e) {
if (!clicked) {
e.preventDefault
}
};
inside click event undo the above preventions and trigger the events in the order you wanted
object.onclick=function(){
clicked=true;
//Do anything
object.unbind('blur'); //this do undo prevent default
object.unbind('focus'); //this do undo prevent default
object.blur(); //in order you want
object.focus();
//make sure to put condition if click clicked
};
Thats it ! Hope it helps
I have a problem with queuing up events in jQuery. I have an elevator project that allows the user to click on buttons, and then lights go on and then numbers change. That works fine, except when they punch a number again before it reaches the floor picked the first time. I want it to get to the floor first picked before it goes to the second clicked floor (or third, or fourth, etc.). I've done some stuff with .promise, when done, etc. and none of it seems to work.
I am using .click which appears to be the issue, because it fires the function regardless of where it is currently. Trouble is that I can't seem to find any alternative and it needs to finish current operation first before moving on to any other floors.
I hope I explained this well. If not please let me know. Perhaps there is another way entirely of doing it. Still learning this front end/jQuery stuff.
$( ".button" ).click(function(event) {
// doing stuff here....
$( runMainscript() ).promise().done(function() {
runMainscript(buttonclicked, floorQ);
});
});
function runMainscript(buttonclicked,floorQ) {
//doing stuff here
}
BTW, here is a timer for 2 seconds on each floor.
JSfiddle: http://jsfiddle.net/ak25Lxab/1/
See how if you click on two buttons quickly, it jumps around?
The deferred object works slightly differently. You should explicitly declare a deferred variable like this:
var dfd = new $.Deferred();
And when you want to fire done callback, you should call:
dfd.resolve();
So your queueing part of the script now looks like this:
$.when(dfd.promise()).done(function() {
dfd = new $.Deferred();
var onfloor = $("#onfloor").text();
runMainscript(buttonclicked, floorQ, onfloor);
});
And inside runMainscript you resolve this dfd deferred when elevator arrived to the floor.
See demo. Now, all floors are in the queue using deferred object.
I'm not an expert in deferreds, so maybe you can optimise this script further.
I don't really understand your problem and your jsfiddle is not working for me but as far as I can see you want to stop listen for the click event when the elevator is moving.
To do this you can stop listening for the click event and then restore the listener.
http://api.jquery.com/off/
So ideally, listen for the click event, as soon as it's fired stop listening for the click event, do your operations and then restore the listener on the click event for the .button
Or you can try to do something like this, put a state and do nothing if the state is not cleared:
jQuery - How can I temporarily disable the onclick event listener after the event has been fired?
I need to do some operations when the map is paned or zoomed, so I attached a callback to the event moveend.
map.on('moveend', function() {
// code stuff
});
It works fine, but when the page is load the event is fired three times and I don't know why.
Probably because during its creation the map is moved.
To avoid this i tried to wait the load event before subscribing moveend event, but nothing changed. So I tried to attach it within whenReady callaback, but again it is fired three times.
map.whenReady(function() {
map.on('moveend', function() {
// code stuff
});
});
Finally, I discovered that after the resize event it works quite fine: moveend is fired jonly one time. But I really believe there is a best way to fix the problem.
Another solution could be to attach my callback to both events zoomend and dragend, to cover paning and zooming cases.
But I didn't find a way to do it.
Thank you for your help.
The best solution I found is to attach the callback to both events:
map.on('zoomend', function() {
// callback
});
map.on('dragend', function() {
// callback
});
Although this way the code is a bit replicated, this is by far the best solution.
For others looking into this, research the options.debounceMoveend option on the invalidateSize function. It's mentioned in briefly in the documentation, but unfortunately it looks like it's only for that function, rather than generally for the moveend event.
[...] If options.debounceMoveend is true, it will delay moveend event so that it doesn't happen often even if the method is called many times in a row.
Reference to the line in source code (L3541)
You can use mouseenter and mouseleave events.
Example:
block.addEventListener('mouseenter', ()=>{
//some code when hover
})
block.addEventListener('mouseleave', ()=>{
// some code when leaving block
})
link to developer.mozilla.org
The 'zoomend' and 'dragend' option didn't work for me. I searched a lot for a suitable option and realized that the "moveend" event fires several times because this event is created every time you move the map. Therefore it is necessary to stop this event. I got out of the situation in this way.
Immediately after the map was initialized, I wrote:
map.off('moveend');
and for me it worked. Now it works fine.
I will be very happy if this is useful to someone.
Is there any way to know, in a jQuery onmouseup handler, if the event is going to be followed by a click event for the same element?
I have an event handler for a menu hyperlink which unbinds itself when the user either clicks on an element or "drops" (as in drag-n-drop) on an element. I want to avoid prematurely unbinding the handler on mouseup if a click is coming next.
I realize I can track mousedown and mouseup events myself or otherwise hack up a solution (e.g. wait 50 msecs to see if a click comes soon), but I was hoping to avoid rolling my own implementation if there's something built-in for this purpose.
There is nothing built-in because it's really specific to your needs. Thus, there would kilometers of code and documentation to maintain if jQuery would handle any combination of clicks, long clicks, moves, etc.
It's also hard to give you a snippet that satisfies your needs, but a setTimeout is usually the first step to take, with something like that :
obj.mouseup = function (){
obj.click = action; // do action
setTimeout ( function() {
obj.click = functionOrigin // after 500 ms, disable the click interception
}, 500);
};
you can use $(selector).data('events') for that
$('div').mouseup(function(){
if($(this).data('events').click){
console.log('Has a click event handler')
}
});