I have the problem that the jQuery mobile slider fires too often to get handled properly on the server. I have something like this:
$("#testSlider").change(function( event, ui ) {
$.getJSON($SCRIPT_ROOT + '/_update_sliders', {
c: $('#testSlider').val()
}, function(data) {
g4.updateOptions( { 'file': data.result } );
});
This works perfectly fine, /_update_sliders starts a function in python which sends data.result back to the site. The problem occurs if I change the slider too fast - too many requests are send, when I stop the slider it takes quite some time too catch up and it even mixes up the requests - so the end state might not even present the actual slider value.
What is a clean solution to this? Anyway to restrict the amount of times the change event fires up?
Thank you and kind regards
lakerz
You could put a throttle on it using following concept. Uses setTimeout() to add delay, and if changes are constantly happening delay gets pushed back and it will not fire until a full delay period has ended
var sliderTimer,
sliderAjaxDelay = 100;
$("#testSlider").change(function (event, ui) {
if (sliderTimer) {
clearTimout(sliderTimer); /* if already a timeout, clear it */
}
// throttle requests using setTimeout
sliderTimer = setTimeout(sliderAjaxUpdate, sliderAjaxDelay);
});
function sliderAjaxUpdate() {
$.getJSON($SCRIPT_ROOT + '/_update_sliders', {
c: $('#testSlider').val()
}, function (data) {
g4.updateOptions({
'file': data.result
});
});
}
Adjust the delay variable to what suits you
I found a solution in jQuery which works, but I'm not sure if this is a "clean" way:
var complete = 0;
$("#testSlider").change(function (event, ui) {
if (complete == 1) {
sliderAjaxUpdate();
complete = 0;
};
});
function sliderAjaxUpdate() {
$.getJSON($SCRIPT_ROOT + '/_update_sliders', {
c: $('#testSlider').val()
}, function (data) {
g4.updateOptions({
'file': data.result
});
});
};
$( document ).ajaxComplete(function() {
complete = 1;
});
Related
This code determines if the user is online :
/* User online status */
var online = true;
var activeTimeout = setTimeout(_setUserInactive, 5000);
$(document).on("mousemove keydown keyup click", function () {
clearTimeout(activeTimeout);
activeTimeout = setTimeout(_setUserInactive, 5000);
if (!online) {
_setUserActive();
}
});
Pretty simple. But, is this going to cause performance issues? It will call every time the mouse is moved. Thanks.
I have a setinterval that runes every 5 seconds. this works fine on page load.
I have the following scenarios:
Load page with interval (WORKS)
press button and load new content and stopp interval(WORKS)
Once the new content is no longer desiered, dissmiss it, return to first content and start interval again(DOES NOT WORK)
I have saftys suchs as events for window.blur that also stops the interval so that the browser does not commponsate for all the missing intervals if i would change tabs or something. Keep in mind that step 3 did not work BUT if i would after step 3 change a tab and then return to my original page(execute blur) the interval would start working again.
NOTE all content loading here exept page load is done with ajax calls.
My code:
initializing:
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function() {
$.automation.tanks.tableInit();
});
binding function:
bindIntervalEvent: function (target, url, callback) {
$(window)
.on("focus.mine",
function() {
$.automation.worker.setUpdateInterval(target, url, callback);
})
.on("blur",
function() {
$.automation.worker.stopUpdateInterval();
}).trigger("focus.mine");
}
interval function:
setUpdateInterval: function (target, url, callback) {
if ($.automation.globals.globalInterval.value.length === 0) {
$.automation.globals.globalInterval.value.push(window.setInterval(
function () {
var options = {
loadTarget: target
}
$.automation.worker.getView(url,
function() {
if (callback)
callback();
},
options);
},
5000));
}
}
the function that stops the interval:
stopUpdateInterval: function () {
if ($.automation.globals.globalInterval.value.length === 0)
return;
console.log("deleting");
for (var i = 0; i <= $.automation.globals.globalInterval.value.length; i++) {
window.clearInterval($.automation.globals.globalInterval.value[i])
$.automation.globals.globalInterval.value.splice(i, 1);
console.log($.automation.globals.globalInterval.value.length);
}
}
when stopping the interval i also remove the window bindings:
unBindIntervalEvent: function() {
$(window).off("focus.mine");
$(window).unbind("blur");
}
Back to step 3:
My sucess method in the callback to my getviewfunction is identical to what i execute in the beginning
code:
$(".updatelatest")
.on("click",
function () {
var _this = $(this);
var options = {
loadTarget:"#TanksContent"
}
$.automation.worker.getView("/Tank/GetTanks",
function (data) {
$(_this).switchClass("col-md-5", "col-md-1", 1000, function() {
$(_this).addClass("hidden");
$(".search").switchClass("col-md-5", "col-md-12", 1000, "easeInOutQuad");
})
$.automation.tanks.tableInit();
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function () {
$.automation.tanks.tableInit();
});
$(window).trigger("blur");
}, options);
});
but this does not start the interval. it is clearly initialized since it works when window.blur is executed for example when I change tab but for some reason this is not working beyond that.
i tried triggering the windows blur event and nothing happened, i tried triggering my custom window event "focuse.mine" but nothing happens.
I did not notice this while developing since I had firebug open and every time i checked scripts or css or the console the blur function was executed so I assumed that my code worked as intended but now that it is deployed I notice this.
My head is pounding beyond reason and I can't for figure out where I have gone wrong.
Well this was a fun one. I simply found that when calling the setUpdateInterval(); function directly it gave me the desiered result.
I realized that the reason I had them split like I did was becaouse of the blur event. "Focus.mine" is triggered to start the inteval again ocne a user comes back to the page.
I can do something such as the following every 30 seconds to reload the page, and the backend logic will determine which session have been invalidated:
setInterval(function () {
location.reload()
}, 30000);
However, how would I only run this 30s location.reload() if the user is not active? For example, how banks will have a user-timeout if the user has not been active on the page (which only starts counting after the user is 'inactive'). How would this be done?
One way is to track mousemoves. If the user has taken focus away from the page, or lost interest, there will usually be no mouse activity:
(function() {
var lastMove = Date.now();
document.onmousemove = function() {
lastMove = Date.now();
}
setInterval(function() {
var diff = Date.now() - lastMove;
if (diff > 1000) {
console.log('Inactive for ' + diff + ' ms');
}
}, 1000);
}());
First define what "active" means. "Active" means probably, sending a mouse click and a keystroke.
Then, design your own handler for these situations, something like this:
// Reseting the reload timer
MyActivityWatchdog.prototype.resetReloadTimer = function(event) {
var reloadTimeInterval = 30000;
var timerId = null;
...
if (timerId) {
window.clearInterval(timerId);
}
timerId = window.setInterval( reload... , reloadTimeInterval);
...
};
Then, make sure the necessary event handler will call resetReloadTimer(). For that, you have to look what your software already does. Are there key press handlers? Are there mouse movement handlers? Without knowing your code, registering keypress or mousemove on document or window and could be a good start:
window.onmousemove = function() {
...
activityWatchdog.resetReloadTimer();
...
};
But like this, be prepared that child elements like buttons etc. won't fire the event, and that there are already different event handlers. The compromise will be finding a good set of elements with registered handlers that makes sure "active" will be recognized. E.g. if you have a big rich text editor in your application, it may be enough to register only there. So maybe you can just add the call to resetReloadTimer() to the code there.
To solve the problem, use window blur and focus, if the person is not there for 30 seconds ,it will go in the else condition otherwise it will reload the page .
setTimeout(function(){
$(window).on("blur focus", function(e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case "blur":
$('div').text("user is not active on page ");
break;
case "focus":
location.reload()
break;
}
}
$(this).data("prevType", e.type);
})},30000);
DEMO : http://jsfiddle.net/rpawdg6w/2/
You can check user Session in a background , for example send AJAX call every 30 - 60 seconds. And if AJAX's response will be insufficient (e.g. Session expired) then you can reload the page.
var timer;
function checkSession() {
$.ajax({
url : 'checksession.php',
success: function(response) {
if (response == false) {
location.reload();
}
}
});
clearTimeout(timer);
timer = setTimeout(checkSession,30 * 1000);
}
checkSession();
Why would my jquery/javascript be buggy?
(using foundation 4.3.2 with Jquery 1.10.2)
Firefox always gives a message to stop the script:
"A script on this page may be busy, or it may have stopped responding..."
Here is the function that gives the problems
function preparePlz() {
$('#plzform').on("submit", function (event) {
event.preventDefault();
var plzVal = $('#plz').val();
var regex = new RegExp("^([0-9]{5})$");
if (!regex.test(plzVal)) {
$('.errormessage').addClass("error");
if ($('.errormessage').hasClass("hide")) {
$('.errormessage').removeClass("hide");
}
$("#plz ").addClass("error");
}
else if(regex.test(plzVal)) {
$('.errormessage').addClass("hide");
$('.errormessage').removeClass("error");
$('#plz').removeClass("error");
$('#message').removeClass("hide");
var plzZone = plzVal.substring(0, 2);
$('#plzModal').foundation('reveal', 'open', {
url: 'http://vaeplan.com/kontact/zone',
data: {showtemplate: false, r: plzZone}
});
}
});
preparePlz();
}
$(document).ready(function () {
preparePlz();
});
You have infinite recursion. Think about it, what happens on document ready? preparePlz is called. What happens inside preparePlz? preparePlz is called. What happens inside preparePlz? preparePlz is called.
The last thing function preparePlz does is run itself:
preparePlz();
When the page loads preparePlz is run once, then goes into an infinite loop.
Change
});
preparePlz();
}
to
});
}
I'm using BigVideo.js jQuery plugin to show full screen background videos. I have links that load different background videos on click. At the end of each video (3-5 sec long) I'm loading an animation. Each video has its own animation on top.
Right now I'm fading in the animations with a time out that corresponds to the video length but it's not full proof. What I really need is for #anim03 to fade in when video-03.mp4 ends. But I can't figure out exactly how the BigVideo.js .on("ended") event really works. In the code I have below (simplified):
// init plugin
var BV = new $.BigVideo({useFlashForFirefox:false});
BV.init();
function setupVideo(url) {
if (Modernizr.touch) {
BV.show(url + '.jpg');
} else {
BV.show(url + '.mp4',{
altSource: url + '.webm',
ambient: false
});
}
}
function setupAnimation(num) {
BV.getPlayer().on("ended", function () { // event from video.js API - when video ends playing
$('#anim0' + num).animate({ opacity: 1 });
});
}
$('a').on('click', function(e) {
e.preventDefault();
// we remove .ext cause we got to setup .webm and .jpg versions
var url = $(this).attr('href').replace('.mp4', '');
setupVideo(url);
var current = $(this).parent().index()+1;
setupAnimation(current);
});
The event is triggered but it seems to go through some sort of queue and fire multiple times. If I console.log num like that:
function setupAnimation(num) {
console.log(num);
BV.getPlayer().on("ended", function () {
$('#anim0' + num).animate({ opacity: 1 });
});
}
I get a single expected value. But if I do it like that:
function setupAnimation(num) {
BV.getPlayer().on("ended", function () {
console.log(num);
$('#anim0' + num).animate({ opacity: 1 });
});
}
Then I get multiple values for num and each time I click and this function is called, I get more and moreā¦ I'm guessing this .on("ended") loops through some array or something? I can't figure out that part from looking at the plugin's code.
Any help or pointer much appreciated!
When you use the player's "on" function you register a new listener function (This gives you the possibility to trigger multiple functions when something happens).
The reason your on "ended" function fires multiple times, is because each time setupAnimation executed it adds a new instance of the listener-function:
function () {
console.log(num);
$('#anim0' + num).animate({ opacity: 1 });
}
check the API documentation of Video.JS
https://github.com/videojs/video.js/blob/master/docs/api/vjs.Player.md#on-type-fn-
If I get right what you're trying to accomplish, the solution is to run 'setupAnimation' outside the on 'click' function.