On-change/click firing even though no changes where made - javascript

I'm trying to fire off a function when the drop down option is selected, but I don't want to have inline JavaScript within the HTML. For some reason when I run the script a change/click is registered automatically. Why?
JSFiddle: http://jsfiddle.net/nysteve/QHumL/22/
var time = new Date();
var timestamp = time.toString("hh:mm:ss");
//create color from time stamp and print within div
function timeToHexColor(){
var showlist = document.getElementById("board").innerHTML +=
"#" + timestamp.split(":").join("") + "<br/>";
}
//Print colors based on time interval
function Colors(interval) {
this.interval = interval;
switch (this.interval) {
case 'second':
x = setInterval(timeToHexColor,1000);
setTimeout(stopColors, 5000);
break;
case 'minute':
x = setInterval(timeToHexColor,60000);
setTimeout(stopColors, 5000);
break;
case 'hour':
x = setInterval(timeToHexColor,60000*60);
setTimeout(stopColors, 5000);
break;
case 'day':
x = setInterval(timeToHexColor,60000*1440);
setTimeout(stopColors, 5000);
break;
default:
}
}
//For demo purposes manually kill priting after 5 seconds
function stopColors() {
clearInterval(x);
}
//Activate printing by selecting an option.
function generateColors(interval){
document.getElementById("options").onclick = Colors(interval);
/*same result with onchange
I even sent the JSFiddle settings per this link:
http://bit.ly/1gev7zR*/
}
generateColors('second');

You can't attach an event listener like that, that calls Colors function immediately.
You can wrap it in a function or you can use addEventListener,
function generateColors(interval){
document.getElementById("options").onclick = function() {
Colors(interval);
}
}
Second method,
function generateColors(interval) {
var el = document.getElementById("options");
el.addEventListener("click", function () {
Colors(interval);
});
}
Updated DEMO

Related

Trigger second click function only when first click function is finish

