Determine from function when an event stops with JavaScript - javascript

Simplified scenario:
I have a click event on a button
Inside the event I call a function X
Function X returns a value
Click event changes DOM using received data (actually renders a jQuery Template)
SAMPLE CODE:
$("button").click(function()
{
var response = FunctionX();
doTemplateRendering(response); //(*)
});
function FunctionX()
{
//some code
return some_value;
//The click event has finished, so now make a little adjust to the generated dom (*)
}
The questions are:
Do I have a way to determine when the click stops form FunctionX()?
Or is there a way that doTemplateRendering() triggers something that I can capture from FunctionX() so it doesn't matter if I return a value, because at some point I'm going to be able to execute the extra code that I need
The reason behind this is that this is part of a framework and I can't change the click event.

You can't return a value from a function and then do further processing within the same function. But you can schedule some code to run later using setTimeout():
function FunctionX()
{
//some code
setTimeout(function() {
//The click event has finished, so now make a little adjust to the generated dom (*)
}, 5);
return some_value;
}
JS is single-threaded (if we ignore web-workers), so the function you pass to timeout won't be executed until after the click event finishes.
Alternatively, you can bind a second click handler to the same button and do your extra processing there - jQuery guarantees that event handlers (for the same event and element) will be run in the order that they're bound.

Not sure if this works for you, but couldn't you use a callback function that you pass to FunctionX?
$("button").click(function()
{
var fn = funcion(){response){
doTemplateRendering(response);
}
FunctionX(fn);
});
function FunctionX(fn)
{
//some code
fn(some_value);
//The click event has finished, so now make a little adjust to the generated dom (*)
}

Related

jQuery call animation before debounce method executes

I have a piece of code like following:
$('.cardButton').click($.debounce(1500, function () {
console.log("OK");
}));
The debounce in this case works just perfectly..
However - I need to add animation function which will replace ".cardButton" element before the debounce occurs...
Doing something like this:
$('.cardButton').click($.debounce(1500, function () {
StartAnimationLoader();
console.log("OK");
}));
// In this case - animation starts as soon as console writes out "OK" ...
Or like following:
$('.cardButton').click(function(){
StartAnimationLoader();
$.debounce(1500, function () {
console.log("OK");
})
});
// When I execute code like this - there is nothing written in the console... - thus this method doesn't works
I need to execute animation before debounce occurs ...
What am I doing wrong here?
Can someone help me out ?
Adding a 2nd (or more) event handler to the same element will fire both events (unless stopped) so you can create two actions by having two separate event handlers:
// existing debounce fire only after user stops clicking
$('.cardButton').click($.debounce... );
// additional event will fire on every click
$(".cardButton").click(function() { StartAnimationloader() });

Unable to unbind event listener - trouble with turbolinks caching

