jQuery - If browser tab is focused, then do AJAX - Not working - javascript

I have a code that determines if current browser window or tab is active. If it's active, the title of the tab says "active" and if not it says "blurred"
It is working fine. Here's the code:
$(window).on("blur focus", function (e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
if (e.type == "blur") {
document.title = 'blurred';
} else if (e.type = "focus") {
document.title = 'focus';
}
}
$(this).data("prevType", e.type);
})
The code above is working fine.
Now if I add AJAX to it, it doesn't work.
$(window).on("blur focus", function (e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
if (e.type == "blur") {
document.title = 'blurred';
} else if (e.type = "focus") {
var interval = function () {
$.ajax({
url: "<?php echo base_url('home/get') ?>",
cache: false,
success: function (html) {
$("#text").val(html);
document.title ='focus';
},
});
};
setInterval(interval, <?php echo $int ?>);
}
}
$(this).data("prevType", e.type);
})
It says focused if it's in focus. If I go out of focus, it says "blurred" for less than a second, then says focus again. I don't know why. I want it to say blurred if it's not in focus. Adding the AJAX code doesn't make it work.
Please help. Thanks.

You need to use clearTimeout() in your blur event. My code continuously polls my server for data, but when I go out of the page, it stops polling. Please look at the implementation below. I have done the similar one in my application here:
$(window).blur(function() {
clearTimeout(getJsonTmr);
clearTimeout(updatePreviewTmr);
}).focus(StartTimers);
function StartTimers () {
// Every half a second,
getJsonTmr = setInterval(function () {
$.get("/doodles/update?getJson&DoodleID=" + DoodleOptions.DoodleID, function (data) {
data = JSON.parse(data);
if (!DoodleOptions.isActive)
clearDoodleCanvas();
$.each(data, function (index) {
drawFromStream(data[index]);
});
});
}, 500);
updatePreviewTmr = setInterval(function () {
$.post("/doodles/update?updatePreview", {
"DoodleID": DoodleOptions.DoodleID,
"DoodlePreview": canvas.toDataURL()
});
}, 5000);
}
StartTimers();
You can use the above code as reference and change yours.
A simple reference implementation for you...
function timers() {
tmrAjax = setInterval(function () {
$.get(/* ... */);
}, 1000);
}
timers();
$(window).blur(function () {
clearInterval(tmrAjax);
}).focus(timers);

Related

Run the function after the effects is done

How can I run the function after the effect is done like delaying running the specified function after a certain time? I tried set timeout and it didn't work for me.
Here my Code
<script>
$("#findtext").keyup(function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13)
{
explodeEffect();
}
$.ajax({
url: 'resultFindFriend.php',
type: 'post',
async: false,
data: { dataFriend: $(this).val() },
success: function (data) {
$('.outputfindfriend').html(data);
}
},setTimeout(150));
});
function explodeEffect() {
$("#explodesearchresult").toggle("explode");
setTimeout(1000);
window.location("http://localhost/index.html");
};
$("#buttonfriend").click(function () {
explodeEffect();
return false;
});
</script>
This is doable with jQuery's .toggle(), just add a function as the second argument.
Try this:
function explodeEffect() {
$("#explodesearchresult").toggle(400, function() {
setTimeout(function() {
window.location.href = "http://localhost/index.html";
}, 1000);
});
}
This will redirect the page 1 second after the explode effect has finished.

submit during beforeunload, maybe who knows radically another method solution