here is my situation,
I'm triggering some functions on click like this:
on first click, trigger function A.
On second click, trigger function B,
On third click, trigger function C,
etc
etc
All the click are on the same div ( body).
However, I would like the second click to trigger only one the first function is finish. ( all the functions are some animations)
Then the thrid click, to trigger only when the second function is finish, etc, etc.
I'm using the code below to have multi click:
var clickCounter = 0;
$("#body").click(function() {
clickCounter++;
switch (clickCounter) {
case 1:
showpanel();
setTimeout(function() {
hidepanel();
}, 1820);
setTimeout(function() {
movetotop();
}, 1820);
setTimeout(function() {
movetotopheight();
}, 1820);
setTimeout(function() {
nav();
}, 1820);
break;
case 2:
centralbutton();
break;
case 3:
footerarea();
break;
case 4:
side();
break;
}
});
Any pointers / help to achieve this will be really fantastic !!
Thanks so much
You can do something like this by updating the counter in the functions when the function is done, while running set counter to 0 so no action will be triggered.
<div id="body">
<h1>Demo</h1>
</div>
var clickCounter = 1;
function showpanel() {
//Set counter 0 so no action is started
clickCounter = 0;
//Do animation and stuff and after set counter to the right step.
setTimeout(function(){
clickCounter = 2;
}, 5000);
}
function centralbutton() {
//After 5 seconds this function can be used
alert('STEP 2');
}
$("#body").click(function() {
console.log('test');
switch (clickCounter){
case 1:
showpanel();
break;
case 2:
centralbutton();
break;
case 3:
footerarea();
break;
case 4:
side();
break;
}
});
https://jsfiddle.net/3u177cs3/
In each function you could attach a specific CSS class to the div, e.g. named by the last function executed. For example at the end of function A append the class "aFinished". Then when performing a click check for the existing classes on the div and by that pick the right function to be executed.
This way you would not even need a clickcounter variable.
var clickCounter = 1;
function showpanel() {
console.log("pan")
//Set counter 0 so no action is started
clickCounter = 0;
//Do animation and stuff and after set counter to the right step.
setTimeout(function(){
clickCounter = 2;
}, 5000);
$("#body").addClass("aFinished")
}
function centralbutton() {
console.log("cen")
//After 5 seconds this function can be used
alert('STEP 2');
$("#body").removeClass("aFinished")
$("#body").addClass("bFinished")
}
$("#body").click(function() {
console.log('click');
if ($("#body").hasClass("aFinished")) {
centralbutton();
}
else if ($("#body").hasClass("bFinished")) {
footerarea();
}
else if ($("#body").hasClass("cFinished")) {
side();
}
else {
showpanel();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="body">
<h1>Demo</h1>
</div>

hide and show div every x time AngularJS

I'm having troubles to hide and show a div that works as an alert to my application.
Currently I'm using the $interval for make this a permanent hide and show action, but the result I'm expecting is that the DIV remains visible X time and then hide the same X time.
Here is how I0'm doing it now:
function showNotification(idNotification) {
$('[id*=noti_]').addClass('dis_none');
$('#noti_' + idNotification).removeClass('dis_none');
}
function hideNotification() {
// $('#noti_' + idNotification).addClass('dis_none');
$('[id*=noti_]').addClass('dis_none');
}
function checkCalendar() {
var tomorrow = moment().add(1, "d").format("YYYY-MM-DD");
WebApiFactory.GetShiftPeriod("BodyShop", "2017-11-07").then(function (data) {
// WebApiFactory.GetShiftPeriod("BodyShop", tomorrow).then(function (data) {
if(data[0].TargetPlantValue === 0){
showNotification("alert");
}
});
}
function notifications(type, time) {
switch (type) {
case "calendar":
// checkCalendar();
$interval(function () {
checkCalendar();
console.log("Active");
},time * 1000);
$interval(function () {
hideNotification();
console.log("Hide");
}, time * 1001);
break;
}
}
Thanks for the help.
Not sure what are you trying to achieve, but if you want to show the dialog for some 'x' time, and then hide it, you shouldn't start both intervals at the same time. Just wait when the dialog is shown and then start a timer for hiding it.
For example if you need to hide the timer after a '100' ms.
function notifications(type, time) {
switch (type) {
case "calendar":
$interval(function () {
checkCalendar();
$timeout(hideNotification, 100);
}, time * 1000);
break;
}
}
Also be aware that I used a $timeout directive here. It's almost the same as $interval but will be invoked only once.
how can I make that the time that the div is shown is the same as the
time when is hide
It's a bit trickier, so let's use another algorithm.
There we just have a single $interval, but keep a current state isNotificationActive and show/hide the element according to this state.
Also be aware that I use $interval.cancel to stop a previous launched interval, if you have one.
var notificationInterval = null,
isNotificationActive = false;
function notifications(type, time) {
switch (type) {
case "calendar":
$interval.cancel(notificationInterval);
notificationInterval = $interval(updateNotificationState, time * 1000);
break;
}
}
function updateNotificationState() {
if(isNotificationActive) {
//hide the element here;
} else {
//show the element here;
}
isNotificationActive = !isNotificationActive;
}
I would do something like this ...
Make your notification element(s) "responsible" for hiding themselves, as follows :
function showNotification(idNotification, hideAfter) {
var $el = $('#noti_' + idNotification);
$timeout.cancel($el.data('timoutRef')); // kill latent auto-hide (if scheduled)
$el.removeClass('dis_none'); // show
if(hideAfter) {
// Schedule auto-hide after `hideAfter` milliseconds,
// and keep a reference to the timeout so it can be cleared.
$el.data('timoutRef', $timeout(function() {
$el.addClass('dis_none'); // hide
}), hideAfter);
}
}
Now adjust checkCalendar() and notifications()
function checkCalendar() {
WebApiFactory.GetShiftPeriod("BodyShop", "2017-11-07").then(function (data) {
if(data[0].TargetPlantValue === 0) {
// Make sure the value passed below is one half the total cycle time
showNotification("alert", 1000/2); // show immediately, hide after 1/2 second
}
});
}
function notifications(type, time) {
switch (type) {
case "calendar":
// Here, everything can be nice and simple
$interval(checkCalendar, time * 1000); // total cycle time
break;
}
}
Providing your various notification elements don't try to occupy the same real-estate on screen, you (probably) don't need to worry about hiding other notifications.
If the notification elements do try to occupy the same real-estate, you need to consider reducing their number to just one.

Chrome Extensions: Javascript not not running clearInterval();

I'm trying the make a chrome extension in javascript. So far, my popup.js looks like this:
let bg;
let clock;
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('button1').addEventListener('click', butClicked);
bg = chrome.extension.getBackgroundPage();
//clock = document.getElementById("label1");
});
let timeStamp;
let isClockRunning = false;
function butClicked() {
let test = bg.getURL();
document.getElementById('test').innerHTML = test;
timeStamp = new Date();
isClockRunning = !isClockRunning;
runCheckTimer();
}
function runCheckTimer() {
var handle;
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}
function updateClock() {
let seconds = bg.returnTimeSince(timeStamp);
document.getElementById("label1").innerHTML = "Seconds: " + seconds;
}
The program works just fine when I click the button once; it starts the timer. But when I click the button the second time, timeStamp gets set to 0, but the updateClock keeps running at the same interval; the interval doesn't get cleared even though I'm toggling the isClockRunning boolean. It's almost as if javascript is forgetting to run the else if part in runCheckTimer(). How can I fix this?
EDIT: On a sidenote, am I doing the timer thing the right way? Or is there a better way to do it? I basically want a timer to keep ticking every second since you've pressed the button, and then when you click it again it'll stop and reset to 0.
You have scoped handle to runCheckTimer. When runCheckTimer starts, it will create a new handle every time.
Move handle outside of the function.
var handle;
function runCheckTimer() {
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}

setInterval time becomes faster after every cycle

Hi I am trying to track the time spent by user on a webpage. So I have written the following javascript to do so.
The script starts tracking the time when the window becomes focused and then pauses if the user moves to some other tab or minimises the window.
here is the fiddle:
following is the code:
$(function(){
var count = 0;
var interval;
var ispaused=false;
function setPause(){
ispaused=true;
}
function unpause(){
ispaused=false;
}
$(window).on("blur focus", function(e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case "blur":
setPause();
clearInterval(interval);
break;
case "focus":
unpause();
var interval = setInterval(
function(){
if(!ispaused) {
$('#timer').text(count += 1);
}
},1000
);
break;
}
}
$(this).data("prevType", e.type);
});
});
The timer starts when you focus the area and pauses when you blur out, but the timer becomes faster after every cycle of focus and blur. No idea why that is happening. Please help !
I checked the fiddle you provided and found out that you are storing the interval variable on a local variable i had tried to fix the problem to see if it is working and had updated the fiddle here:
http://jsfiddle.net/9fzd1dap/1/
This is the updated Script
$(function () {
var count = 0;
var interval; //This is the global interval variable
var ispaused = false;
function setPause() {
ispaused = true;
}
function unpause() {
ispaused = false;
}
$(window).on("blur focus", function (e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case "blur":
setPause();
break;
case "focus":
unpause();
clearInterval(interval);
//I removed the var keyword from the line below to prevent dual declarations.
interval = setInterval(
function () {
if (!ispaused) {
$('#timer').text(count += 1);
}
}, 1000
);
break;
}
}
$(this).data("prevType", e.type);
});
});
What happened is that the global interval variable is not being populated and the local interval (inside the function) variable is the one that gets populated. I've already tested it on the updated fiddle and seems to work fine ;)

