setInterval / clearInterval Issue inside it's scope - javascript

I have the following code, and it works fine until i hit the the #play button. I'm assuming it's because the var intID is set in another place and it's not in the same scope when i window.clearInterval() it... how do I fix this? BTW, this is the Google Maps API Version 3
function intervalTrigger(){
return window.setInterval(function(){
placement++;
if(placement >= markers.length){placement = 0;}
google.maps.event.trigger(markers[placement], "click");
}, 5000);
};
var intID = intervalTrigger();
$('#map_canvas').click(function(){window.clearInterval(intID);});
$('a[href=#nextmarker]').live('click',function(){
placement++;
if(placement >= markers.length){placement = 0};
google.maps.event.trigger(markers[placement], "click");
window.clearInterval(intID);
$('a[href=#pause]').replaceWith('Play');
return false;
});
$('a[href=#prevmarker]').live('click',function(){
placement--;
if(placement == -1){placement = markers.length-1}
google.maps.event.trigger(markers[placement], "click");
window.clearInterval(intID);
$('a[href=#pause]').replaceWith('Play');
return false;
});
$('a[href=#play]').live('click',function(){
$('a[href=#play]').replaceWith('Pause');
var intID = intervalTrigger();
return false;
});
$('a[href=#pause]').live('click',function(){
window.clearInterval(intID);
$('a[href=#pause]').replaceWith('Play');
return false;
});

Remove the var from your #play click handler to the following:
$('a[href=#play]').live('click',function(){
$('a[href=#play]').replaceWith('Pause');
intID = intervalTrigger();
return false;
});
That will correctly set the value of the global var intID so it's available to the other event handlers.

You're creating a new variable with that var keyword, if you want to reference the variable in the outer scope, you need to take it out, like this:
$('a[href=#play]').live('click',function(){
$('a[href=#play]').replaceWith('Pause');
intID = intervalTrigger();
return false;
});
Otherwise it's just creating a new variable inside that .live() handler that doesn't go anywhere...but since you want to set the variable you already have, leave off the var.

Related

Passing jquery variable to another function