Reviewed many similar questions on stackoverflow.com (also on other resources), but found no answers. So I simplified and generalized questions. It seems like the obvious solution:
$(document).ready(function() {
var a = 3;
var b = 5;
// no message when pressed submit button
$('form').submit(function() {
$(window).off('beforeunload');
});
// confirm of the need to save
$(window).on('beforeunload', function(e) {
if (a != b)
if (confirm('You changed data. Save?')) {
$('form').submit();
// alert('Your data is saved. (With alert submit() work only in FireFox!?)');
}
});
});
But not submit work. If you use the alert(), it works only in FireFox. I would like to correct (possibly without delay) cross-browser solution. Maybe who knows radically another method solution.
P.S. On some originality beforeunload described here in the first part: https://stackoverflow.com/a/6065085/1356425, but this is not the solution obvious functional.
Chrome and Firefox blocking submits after the onbeforeunload-event. You have to use
$(window).on('beforeunload', function(e) {
if (a != b)
return 'You\'ve changed the data. Leave page anyway?';
}
});
I used synchronous AJAX (JAX) request and run handler for events onUnload or onBeforeUnload once for the respective browser. This solution has a single and almost cross-browser behavior.
Example (on jsfiddle):
$(document).ready(function() {
var form = $('form');
var textareas = $('textarea');
function array_compare(a_0, a_1) {
if(a_0.length != a_1.length)
return false;
for(i = 0; i < a_0.length; i++)
if(a_0[i] != a_1[i])
return false;
return true;
}
var flag = false; // flag to control the execution of the unloadHandler() once
var a_open = []; // array with data before unload
$('textarea').each(function(index) {
a_open.push($(this).val());
});
function unloadHandler() {
if (flag)
return;
var a_close = []; // array with data during unload
$('textarea').each(function(index) {
a_close.push($(this).val());
});
if (!array_compare(a_open, a_close)) {
if (confirm('You changed the data, but not saved them. Save?')) {
$.ajax({
type: 'POST',
url: '/echo/json/',
async: false,
data: form.serialize()/* {
json: JSON.stringify({
text: 'My test text.'
}),
delay: 3
} */,
success: function(data) {
if (data) {
console.log(data);
alert('All data is saved!');
}
}
});
}
}
flag = true;
}
// For FireFox, Chrome
$(window).on('beforeunload', function () {
unloadHandler();
});
// For Opera, Konqueror
$(window).unload(function() {
unloadHandler();
});
// Without message when pressed submit button
$('form').submit(function() {
$(window).off('beforeunload');
$(window).off('unload');
});
});
Best way to submit data on unload is to store it in localstorage and send it next time when any other page under same origin is requested.
function sendBeacon(data) {
data?dataArr.push(data):'';
for (var i = 0, len = dataArr.length; i < len; i++) {
$.getScript(dataArr[i], (function (index) {
dataArr.splice(index, 1) //Updata dataArray on data submission
}(i)))
}
}
$(window).on('beforeunload', function () {
localStorage.setItem('dataArr', JSON.stringify(dataArr));
})
var dataArr = JSON.parse(localStorage.getItem('dataArr'));
if (!dataArr) {
dataArr = []; // Create Empty Array
} else {
sendBeacon(dataArr); //Submit stored data
}

setInterval and clearInterval javascript not working as needed

I have the following code partially working. I am newbie in javascript so please don't blame me if my approach is not the best.
window.url_var = "status.htm";
window.elem = "#e1";
function menu_item(){
$(window.elem).click(function (event)
{
$("#divTestArea1").load(window.url_var);
});
}
$("#e1").click(function (event)
{
event.preventDefault();
window.url_var = "demo2.txt";
window.elem = "#e1";
$("#divTestArea1").load(window.url_var);
auto_refresh = setInterval(menu_item(), 5000);
});
$("#e2").click(function (event)
{
event.preventDefault();
window.url_var = "status.htm";
window.elem = "#e2";
$("#divTestArea1").load(window.url_var);
auto_refresh = setInterval(menu_item(), 5000);
});
$("#e3").click(function (event)
{
event.preventDefault();
window.url_var = "form.htm";
window.elem = "#e3";
clearInterval(auto_refresh);
$("#divTestArea1").load(window.url_var);
});
jQuery(document).ready(function() {
$("#divTestArea1").load(window.url_var);
auto_refresh = setInterval(menu_item(), 5000);
});
Whenever I click elements e1 and e2, the setInterval works as expected and as soon as I click element e3, the element cease to be reloaded.
That's the behavior I want so far. But I also wants to start the setinterval again if e1 or e2 get's again clicked.
the last is what it's not working on the above code.
I will appreciate if you could point me in the right direction.
I have come to this code after seeing some of the answers to my original question (thanks to everyone). To clarify my original idea, I need to update some items on my web page on a regular basics but the content can be change with some menu and also some of the contents like a form should not be updated.
window.url_var = "demo2.txt";
var auto_refresh = null;
function setRefresh() {
var self = this;
this.bar = function() {
if(window.url_var != ""){
$("#divTestArea1").load(window.url_var);
auto_refresh = setTimeout(function() { self.bar(); }, 5000);
}
}
this.bar();
}
$("#e1").click(function (event)
{
event.preventDefault();
window.url_var = "demo2.txt";
setRefresh();
});
$("#e2").click(function (event)
{
event.preventDefault();
window.url_var = "status.htm";
setRefresh();
});
$("#e3").click(function (event)
{
event.preventDefault();
window.url_var = "form.htm";
$("#divTestArea1").load(window.url_var);
window.url_var = "";
});
$(document).ready(function() {
setRefresh();
});
Try using 2 different variables and clearing all if needed. This is: auto_refresh1 and auto_refresh2. Each time you call setinterval, it creates a new timer with a new id. You are overwriting auto_refresh variable and the timer before that will still fire.
Or you can store the setinterval in a hash object and run through and clear them all.
I'm unclear as to what exactly it is that you're trying to do here. Nevertheless, I've rewritten your code a bit to make some improvements (and fix one glaring bug in your code involving the setInterval calls).
var url_var = "status.htm",
elem = "#e1",
$destination = $("#divTestArea1"),
auto_refresh;
function menu_item() {
$(elem).bind("click", function (e) {
$destination.load(url_var);
});
}
function load() {
$destination.load(url_var);
}
function set(url, id) {
url_var = url;
elem = id;
}
function setRefresh() {
return setInterval(menu_item, 5000);
}
function handleClick(e) {
e.preventDefault();
set(e.data.url, e.data.id);
load();
auto_refresh = setRefresh();
}
$("#e1").on("click", {
url: "demo2.txt",
id: "#e1"
}, handleClick);
$("#e2").on("click", {
url: "status.htm",
id: "#e2"
}, handleClick);
$("#e3").on("click", function (e) {
e.preventDefault();
set("form.htm", "#e3");
clearInterval(auto_refresh);
load();
});
$(document).ready(function () {
load();
auto_refresh = setRefresh();
});
I'm guessing that maybe those setInterval calls should actually be setTimeout calls? Why would you want to bind a "click" event handler over and over again?
EDIT #1: Switched to jQuery's currently preferred on method from the bind method, included use of event data parameter to further abstract event handling code.

