Is there any way to pause mousemove event until task complete?
$( document ).bind( 'mousemove', function ( e )
{
// mousemove: please wait and stop moving
document.removeEventListener('mousemove');
// I am the task
$.ajax( {
url: '/getData',
type: 'POST',
success: function ( result ){}
} )
.done(function()
{
// I am done, start moving...
document.addEventListener('mousemove');
});
} );
What I want:
mousemove event fired and stopped as
soon as it is fired.
Function inside it executes.
When function done executing,
mousemove event starts again firing
What this does is pause the mouse
move event until task is done or
fails.
First of all, why do you mix raw DOM/event access with jQuery? Don't do that.
To achieve what you want simple make your function a non-anonymous one and use $(document).one('mousemove', yourFunction); to bind it - both somewhere outside and in your done() function.
function handleMouseMove(e)
{
// I am the task
$.ajax({
url: '/getData',
type: 'POST',
success: function ( result ){}
})
.done(function() {
$(document).one('mousemove', handleMouseMove);
});
}
$(document).one('mousemove', handleMouseMove);
If your task time is small.
You can use a bool flag to keep a lock on mousemove functionality.
This will call the function on mousemove though, but return without doing anything
until you release the lock.
var moveFlag = true;
$( document ).bind( 'mousemove', function ( e )
{
if(moveFlag == false)
return;
moveFlag = false;
// I am the task
$.ajax( {
url: '/getData',
type: 'POST',
success: function ( result ){}
} )
.done(function()
{
// I am done, start moving...
moveFlag = true;
});
} );
Use a flag to disable/enable it like this:
$(document).data('enableMyMouseMove',true).bind('mousemove',function (e) {
if($(document).data('enableMyMouseMove')) {
$(document).data('enableMyMouseMove',false);
$.ajax( {
url: '/getData',
type: 'POST',
success: function (result) {},
complete: function (){ $(document).data('enableMyMouseMove',true); }
});
}
});
Notice that I have moved your 'done' function into the complete eventHandler on the ajax call, since imo, that is cleaner, but you can keep the done function if your wish, the logic is the same.
Try to avoid binding/unbinding event handlers all the time, since it is a very easy way to create memleaks unless you know what you are doing, especially in ie.
The reason for this is that ie has separate garbage collection for js and DOM objects, and if there is a cyclic reference between the two, garbage collection will not occur. Creating cyclic dependencies between js and DOM happens very easily when you bind eventHandlers
Related
I have this click handler which has an ajax call to get back some data and I set a flag in before send and clears it in complete. The problem that I am facing is that. When I tired to click this twice, the process goes like the following. I wondered what would be a better way to solve this issue. I thought about doing $.active to find out the numbers of ajax calls that's active but that doesn't seem like that right way
1 remove initiated, set flag,
2 remove initiated, set flag.
1 remove response completed, reload and clear the flag.
2 remove response completed, reload (Since the flag was clear by the 1 response, it adds the default which I don't want ).
$(document).on('click', '#remove', function () {
$.ajax({
type: 'POST',
url: '/remove'
data: {
fruits: $(this).val()
},
beforeSend: function () {
$('#fruit-table').addClass('loading');
},
success: function (data) {
loadFruitTable(data);
},
complete: function () {
$('#fruit-table').removeClass('loading');
}
};
loadFruitTable = function (data) {
$('#fruit-table').html(data);
if ($('.processing').length) {
preLoadDefault();
}
};
Just an idea: disable the remove button on click and enable it in the complete-part?
You could use .ajaxStart to show the loading object and .ajaxComplete to handle the event of all data being loaded:
$( document ).ajaxStart(function() {
$( ".log" ).text( "Triggered ajaxStart handler." );
});
$( document ).ajaxComplete(function() {
$( ".log" ).text( "Triggered ajaxComplete handler." );
});
http://api.jquery.com/ajaxComplete/
$(document).on('click', '#remove', function () {
var $fruitTable = $('#fruit-table');
if ($fruitTable.hasClass('loading')) {
return;
}
$fruitTable.addClass('loading');
$.ajax({
type: 'POST',
url: '/remove'
data: {
fruits: $(this).val()
})
.then(loadFruitTable, function () {})
.then(reinitFruitTableStatus);
};
var reinitFruitTableStatus = function () {
$('#fruit-table').removeClass('loading');
};
loadFruitTable = function (data) {
$('#fruit-table').html(data);
if ($('.processing').length) {
preLoadDefault();
}
};
If the element #fruit-table is not dynamically created, you should store it once in a variable available in the whole code above.
Actually... Instead of adding a class, I added a count which increments in beforeSend and decrement in complete. So that way, i can always check if there is any process that's active.
I am making few ajax requests in my jQuery file. On success of these jQuery requests, I wrote few on click events which are not working.
This is my code
$(document).ready(function (){
$.ajax ({
type: "POST",
url: 'myServlet',
async: false,
success: function (response) {
id = parseInt(response);
setOutputEvents();
}
});
function setOutputEvents() {
for (var queryNumber = 0; queryNumber <= id; queryNumber++) {
$.ajax({
type: "POST",
url: 'myOtherServlet',
data: {queryNumber: queryNumber},
success: success,
async: false
});
var success = function (response) {
//some code here
generateTable();
}
}
}
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
});
I understand making multiple ajax requests is a bad programming practice but what could be the reason for on click events not getting triggered?
These are the onclick events which are not working.
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
I am using Google Chrome Version 39.0.2171.95 on Windows 7.
Please do let me know if any further information is necessary.
Since you use ajax to load even the initial content it seems, .class / #me html elements likely do not exist on initial page load of the DOM. As you didn't post html, i'm guessing this is the case.
Thus, you need to use a delegated event click handler to respond to it
so, you would change
$("#me").on("click", function(){
to
$(document).on("click", "#me", function(){
and so forth to link it to the parent element that does exist, the document itself.
This would work:
$(".class").on("click", function(){
alert("me is triggered");
});
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").trigger("click");
}
Some notes:
Event handler must be registered before triggering click.
Triggered click selector must match the class which has the click event registered.
Functions must be defined before the usage.
We're trying to upgrade our jquery using jquery migrate.
We get the "JQMIGRATE: Global events are undocumented and deprecated" on this code (a wrapper for jquery.ajax):
ajaxPost: function (url, jsonData, successCallback, async) {
if (async == null) {
async = true;
}
var ajaxSettings = {
url: url,
type: 'POST',
async: async,
data: JSON.stringify(jsonData),
contentType: 'application/json; charset=UTF-8',
success: function (data, code, xht) {
successCallback(data, code, xht);
},
error: function (xht, errorType, exception) {
console.log(...);
}
};
$.ajax(ajaxSettings);
}
The "error" occurs for this line:
successCallback(data, code, xht);
We're not sure how to fix it?!
This is a piece of code from JQMIGRATE responsible for warning
// Turn global events into document-triggered events
jQuery.event.trigger = function( event, data, elem, onlyHandlers ){
if ( !elem && !rajaxEvent.test( event ) ) {
migrateWarn( "Global events are undocumented and deprecated" );
}
return eventTrigger.call( this, event, data, elem || document, onlyHandlers );
};
Looks like this warning is popping on trigger() calls in two cases:
1) no element is specified as trigger context
2) event is global ajax event
Global ajax event example:
$(document).bind("ajaxSend", function(){
$("#loading").show();
}).bind("ajaxComplete", function(){
$("#loading").hide();
});
But if you say you had disabled global events by setting jQuery.ajaxSetup({global: false}), then
problem could be caused by case 1, but i dont see any code releavant to it in the provided fragment.
Probably you need to check implementation of method successCallback for case 1.
I have a text field with keypress event handler jsfiddle. And when I type something in this field and press "Enter" 2 times, 2 requests will be send. I want to turn off all events, while ajax request in progress. One option is to call .off() function before ajax call, and then bind event handler again. Any other options?
use the callback handlers from your ajax call and a boolean used as flag. By setting the ajaxLoading boolean to false in the "always" callback, you can be sure that other, future requests can be made independent from whether the current ajax call throws an error or not.
var ajaxLoading = false;
if(!ajaxloading){
ajaxloading=true;
$.ajax({
url: 'your url',
type: 'GET',
dataType: 'JSON'
})
.done(function(data) {
console.log("success");
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
ajaxloading=false;
});
}
I use 2 boolean flags, like:
var is_requesting = false, should_request = false;
function onkeydown() {
if (is_requesting) {
should_request = true;
return;
}
is_requesting = true;
$.ajax({}, function () {
is_requesting = false;
if (should_request) {
onkeydown();
}
});
}
Is there a good reason for you not to use the jQuery .off() function?
If so then you could simply disable the control prior to making the ajax request and re-enable it once the request is complete. This would also stop the user from thinking he/she could change the result by changing the text value during the request.
//Disable the input
$('#myresult').prop('disabled', true);
$('#myresult').append('<br>'+$(this).val());
$.ajax({
type: "POST",
beforeSend: function() {},
complete: function() {
//Re-Enable the input
$('#myresult').prop('disabled', false);
},
url: "/echo/json/",
data: { delay : 3 },
success: function(){},
error: function() {},
dataType: 'json'
});
I'm having problems with updating elements that are not ready after an ajax request.
If I run my myFunction() function on page load like so:
$(function() {
myFunction();
}
I have no problems at all. But if I then use something like
$.ajax({
url: this.href,
dataType: "script",
complete: function(xhr, status) {
myFunction();
}
});
which returns $(".myElement").replaceWith("htmlHere"). The elements are simply not ready when the complete event fires. If I set a delay in there it works fine again.
Is there any other event that gets fired other than 'complete' when the DOM is ready?
Update:
Here's the actual code:
$(function() {
$("a.remote").live("click", function(e) {
$.ajax({
url: this.href,
dataType: "script",
success: function(xhr, status) {
myFunction();
}
});
e.preventDefault();
return false;
});
myFunction();
});
function myFunction() {
// Modify the dom in here
}
The missing ); was just a typo on my part.
Ive tried using success now instead of complete and it doesn't appear to make any difference.
I have set up a jsfiddle based on your code, and it seems to be working.
This is the current code:
$(function() {
$("a.remote").live("click", function(e) {
$.ajax({
url: this.href,
dataType: "script",
success: function(xhr, status) {
myFunction();
}
});
e.preventDefault();
return false;
});
});
function myFunction() {
$("span").replaceWith("<p>test</p>");
}
And it replaces span tag with a paragraph. Please check it and compare with your code. If it is the same, then your problem somewhere other than this function (maybe in myFunction?).
You can use $(document).ready(function() { ... }); to wrap up anything you want fired when the DOM has loaded. Your ajax request could be placed inside the document.ready if you want this to wait until the dom has loaded.
If you want to wait until the ajax has loaded its resource then you should use ajax.success rather than complete.
Just change complete: to success: in your $.ajax() call:
$.ajax({
url: this.href,
dataType: "script",
success: function(xhr, status) {
//make your DOM changes here
myFunction();
}
});
The success function will run once the AJAX request receives a successful response. So make your DOM changes within that function, and then run myFunction().
Edit
You seem to be trying to make the DOM changes using your myFunction(). But if you don't first insert the HTML received in the AJAX response into the DOM, then there will be nothing for myFunction() to modify. If this is indeed what's happening, then you have two options:
Insert the response HTML into the DOM, then call myFunction() (and all of this should happen within the success callback function).
Pass the AJAX response to myFunction() as an argument, so that myFunction() can handle the DOM insertion and then do the necessary modification.
There is a event that triggers after every ajax call. It is called ajaxComplete.
$( document ).ajaxComplete(function() {
$( ".log" ).text( "Triggered ajaxComplete handler." );
});
So you can
function Init(){
// stuff here
}
$(document).ready(function()
Init();
});
$(document).ajaxComplete(function()
Init();
});
You are missing the closing parenthesis of the document ready wrapper function.
$(function() {
myFunction();
});
Note the }); at the end.
$(function() {
myFunction();
}
should be
$(document).ready(function() {
myFunction();
});
Or incase you want the ajax to run on load. Do
$(document).ready(function() {
$.ajax();
});