I'm binding then unbinding the ready event listener to the document.
$(document).bind("ready", readyEventHandler);
function readyEventHandler() {
// run some code
$(document).unbind("ready");
}
The code produces no errors and will work. However, my javascript is cached and duplicates the code so I'll end up with having this code run more than once if I go back and then forward a page in the browser. When this happens, the ready event listener is not called at all. Am I properly unbinding this event listener? I know the caching issue becomes problematic(it's own separate issue) but I just want to bind the ready event listener, have it run code, then unbind it.
Not so sure it will help, but here are my 2 cents - instead of trying to unbind the readyEventHandler - make sure that if you run the function once it will not run twice:
var readyHandlerRun = false;
$(document).bind("ready", readyEventHandler);
function readyEventHandler() {
if (readyHandlerRun) {
return;
}
readyHandlerRun = true;
// Rest of your code...
}
Another options that popped just now:
$(document).bind("ready", readyEventHandler);
function readyEventHandler() {
readyEventHandler = function() { }
console.log('ready');
// Rest of your code...
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
UPDATE (by #jason328)
After talking with Dekel he provided me the appropriate answer.
$(document).bind("ready", function() {
readyEventHandler();
readyEventHandler = function() { }
});
Elegant and works like a charm!
if you just would like to use an eventhamdler only once, you could use one instead of bind
$(document).one("ready", function() {
// code to run on document ready just for once
});

Why does click event on window not have target event path unless within setTimeout?

I am working on a JavaScript library for some data collection. I need to capture all click events, and want to traverse the event path looking for specific tags/ids/classes on click.
If I run the following code without the setTimeout, the event path always comes back with a single object in the array for Window. Add the setTimeout and the event path comes as expected.
window.addEventListener('click', function (event) {
// setTimeout with a 4ms delay to push to the end of the JS execution queue.
setTimeout(function() {
console.log(event.path);
}, 4);
});
You should wait for window to load, use below code so you should get the same result without the time delay:
window.onload = function() {
document.addEventListener('click', function (event) {
console.log(event.path);
});
};

jQuery prevent multiple submisssions before response

I would do this in JS fiddle, but I can't get the POST echoer to work, so I'll make an example here. Let's pretend that someApi returns "bar"
JS / jQuery
$(function() {
$('button').click(function(event) {
getSomeData();
});
function getSomeData() {
$("div").text("Foo = ");
$.get("someApi", function(i) {
$("div").append(i);
});
};
});
HTML
<div></div>
<button>Click Me</button>
There maybe some typos here, but please ignore them as I've written an example on-the-fly. What happens is when <button> is clicked once, all works well. The AJAX function is called and the <div> is appended when the response comes. If I wait for the response and click again, the <div> is overwritten with Foo = and then appended. The issue comes when the user becomes inpatient and clicks <button> multiple times, spawning multiple AJAX requests. This ends up with "bar" being appended multiple times. Is there a feature within JS / jQuery to avoid sending multiple requests to the same URL? I DON'T mean I want a async = false scenario; I know this would work, but would also slow the application down. I also know I could add an if loop that checks if bar has already been appended. What I'm asking for is a proper JS / jQuery .blockMultipleRequest(); kind of thing.
I don't think that there's a plugin for that. You could use .one() in this way:
function bindButton() {
$('button').one('click', function(event) {
getSomeData();
});
}
function getSomeData()
$("div").text("Foo = ");
$.get("someApi", function(i) {
$("div").append(i);
bindButton();
});
}
$(function() {
bindButton();
});
In function bindButton() you define your event handler with one(). Once button has been clicked event is removed until response of AJAX call, then function bindButton() is called again and event handler gets bound again.
You could use the global AJAX event handlers that jQuery provides and then do stuff depending on the request.
.ajaxSend() when any request starts (the event, jqXHR, and settings properties are sent to the handler, so you can then do URL-specific actions by evaluating settings.url
.ajaxComplete() when any request completes.
You could then use an object that keeps track of AJAX calls per URL, which can consult before sending off another request (e.g. only if it not currently in an active/pending state).

jquery after ajax complete /done , to call a function, the function will execute more and more times. why?

I've been stuck on this issue for about 2 days. My code (JSFiddle here) is thus:
var foo = function(){
// The code in here will be execute more and more and more times
$(element).hover(function() {
console.log("buggie code run")
})
}
var sliderShow = $(secondElement).bxSlider({
onAfterSlide:function(currentSlideNumber) {
$.ajax("/echo/html/").done(function() {
foo();
})
}
})
My problem is the code will run more than once. For example, when you hover over the element it will fire the function once, but second time it will fire twice. The third time it will fire 3 times, and so on. Why is this happening? Am I making a basic logic error, or is this JavaScript doing something?
This means you are registering the event more than once, probably on each load. You should do so only once!
Hovering itself calls the function twice once on entry and once on exit.. try
var foo = function(){
$(element).hover(function() {console.log("IN")},function() {console.log("OUT")});
}
But then as ThiefMaster pointed out you are also registering the eventhandler multiple times. In you slider, the second time you will add the event handler again and so on and on.
Look at http://docs.jquery.com/Namespaced_Events

Categories