How do I test to see if <DIV> contents have changed before displaying them

Ive got a div with the id "responsecontainer" and I want to load a page. If the contents of the DIV have changed then update the DIV otherwise just leave it the same.
Here is my code, which doesnt work;
<script>
$(document).ready(function () {
$("#responsecontainer").load("qr.asp");
var refreshId = setInterval(function () {
$.get("qr.asp?randval=" + Math.random(), function (result) {
var newContent = $('.result').html(result);
if (newContent != $("#responsecontainer")) {
$("#responsecontainer").html(result);
};
});
}, 5000);
$.ajaxSetup({
cache: false
});
});
</script>
This:
if (newContent != $("#responsecontainer")) {
Should be this:
if (newContent != $("#responsecontainer").html()) {
I wouldn't rely on .html() representations for string comparison.
The browser decides how the HTML string should be rendered, and the developer won't be able to have any control if the browser decides it should be displayed differently one time.
You should have a variable that is accessible to each interval invocation, and do a string comparison between the old and new responses.
$(document).ready(function () {
var prev_response;
$("#responsecontainer").load("qr.asp", function(resp) {
prev_response = resp;
});
var refreshId = setInterval(function () {
$.get("qr.asp?randval=" + Math.random(), function (result) {
if (prev_response !== result) {
prev_response = result;
$("#responsecontainer").html(result);
}
});
}, 5000);
$.ajaxSetup({
cache: false
});
});

Long Press in JavaScript?

Is it possible to implement "long press" in JavaScript (or jQuery)? How?
(source: androinica.com)
HTML
Long press
JavaScript
$("a").mouseup(function(){
// Clear timeout
return false;
}).mousedown(function(){
// Set timeout
return false;
});
There is no 'jQuery' magic, just JavaScript timers.
var pressTimer;
$("a").mouseup(function(){
clearTimeout(pressTimer);
// Clear timeout
return false;
}).mousedown(function(){
// Set timeout
pressTimer = window.setTimeout(function() { ... Your Code ...},1000);
return false;
});
Based on Maycow Moura's answer, I wrote this. It also ensures that the user didn't do a right click, which would trigger a long press and works on mobile devices. DEMO
var node = document.getElementsByTagName("p")[0];
var longpress = false;
var presstimer = null;
var longtarget = null;
var cancel = function(e) {
if (presstimer !== null) {
clearTimeout(presstimer);
presstimer = null;
}
this.classList.remove("longpress");
};
var click = function(e) {
if (presstimer !== null) {
clearTimeout(presstimer);
presstimer = null;
}
this.classList.remove("longpress");
if (longpress) {
return false;
}
alert("press");
};
var start = function(e) {
console.log(e);
if (e.type === "click" && e.button !== 0) {
return;
}
longpress = false;
this.classList.add("longpress");
if (presstimer === null) {
presstimer = setTimeout(function() {
alert("long click");
longpress = true;
}, 1000);
}
return false;
};
node.addEventListener("mousedown", start);
node.addEventListener("touchstart", start);
node.addEventListener("click", click);
node.addEventListener("mouseout", cancel);
node.addEventListener("touchend", cancel);
node.addEventListener("touchleave", cancel);
node.addEventListener("touchcancel", cancel);
You should also include some indicator using CSS animations:
p {
background: red;
padding: 100px;
}
.longpress {
-webkit-animation: 1s longpress;
animation: 1s longpress;
}
#-webkit-keyframes longpress {
0%, 20% { background: red; }
100% { background: yellow; }
}
#keyframes longpress {
0%, 20% { background: red; }
100% { background: yellow; }
}
You can use taphold event of jQuery mobile API.
jQuery("a").on("taphold", function( event ) { ... } )
I created long-press-event (0.5k pure JS) to solve this, it adds a long-press event to the DOM.
Listen for a long-press on any element:
// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
console.log(e.target);
});
Listen for a long-press on a specific element:
// get the element
var el = document.getElementById('idOfElement');
// add a long-press event listener
el.addEventListener('long-press', function(e) {
// stop the event from bubbling up
e.preventDefault()
console.log(e.target);
});
Works in IE9+, Chrome, Firefox, Safari & hybrid mobile apps (Cordova & Ionic on iOS/Android)
Demo
While it does look simple enough to implement on your own with a timeout and a couple of mouse event handlers, it gets a bit more complicated when you consider cases like click-drag-release, supporting both press and long-press on the same element, and working with touch devices like the iPad. I ended up using the longclick jQuery plugin (Github), which takes care of that stuff for me. If you only need to support touchscreen devices like mobile phones, you might also try the jQuery Mobile taphold event.
For modern, mobile browsers:
document.addEventListener('contextmenu', callback);
https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu
jQuery plugin. Just put $(expression).longClick(function() { <your code here> });. Second parameter is hold duration; default timeout is 500 ms.
(function($) {
$.fn.longClick = function(callback, timeout) {
var timer;
timeout = timeout || 500;
$(this).mousedown(function() {
timer = setTimeout(function() { callback(); }, timeout);
return false;
});
$(document).mouseup(function() {
clearTimeout(timer);
return false;
});
};
})(jQuery);
$(document).ready(function () {
var longpress = false;
$("button").on('click', function () {
(longpress) ? alert("Long Press") : alert("Short Press");
});
var startTime, endTime;
$("button").on('mousedown', function () {
startTime = new Date().getTime();
});
$("button").on('mouseup', function () {
endTime = new Date().getTime();
longpress = (endTime - startTime < 500) ? false : true;
});
});
DEMO
For cross platform developers (Note All answers given so far will not work on iOS):
Mouseup/down seemed to work okay on android - but not all devices ie (samsung tab4). Did not work at all on iOS.
Further research its seems that this is due to the element having selection and the native magnification interupts the listener.
This event listener enables a thumbnail image to be opened in a bootstrap modal, if the user holds the image for 500ms.
It uses a responsive image class therefore showing a larger version of the image.
This piece of code has been fully tested upon (iPad/Tab4/TabA/Galaxy4):
var pressTimer;
$(".thumbnail").on('touchend', function (e) {
clearTimeout(pressTimer);
}).on('touchstart', function (e) {
var target = $(e.currentTarget);
var imagePath = target.find('img').attr('src');
var title = target.find('.myCaption:visible').first().text();
$('#dds-modal-title').text(title);
$('#dds-modal-img').attr('src', imagePath);
// Set timeout
pressTimer = window.setTimeout(function () {
$('#dds-modal').modal('show');
}, 500)
});
The Diodeus's answer is awesome, but it prevent you to add a onClick function, it'll never run hold function if you put an onclick. And the Razzak's answer is almost perfect, but it run hold function only on mouseup, and generally, the function runs even if user keep holding.
So, I joined both, and made this:
$(element).on('click', function () {
if(longpress) { // if detect hold, stop onclick function
return false;
};
});
$(element).on('mousedown', function () {
longpress = false; //longpress is false initially
pressTimer = window.setTimeout(function(){
// your code here
longpress = true; //if run hold function, longpress is true
},1000)
});
$(element).on('mouseup', function () {
clearTimeout(pressTimer); //clear time on mouseup
});
You could set the timeout for that element on mouse down and clear it on mouse up:
$("a").mousedown(function() {
// set timeout for this element
var timeout = window.setTimeout(function() { /* … */ }, 1234);
$(this).mouseup(function() {
// clear timeout for this element
window.clearTimeout(timeout);
// reset mouse up event handler
$(this).unbind("mouseup");
return false;
});
return false;
});
With this each element gets its own timeout.
This worked for me:
const a = document.querySelector('a');
a.oncontextmenu = function() {
console.log('south north');
};
https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/oncontextmenu
You can use jquery-mobile's taphold. Include the jquery-mobile.js and the following code will work fine
$(document).on("pagecreate","#pagename",function(){
$("p").on("taphold",function(){
$(this).hide(); //your code
});
});
Most elegant and clean is a jQuery plugin:
https://github.com/untill/jquery.longclick/,
also available as packacke:
https://www.npmjs.com/package/jquery.longclick.
In short, you use it like so:
$( 'button').mayTriggerLongClicks().on( 'longClick', function() { your code here } );
The advantage of this plugin is that, in contrast to some of the other answers here, click events are still possible. Note also that a long click occurs, just like a long tap on a device, before mouseup. So, that's a feature.
I needed something for longpress keyboard events, so I wrote this.
var longpressKeys = [13];
var longpressTimeout = 1500;
var longpressActive = false;
var longpressFunc = null;
document.addEventListener('keydown', function(e) {
if (longpressFunc == null && longpressKeys.indexOf(e.keyCode) > -1) {
longpressFunc = setTimeout(function() {
console.log('longpress triggered');
longpressActive = true;
}, longpressTimeout);
// any key not defined as a longpress
} else if (longpressKeys.indexOf(e.keyCode) == -1) {
console.log('shortpress triggered');
}
});
document.addEventListener('keyup', function(e) {
clearTimeout(longpressFunc);
longpressFunc = null;
// longpress key triggered as a shortpress
if (!longpressActive && longpressKeys.indexOf(e.keyCode) > -1) {
console.log('shortpress triggered');
}
longpressActive = false;
});
In vanila JS if need to detect long-click after click released:
document.addEventListener("mousedown", longClickHandler, true);
document.addEventListener("mouseup", longClickHandler, true);
let startClick = 0;
function longClickHandler(e){
if(e.type == "mousedown"){
startClick = e.timeStamp;
}
else if(e.type == "mouseup" && startClick > 0){
if(e.timeStamp - startClick > 500){ // 0.5 secound
console.log("Long click !!!");
}
}
}
May need to use timer if need to check long-click while clicking. But for most case after release click is enought.
For me it's work with that code (with jQuery):
var int = null,
fired = false;
var longclickFilm = function($t) {
$body.css('background', 'red');
},
clickFilm = function($t) {
$t = $t.clone(false, false);
var $to = $('footer > div:first');
$to.find('.empty').remove();
$t.appendTo($to);
},
touchStartFilm = function(event) {
event.preventDefault();
fired = false;
int = setTimeout(function($t) {
longclickFilm($t);
fired = true;
}, 2000, $(this)); // 2 sec for long click ?
return false;
},
touchEndFilm = function(event) {
event.preventDefault();
clearTimeout(int);
if (fired) return false;
else clickFilm($(this));
return false;
};
$('ul#thelist .thumbBox')
.live('mousedown touchstart', touchStartFilm)
.live('mouseup touchend touchcancel', touchEndFilm);
You can check the time to identify Click or Long Press [jQuery]
function AddButtonEventListener() {
try {
var mousedowntime;
var presstime;
$("button[id$='" + buttonID + "']").mousedown(function() {
var d = new Date();
mousedowntime = d.getTime();
});
$("button[id$='" + buttonID + "']").mouseup(function() {
var d = new Date();
presstime = d.getTime() - mousedowntime;
if (presstime > 999/*You can decide the time*/) {
//Do_Action_Long_Press_Event();
}
else {
//Do_Action_Click_Event();
}
});
}
catch (err) {
alert(err.message);
}
}
You can use jquery Touch events. (see here)
let holdBtn = $('#holdBtn')
let holdDuration = 1000
let holdTimer
holdBtn.on('touchend', function () {
// finish hold
});
holdBtn.on('touchstart', function () {
// start hold
holdTimer = setTimeout(function() {
//action after certain time of hold
}, holdDuration );
});
like this?
target.addEeventListener("touchstart", function(){
// your code ...
}, false);

Categories

Resources