This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Throttle event calls in jQuery
I like the .change() functionality of jQuery, but I'd like to prevent triggering a ton of AJAX requests when a user quickly changes options in a select drop down. As an example, when a user uses a mouse scroll wheel, it will trigger each options as they pick their new option.
I'd like to come up with a good clean way to handle only sending these updates once the user stops updating the select dropdown a second.
Is there a neat way of handling this situation?
The typical way to do this is with a setTimeout and clearTimeout:
var wto;
$('#select').change(function() {
clearTimeout(wto);
wto = setTimeout(function() {
// do stuff when user has been idle for 1 second
}, 1000);
});
I recommend you to use underscore.js then:
var newFunction=_.debounce(function (){
alert('You function, after use stop scroll')
},1000); //Wait seconds after he stops
$('#select').change(newFunction);
Read more about underscore.debounce.
Related
This is a new issue for me and I've been unable to find any information about this.
I have a simple onclick listener that performs a smooth scroll to a target on the page. Here is the code below:
$(".nav-scroll").click(function (event) {
var ID = this.hash;
//has a few extra conditionals here specific to the page
$('html,body').animate({ scrollTop: $(ID).offset().top }, 1000);
});
Ultimately, the scenario is that this function takes time to execute. Not much time, but it does add up if someone spams the link on the page and the browser starts queuing the function calls. Now spamming is an extreme case, but even after 3 or 4 consecutive clicks it hinders the user experience while they can't scroll down the page because the page is trying to scroll them back to the target 3 or 4 times.
All my research has been able to turn up is checking if a window has an event listener already like found here: JavaScript - how to check if event already added or listing all the event listeners on an element like here: jQuery find events handlers registered with an object , but nothing to check to see if something is currently running.
Is it possible to prevent this side effect by dumping all previous listener calls on the page mid execution before executing or by another method? Or is this something that is not offered by JavaScript? If so, is there strategies to get around this like checking to see if the function is already executing?
From the conversation in the comments, it sounds like you want the users to be able to click on the element as fast as they want to, and have it interrupt the existing animation and start a new one, rather than queueing them up and causing it to scroll around the page. You can achieve this by simply using stop:
$(".nav-scroll").click(function (event) {
var ID = this.hash;
//has a few extra conditionals here specific to the page
//call stop to kill old animations
$('html,body').stop().animate({ scrollTop: $(ID).offset().top }, 1000);
});
A debouncing approach would prevent them from clicking at all until the animation ends, rather than allowing them to click one element, realise they've clicked in slightly the wrong place and quickly click the right element.
You need this:
var debounce = false;
$(".nav-scroll").click(function (event) {
if (debounce) return;
debounce = true;
var ID = this.hash;
//has a few extra conditionals here specific to the page
$('html,body').animate({ scrollTop: $(ID).offset().top}, 1000, function() {debounce=false;});
});
Basically, it disables the onclick event on fire until it is scrolled up, then enables the event.
You could wrap you onClick function in a throttle which keeps it from executing again while it's scrolling.
Like so:
// lodash is defined here as _
var animationTime = 1000;
var scrollTo = _.throttle(function (event) {
var ID = this.hash;
//has a few extra conditionals here specific to the page
$('html,body').animate({ scrollTop: $(ID).offset().top }, animationTime);
}, animationTime);
$(".nav-scroll").click(scrollTo);
Is this case the first time the users clicks the function gets called but if they click again within the time frame (the 1000ms) the the function does not execute again. Only after the time has passed can the user invoke the function again.
Here you can find the documentation for lodash throttle:
https://lodash.com/docs#throttle
This question already has answers here:
Fire event each time a DropDownList item is selected with jQuery
(10 answers)
Is there an onSelect event or equivalent for HTML <select>?
(37 answers)
Closed 8 years ago.
I have a simple dropdown named Filtername. I want to run a function when a value is selected from the list. I have already tried below
$('#FilterName').change(function() {
code1;
code2;
}
The problem is that it works only when selected value gets changed. I want to run the function even if the user selects the same value again from the dropdown. So I need to run the function when the value is selected. I tried .select/.submit functions but they didn't work. Please help.....
From my answer on Fire event each time a DropDownList item is selected with jQuery:
A lot of the current solutions will break in a lot of situations. Any solution that relies on checking the click count twice will be very fickle.
Some scenarios to consider:
If you click on, then off, then back on, it will count both clicks and fire.
In firefox, you can open the menu with a single mouse click and drag to the chosen option without ever lifting up your mouse.
If you use any combination of keyboard strokes you are likely to get the click counter out of sync or miss the change event altogether.
You can open the dropdown with Alt+↕ (or the Spacebar in Chrome and Opera).
When the dropdown has focus, any of the arrow keys will change the selection
When the dropdown menu is open, clicking Tab or Enter will make a selection
Here's a more comprehensive extension:
The most robust way to see if an option was selected is to use the change event, which you can handle with jQuery's .change() handler.
The only remaining thing to do is determine if the original element was selected again.
This has been asked a lot (one, two, three) without a great answer in any situation.
The simplest thing to do would be to check to see if there was a click or keyup event on the option:selected element BUT Chrome, IE, and safari don't seem to support events on option elements, even though they are in the w3c recommendation
Inside the Select element seems to be a black box. If you listen to events on it, you can't even tell on which element the event occurred or whether the list was open or not.
The next best thing then, seems to handle the blur event. This will indicate that the user has focused on the dropdown (perhaps seen the list, perhaps not) and made a decision that they would like to stick with the original value. To continue handling changes right away we'll still subscribe to the change event. And to ensure we don't double count, we'll set a flag if the change event was raised so we don't fire back twice:
Code:
(function ($) {
$.fn.selected = function (fn) {
return this.each(function () {
$(this).focus(function () {
this.dataChanged = false;
}).change(function () {
this.dataChanged = true;
fn(this);
}).blur(function (e) {
if (!this.dataChanged) {
fn(this);
}
});
});
};
})(jQuery);
Then call like this:
$("#dropdownid").selected(function (e) {
alert('You selected ' + $(e).val());
});
Updated example in jsFiddle
I am working on a Javascripyt/html mobile app and I want to implement the session timeout feature. The easiest way is to use the setTimeout function but I want to check if any click, change event was performed before I make the decision. The logic needs to be:
checkForSessionTimeout() {
if(delta(last logged event time) < session timeout time) {
// do not timeout
// reset the delta to 0
} else {
//timeout and take to login page
}
}
I am able to get the function but not sure how do I log all click and change events on the browser.
Please help!
Are you using jQuery? This example uses jQuery but you should be able to adapt it to whatever you are using: Listen for events on all DOM nodes. With jQuery, $('*').on('click', function() ...). This will let you capture events even when a more close event binding has used stopPropagation.
It should work the same for change...
An example (open console): http://jsfiddle.net/u6eDj/2/
Yes, I know this question has been asked before, but I can't find an answer that works. This is an accepted answer from one of the other questions:
$('#element').hover(function()
{
$(this).data('timeout', window.setTimeout(function()
{
alert('hovered for 2 seconds');
}, 2000));
},
function()
{
clearTimeout($(this).data('timeout'));
alert('mouse left');
});
http://jsfiddle.net/nCcxt/
As you see it doesn't do what it's supposed to.
What I need is simple in theory but I can't get it to work - when a user hovers over a link for 2 seconds, a function is called. If the user moves the mouse away before 2 seconds pass, nothing happens.
The code works perfectly fine. It only breaks due to the alert() calls which causes the mouseout event to be triggered.
What do we learn from it? Do not use alert() in combination with focus/hover/mousemove-related events.
By the way, there are already jQuery plugins available for what you want to do: http://cherne.net/brian/resources/jquery.hoverIntent.html
I need to initiate the event handler after 3 seconds of being focused on an image. How should I go about it?
Also, I need to trigger another event handler, when I am at a particular part of an image, say the approximate middle of the image. How do I do this?
Use javascript's setTimeout and setInterval functions.
// alert after 2 seconds
setTimeout("alert('Hello World!')", 2000);
// alert every 2 seconds
setInterval("alert('Hello, world!')", 2000);
JavaScript
var timeout;
function message(){
alert('Hey there');
}
function start(){
timeout = setTimeout(message,3000);
}
function stop(){
clearTimeout(timeout);
}
HTML
<img src="HappyCow.jpg" onmouseover="start()" onmouseout="stop()" />
The event handling is rough here (inline >.<), but I think this gets you started.
For question #1: look into timers - you'd start it when the image is in focus (or the mouse hovers over it etc.), then it calls a function after 3 seconds (or any other period). The function would handle what you want to do after three seconds. (Maybe also check if the image is still "active".)
For question #2: One way to do this is Imagemaps, but there may be other/better options.
Hope this helps!