Not sure why this isn't working, and it's returning as an object/undefined.
I have a variable outside above the doc.ready:
var video_box_original_link = '';
I have a link that I click on inside the ready function which grabs the info fine:
$(document).on('click', '.youtube_video', function(video_box_original_link){
var my_game_name = $('a.game_title_link').attr('name');
var my_game_platform = $('a.game_platform_link').attr('name');
video_box_original_link = "/"+my_game_platform+"/"+my_game_name+"/videos";
});
And I have a function that I'm trying to pass to this which is also in the doc.ready down below:
$(document).on('click', '.popblock_box', function(e, video_box_original_link){
window.history.pushState("vidPage", "vidPopped", ""+ video_box_original_link +"");
}
Is this should be fine?
The "e" is for something else in the script which is not necessary to show.
You couldn't pass variable to callback like you do like you do in function(video_box_original_link) you should define it in global scope then just use it :
var video_box_original_link = '';
$(document).on('click', '.youtube_video', function(){
var my_game_name = $('a.game_title_link').attr('name');
var my_game_platform = $('a.game_platform_link').attr('name');
video_box_original_link = "/"+my_game_platform+"/"+my_game_name+"/videos";
});
$(document).on('click', '.popblock_box', function(e){
window.history.pushState("vidPage", "vidPopped", ""+ video_box_original_link +"");
}
Hope this helps.

Issues with resetting an interval

I have two elements. When I click the left element I want to change the right element into another element. If the left element is not clicked again the right element changes back to its original state. I've been able to make that happen, but I want to be able to click on that element again and have the interval I set restart. I feel like I'm close.
var changeImage = function(){
if(imageClicked == true){
var Img = document.getElementById('Img');
Img.setAttribute('src', "./images/img2.jpg");
imageTimeout = setTimeout(function(){
var Image = document.getElementById('Image');
Image.setAttribute('src', './images/image.jpg');
}, 3000)
imageClicked = false;
return imageTimeout;
} else {
imageClicked = true;
resetTimer();
}
}
var resetTimer = function(){
clearTimeout(imageTimeout);
window.setTimeout(imageTimeout, 3000);
}
random_image.addEventListener("click", changeImage, false);
The problem is that you are calling setTimeout(function ,delay) without a callback function.
The issue is in this line in the else block:
window.setTimeout(imageTimeout, 3000);
where imageTimeout is not a function, but the id of the timeout.
You need to create a separate function (let's call it timeoutFunction for example) with the timeout code and call it every time you invoke setTimeout.
After you create that function, and call it in the if block as well, change that line to:
imageTimeout = window.setTimeout(timeoutFunction, 3000);
from your code:
function timeoutFunction(){
var flowerImage = document.getElementById('flowerP');
flowerImage.setAttribute('src', './images/flowers.jpg');
}
by the way, you can define that flowerImage variable outside that function once instead of searching the DOM every time.
In order to clear a timeout, you need to call the clearTimeout function with the reference to the object that was returned by window.setTimeout. So you need to change your code to:
var resetTimer = function() {
clearTimeout(timeoutId);
createjs.Sound.stop(playSoundD);
timeoutId = window.setTimeout(imagetimeout, 3000);
console.log("I've been reset");
}

Understanding module design patterns in javascript

I am trying to understand module patterns in Javascript so that i can separate my code into different modules and use them where required.
var messageHandler = (function(){
var el;
var display = function(a){
if(a=='error'){
el = $('.error');
el.css('display','block');
}
else if (a==='success'){
el = $('.success');
el.css('display','block');
}
else if (a=='warning'){
el = $('.warning');
el.css('display','block');
}
else if (a=='danger'){
el = $('.danger');
el.css('display','block');
}
registerClick(el.find('.close'));
return this;
}
function registerClick(p_el){
p_el.bind('click',function(){
hide();
});
}
var hide = function(){
el.css('display','none');
}
return {
display: display,
hide: hide
}
})();
window.messageHandler = messageHandler;
messageHandler.display('warning');
So, I have four different classes in css for different types of messages.The close class is for a small cross button on the top right to close the message.
This works fine till i call the function only once.When i do this
messageHandler.display('warning');
messageHandler.display('success');
Now both the messages close button have been bind to the success close button because el gets overwritten.
How to achieve it keeping the code reusable and concise.
The problem here is that you have a closure variable el that you are overwriting every time display() is called. The hide() function uses whatever is the current value of el at the time it is called, so overwriting el is a problem.
If you want to have "static" functionality like this display() method, you need to avoid shared state.
As #Bergi points out in the comments, you can eliminate the shared el and modify hide() to take an element as input:
var messageHandler = (function(){
var el; // delete this
var display = function(a){
var el; // add this
function registerClick(el){
el.bind('click', function(){
hide(p_el);
});
}
function hide(el){
el.css('display','none');
}
You could also modify hide to make use of the current event properties, and then just have:
function registerClick(el){
el.bind('click', hide);
}
function hide(event){
$(event.target).css('display','none');
}
Cleaned up version including the auto-hide discussed in the comments:
var messageHandler = (function(){
var display = function(a){
var el = $('.' + a);
el.css('display', 'block');
var hideAction = function () { el.css('display', 'block'); };
var token = setTimeout(hideAction, 5000);
el.find('.close').bind('click', function () {
hideAction();
clearTimeout(token);
});
return this;
}
return {
display: display
}
})();

Keeping variables between function executions (Javascript)

I have a JavaScript function that runs every time one of the many links is clicked. The functions first checks what the id of the link clicked is, then it runs an if stement. depending on the id of the link, different variables are defined.
All this works, but the problem is that some links define one variable while other links define another, I need to keep the variables defined in previous executions of the function defined for other executions of the function.
An example follows:
$(document).ready(function()
{
$(".sidebar a").click(function(event) {
event.preventDefault()
var targetID = $(this).attr("data-target")
$("#" + targetID).attr("src", $(this).attr("href"))
var element = $(this).attr("class")
if (element == "submit") {
var submit = $(this).attr("user")
alert("1")
} else if (element == "view") {
var view = $(this).attr("user")
alert("2")
}
})
window.history.replaceState({}, 'logs', '/file/path?submit=' + submit + '&' + 'view=' + view)
})
Thanks
You can use an outer function which does nothing but declare some variables and return an inner function. The inner function can access the variables from the outer scope which stay the same for every call of the function.
Example
var next = (function() {
var value = 0;
function next() {
return value++;
}
}());
console.log(next());
console.log(next());
console.log(next());
Live demo
http://jsfiddle.net/bikeshedder/UZKtE/
Define the variables in an outer scope:
$(document).ready(function () {
var submit;
var view;
$(".sidebar a").click(function (event) {
event.preventDefault();
var targetID = $(this).attr("data-target");
$("#" + targetID).attr("src", $(this).attr("href"));
var element = $(this).attr("class")
if (element == 'submit') {
submit = $(this).attr("user")
alert("1")
} else if (element == 'view') {
view = $(this).attr("user")
alert("2")
}
});
});
Create var submit and view outside of the function so it has a global scope.
You can store arbitrary data on a matched element with JQuery's .data() function.
Example:
$(this).data("submit", $(this).attr("user")); // set a value
var submit = $(this).data("submit"); // retrieve a value
This places the data in the context of JQuery's knowledge of the element, so it can be shared between function calls and even between different events.

ClearInterval Is Not Stopping

I'm trying to use setInterval to check for hash value change when a person clicks on a submit button. When the submit button is hit, the page will not change at all. Only the hash value is changed. I want to use the setInterval to repeatedly look for the hash value until it goes to page2 (in case the form values entered are incorrect). Once page2 is detected, it will clear the setInterval, but this part is not working.
var chkHash;
var hashval = window.location.hash;
var sb = document.getElementById("submitButton").onclick = function() {
startHash();
}
function checkHash() {
hv = window.location.hash;
if (hashval !== hv ) { hashval = hv; }
if(/page2/i.test(hv)) {
clearHash();
}
}
function startHash() {
chkHash = setInterval('checkHash()', 5000);
}
function clearHash() {
clearInterval(chkHash);
}
Some improvements:
//Inside startHash, change:
chkHash = setInterval('checkHash()', 5000);
//to
clearInterval(chkHash); //Don't create multiple timers
chkHash = setInterval(checkHash, 5000);
I also recommend to add var before hv = window.location.hash inside function checkHash, so that the variable doesn't leak to the global scope.

Categories

Resources