I have a social stream that I want to update with setInterval. SetInterval needs to be stopped when someone is leaving a comment or a reply otherwise it clears the content of the textarea because it is nested inside the content being updated.
I'm attempting to use this code, modified, from another answer, but it is failing in that it won't stop the timer after the first cycle of the setInterval timer.
HTML...
<div id="social_stream_content">
<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer"></textarea>
</div>
JS...
function auto_load(){
data = '<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer..."></textarea>';
$("#social_stream_content").html(data);
alert("auto_load invoked");
}
var myInterval;
var interval_delay = 10000;
var is_interval_running = false; //Optional
$(document).ready(function(){
auto_load(); //Call auto_load() function when document is Ready
//Refresh auto_load() function after 10000 milliseconds
myInterval = setInterval(interval_function, interval_delay);
$('textarea').focus(function () {
console.log('focus');
clearInterval(myInterval); // Clearing interval on window blur
is_interval_running = false; //Optional
}).focusout(function () {
console.log('focusout');
clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet
if (!is_interval_running) //Optional
myInterval = setInterval(interval_function, interval_delay);
});
});
interval_function = function () {
is_interval_running = true; //Optional
// Code running while textarea is NOT in focus
auto_load();
}
Edit: I've updated the code to include everything as tested on JSfiddle. The timer will stop if you immediately set focus to the comment textarea after closing the alert at document ready.
After removing focus, and the first cycle of the interval timer completes, the timer will not stop again. The focus event seems to stop firing.
Is this because the comment textarea is nested inside the content area that is updating? I'm pulling my hair out. If I remove the nesting, it works as expected.
My caveat is that the comment textareas are always going to be nested inside of the social stream's content div, for obvious reasons.
So, to update the question further: Is there a way to get the interval timer to stop on textarea focus using jquery, while the focused element is nested inside the updating element? Why does the focus event stop firing after the first interval completes?
Edit: The complete JS code, working coreectly, with Jeremy Klukan's solution incorporated, for anyone doing the same type of project.
WORKING JS:
function auto_load(){
data = '<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer..."></textarea>';
$("#social_stream_content").html(data);
alert("auto_load invoked");
}
var myInterval;
var interval_delay = 10000;
var is_interval_running = false; //Optional
$(document).ready(function(){
auto_load(); //Call auto_load() function when document is Ready
//Refresh auto_load() function after 10000 milliseconds
myInterval = setInterval(interval_function, interval_delay);
$('body').on('focus', '#social_stream_content textarea', function (event) {
console.log('focus');
clearInterval(myInterval); // Clearing interval on window blur
is_interval_running = false; //Optional
}).on('focusout', '#social_stream_content textarea', function(event) {
console.log('focusout');
clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet
if (!is_interval_running) //Optional
myInterval = setInterval(interval_function, interval_delay);
});
});
interval_function = function () {
is_interval_running = true; //Optional
// Code running while textarea is NOT in focus
auto_load();
}
You can detect focus and blur for a textarea
using addEventListener
(events: focus and blur).
You can end a setInterval()
using clearInterval()
passing anintervalID
.
Below a simple working example showing the principal (in vanilla JavaScript).
Basically:
textarea
timer stops.textarea
timer starts again.Documentation:
WindowTimers.clearInterval()
WindowTimers.setInterval()
You may also find of interest Document.activeElement.
window.app = {
timerRef: null,
timerStart: function() {
this.timerRef = setInterval(function() {
//alert("Hello");
console.log('refresh stream');
}, 2000);
},
timerStop:function(){
clearInterval(this.timerRef);
},
txtAreaListenFocus: function() {
var txtArea = document.getElementById('txtArea');
txtArea.addEventListener('focus', function(event) {
this.timerStop();
console.log('focus');
}.bind(this));
},
txtAreaListenBlur: function() {
var txtArea = document.getElementById('txtArea');
txtArea.addEventListener('blur', function(event) {
this.timerStart();
console.log('blur');
}.bind(this));
},
start: function() {
this.timerStart();
this.txtAreaListenFocus();
this.txtAreaListenBlur();
}
};
window.app.start();
<textarea id="txtArea" rows="4" cols="50">
Some content here
</textarea>
Jquery version below. You can use .focusout() and .focusin():
$(document).ready(function(){
window.app = {
timerRef: null,
timerStart: function() {
this.timerRef = setInterval(function() {
//alert("Hello");
console.log('refresh stream');
}, 2000);
},
timerStop:function(){
clearInterval(this.timerRef);
},
txtAreaListenFocus: function() {
$('#txtArea').focusin(function(event) {
this.timerStop();
console.log('focus');
}.bind(this));
},
txtAreaListenBlur: function() {
$('#txtArea').focusout(function(event) {
this.timerStart();
console.log('blur');
}.bind(this));
},
start: function() {
this.timerStart();
this.txtAreaListenFocus();
this.txtAreaListenBlur();
}
};
window.app.start();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="txtArea" rows="4" cols="50">
Some content here
</textarea>
Regarding specifically your code in question, I have fix it in the working example below.
$(document).ready(function() {
var myInterval;
var interval_delay = 1000;
var is_interval_running = false; //Optional
var interval_function = function() {
is_interval_running = true; //Optional
console.log('refresh stream');
// Code running while comment textarea is not in focus
//auto_load();
};
//auto_load(); //Call auto_load() function when DOM is Ready
//Refresh auto_load() function after 1000 milliseconds
myInterval = setInterval(interval_function, interval_delay);
$('#textarea').focus(function() {
clearInterval(myInterval); // Clearing interval on window blur
is_interval_running = false; //Optional
}).focusout(function() {
clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet
if (!is_interval_running) //Optional
myInterval = setInterval(interval_function, interval_delay);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="textarea" rows="4" cols="50">
Some content here
</textarea>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With