jQuery animation function timing

Feel like I'm overlooking the obvious here...
I've got several vars set up like so:
var productOne = function () {
$(".product2").fadeIn(200).animate({"right": "+=75px"}, 500, "easeOutElastic").delay(3000).fadeOut(200).css("right", "0");
$(".product-text.two").fadeIn(200).delay(3500).fadeOut(200);
}
var productTwo = function () {
$(".product2").fadeIn(200).animate({"right": "+=75px"}, 500, "easeOutElastic").delay(3000).fadeOut(200).css("right", "0");
$(".product-text.two").fadeIn(200).delay(3500).fadeOut(200);
}
etc...Then I want to fire them in order, like so, and loop back to the first:
window.setInterval(function() {
$(productTwo);
$(productThree);
//and so on
}, 5000);
but they all fire at the same time. How can I put a specific number of ms between each function call?
You need to fire each one off from the end of the previous one. So productOne would setTimeout to call productTwo, and productRwo would setTimeout to call productThree, and productThree to call productOne.
ETA Example:
var productOne = function () {
$(".product2").fadeIn(200).animate({"right": "+=75px"}, 500, "easeOutElastic").delay(3000).fadeOut(200).css("right", "0");
$(".product-text.two").fadeIn(200).delay(3500).fadeOut(200);
setTimeout(productTwo, 5000);
}
var productTwo = function () {
$(".product2").fadeIn(200).animate({"right": "+=75px"}, 500, "easeOutElastic").delay(3000).fadeOut(200).css("right", "0");
$(".product-text.two").fadeIn(200).delay(3500).fadeOut(200);
setTimeout(productThree, 5000);
}
If you want animations to fire in order then you should call the next one from the complete callback function. Example:
$(".product2").fadeIn(200).animate(
{"right": "+=75px"},
500,
"easeOutElastic",
function() {
// call your next animation here. Add delays here if you want...
}).delay(3000).fadeOut(200).css("right", "0");
// initial product count
var product = 1;
// function which select which animation to call
function fire_product( product ) {
switch ( product ) {
case 1:
$(productTwo);
break;
case 2:
$(productTwo);
break;
case 3:
$(productThree);
break;
}
// go to next product next time
product++;
// reset to first product when we reach the last product
if (product > 3) product = 1;
// self-call this function again
setTimeout( function() {
fire_product( product );
}, 5000);
}
// call the function for the first time with desired parameter
fire_product( 1 );

Categories