variable reassignment problem in JS, braking my head trying to understand - javascript

I'm building my own custom made image slideshow, here is a code so far:
function slideSwitch() {
var images = new Array('Aerodynamics.jpg','ABC_news.jpg','yep.jpg');
var currentImage = 0;
var newImage = 'url(images/'+images[currentImage]+')';
$('.inner_img').css('background-image',newImage).animate({opacity:1.0},4000,function(){
if (currentImage != images.length-1){
currentImage++;
} else {
currentImage = 0;
};
$(this).animate({opacity:0.0},4000);
});
};
function interval(){
setInterval(slideSwitch,1000);
};
interval();
Problem is, when interval triggers slideSwitch() function again, the variable newImage holds with the same value when it triggered for the first time. Can you please tell me what am I doing wrong. I also tryed to place variables outside the function, gives me the same result.

thats bc currentImage is assigned to zero every time the function is called.
You should put currentImage into a greater scope and take the assignment outside of the function slideSwitch
var currentImage = 0;
function slideSwitch()
{
//same thing, but lose the line: var currentImage = 0
}
function interval()
{
//unchanged
}
interval();
Btw, the following block:
if (currentImage != images.length-1){
currentImage++;
}
else{
currentImage = 0;
};
can be simplfied to
currentImage = (currentImage + 1) % images.length;

That's because you redeclare var currentImage = 0; inside the method every time you call it.
Either use jQuery's .data() api to store it in the related DOM element or declare it outside the method
var currentImage = 0;
function slideSwitch() {
//code
}

Pull currentImage out of your slideSwitch function and it should work fine. your interval is calling:
var currentImage = 0;
which right there resets it.

Related

Because my dynamic title is not displayed correctly?

I have a question about my JS test code. I need it to show each interval of 1500 the next character, but for some reason I do not see where they are automatically multiplied, until the browser is bugged. I share the code here:
<title>Minuevotitulodeprueba</title>
<script type="text/javascript">
var i=1;
var LegitTitle = document.title;
function ChangeTitle(){
document.title = LegitTitle.substring(0,i);
i++;
if(i>LegitTitle.length)
i = 0;
setInterval('ChangeTitle()',1500);
}
ChangeTitle()
</script>
I am a new developer I beg for mercy xdd
There are two issues with your code
The first parameter to the setInterval function shouldn't be a string, but a function --> setInterval(ChangeTitle,1500);. It would work though with the string (expression) version, but that is not recommended.
You shouldn't use the setInterval inside a function that itself is called itself in the setInterval unless you know what you are doing
Put it outside of the function ...
var i = 1;
var LegitTitle = document.title;
function ChangeTitle(){
document.title = LegitTitle.substring(0,i);
i++;
if (i > LegitTitle.length) {
i = 0;
}
console.log(document.title)
}
setInterval(ChangeTitle,1500);
<title>Minuevotitulodeprueba</title>
... or alternatively use setTimeout instead of setInterval
var i = 1;
var LegitTitle = document.title;
function ChangeTitle(){
document.title = LegitTitle.substring(0,i);
i++;
if (i > LegitTitle.length) {
i = 0;
}
console.log(document.title)
setTimeout(ChangeTitle, 1500);
}
ChangeTitle()
<title>Minuevotitulodeprueba</title>
Only issue you had is you used setInterval instead of setTimeout... Simple swap and the code works fine.
var i = 1;
var LegitTitle = document.title;
function ChangeTitle() {
document.title = LegitTitle.substring(0, i);
console.log(document.title)
i++;
if (i > LegitTitle.length)
i = 0;
setTimeout('ChangeTitle()', 1500);
}
ChangeTitle()
<title>Minuevotitulodeprueba</title>
You set a new interval each time you call the function, but the iteration calls the function on an interval not a timeout. Therefore you can avoid this problem by declaring the iteration outside of the function call.
var i=1;
var LegitTitle = document.title;
function ChangeTitle(){
document.title = LegitTitle.substring(0,i);
if(i>LegitTitle.length) {
i = 0;
}
console.log('i = ' + i);
console.log('Title = ' + document.title);
i++;
}
ChangeTitle();
setInterval(ChangeTitle,1500);
<title>Minuevotitulodeprueba</title>

Why does the second loop execute before the first loop?

so this might be a repost, but I don't really know how to explain my second problem.
I have this code:
var paragraphsArray = new Array();
function setParagraphs(offSet)
{
offSet = offSet * 12;
for (var i = 1; i < 13; i++)
{
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', {idd: parX}).done(function(paragraph)
{
//clear paragraph1 div
document.getElementById("paragraph1").innerHTML = "";
//create p elements
var pElem = document.createElement("p");
pElem.setAttribute("id", "pEntry"+i);
document.getElementById("paragraph1").appendChild(pElem);
$("pEntry"+i).text(paragraph);
});
}
}
edited: I removed the second loop because it was unnecessary, for some reason the p element creation starts on i==13, which is the extra one that shouldn't even do.
for some reason the second loop executes first, so the paragraphArray is printed out as undefined. I managed to "fix" the order with the setTimeout() function, BUT I still get the undefined message, instead of the value. In the first loop the value is printed out fine, but if I try and put it in a $("p").text(paragraph); I also get undefined. So although I was right about the execution order, the problem is still there!
Because first is in ajax call, declare paragraphsArray in global space and use a callback function, try this:
*Updated
var paragraphsArray = [];
function setParagraphs(offSet) {
offSet = offSet * 12;
var request = 0;
for (var i = 1; i < 13; i++) {
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', {idd: parX}).done(function(paragraph) {
request++;
paragraphsArray[request] = paragraph;
console.log(paragraphsArray[request]);
if (request === 12) {
alert('first');
callback();
}
});
}
}
function callback() {
for (var i = 1; i < 13; i++) {
console.log(paragraphsArray[i]);
}
alert('second');
}
Run the second loop inside of the first loop.
function setParagraphs (offSet) {
//paragraphs
var testing = 0;
var paragraphsArray = new Array();
offSet = offSet * 12;
for (var i=1;i<13;i++) {
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
for (var i=1;i<13;i++) {
console.log(paragraphsArray[i]);
alert('second');
}
});
}
}
$.get is async function. 1st cycle will just send requests and wouldn't wait for response, so 2nd cycle will start right after first, without getting response of $.get function. Thats why console.log(paragraphsArray[i]); in 2nd cycle shows undefined.
You only can handle response in first cylce.
You can use $("p").text(paragraph); only like in this example:
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
$("p").text(paragraph);
});
You can't use variables, which are assigned in function
function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
$("p").text(paragraph);
}
outside of this function.
To achieve what you want you have to use another approach.
HTML will be:
<div id='paragraphs'>
</div>
JS code:
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
$("#results").append("<p>"+paragraph+"</p>")
});
You should use ~ this code. I just show you approach.

How can I make this function loop with javascript?

function argsToArray(args) {
var r = []; for (var i = 0; i < args.length; i++)
r.push(args[i]);
return r;
}
argsToArray(document.getElementsByTagName('img')).forEach(function(img) {
img.src = img.src.split('VTlibOlte8YCb').join('X0X810D0' + Math.floor((Math.random()*10)+1));;
});
I tried adding setInterval(argsToArray,500); at the end but that seem to have broken things.
This is quite archaic and will probably crash the browser, but for this experiment it might just work.
function reloadPage()
{
location.reload();
}
setInterval(reloadPage,.5);
I assume from using native forEach that you're targeting IE9+, so instead of manually pushing the collection contents into an array you could just:
function argsToArray(args) {
return Array.prototype.slice.call(args)
}
The rest of the code looks perfectly workable, maybe there's something wrong with the split() or join() arguments. Please explain what are you trying to achieve here.
Adding setInterval(argsToArray,500) would just call your first function without any arguments, you should use an anonymous function or pass arguments into the setInterval/setTimeout function (see MDN).
So you want to do something like this?
window.onload=function() {
var imgs = document.images;
var tId = setInterval(function() {
for (var i=0;i<imgs.length;i++) {
var img = imgs[i];
var val = 'X0X810D0' + (Math.floor(Math.random()*10)+1);
img.src = img.src.replace(/VTlibOlte8YCb/g,val);
}
},1000);
}
which is designed replace the src of each image every second - but actually only once since there is no more VTlibOlte8YCb to replace after the first time
Here is one that does replace the value each time
Live Demo
window.onload=function() {
var imgs = document.images;
var oldVal = new RegExp(/VTlibOlte8YCb/g);
var val = 'X0X810D0' + (Math.floor(Math.random()*10)+1);
var tId = setInterval(function() {
for (var i=0;i<imgs.length;i++) {
var img = imgs[i];
val = 'X0X810D0' + (Math.floor(Math.random()*10)+1);
img.src = img.src.replace(oldVal,val);
oldVal = new RegExp("/"+val+"/g");
}
},200);
}

Javascript setInterval not making it into function

Ok Im trying to do a setInterval into a sub function and its not making it in there...my alert is not firing off because of this:
var doneVar= 0;
var groupsVar= 4;
var interval = setInterval(process_chunk, 1000);
var $myTree= $("#myTree");
var chunkLength = myArray.length / groupsVar;
process_chunk = function() {
alert("we are after chunk");
var arrayChunk = myArray.slice(doneVar*chunkLength, (doneVar + 1)*chunkLength);
//alert("we are in function!!");
$.each(arrayChunk, function(key, item){
$myTree.jstree("uncheck_node", "#"+item);
});
doneVar += 1;
if (doneVar === groupsVar) {
interval.clearInterval();
}
}
process_chunk has not been assigned a value yet, when you pass it into setInterval. Move the line:
var interval = setInterval(process_chunk, 1000);
To right before (and right after the anonymous function is assigned to process_chunk):
doneVar += 1;
Or if you are looking for hoisting the function then use a function declaration rather than an expression:
function process_chunk() {
Both versions will solve your problem.
You need to declare the function before using it.
Put
process_chunk = function() { ... });
Before
var interval = setInterval(process_chunk, 1000);
If you are only using the function from the interval use this (my preferred method, your way is not wrong)
var doneVar= 0;
var groupsVar= 4;
var $myTree= $("#myTree");
var chunkLength = myArray.length / groupsVar;
var interval = setInterval(function() {
alert("we are after chunk");
var arrayChunk = myArray.slice(doneVar*chunkLength, (doneVar + 1)*chunkLength);
//alert("we are in function!!");
$.each(arrayChunk, function(key, item){
$myTree.jstree("uncheck_node", "#"+item);
});
doneVar += 1;
if (doneVar === groupsVar) {
interval.clearInterval();
}
},1000);
that should do it, doing it this way and defining the function within the interval prevents many problems, like in this case you need to defined the function before you set it in an interval. Here is another version keeping your style.
var doneVar= 0;
var groupsVar= 4;
var $myTree= $("#myTree");
var chunkLength = myArray.length / groupsVar;
var process_chunk = function() {
alert("we are after chunk");
var arrayChunk = myArray.slice(doneVar*chunkLength, (doneVar + 1)*chunkLength);
//alert("we are in function!!");
$.each(arrayChunk, function(key, item){
$myTree.jstree("uncheck_node", "#"+item);
});
doneVar += 1;
if (doneVar === groupsVar) {
interval.clearInterval();
}
}
var interval = setInterval(process_chunk, 1000);
I guess one other thing I noticed just now, you use process_chuck and not var process_chuck witch can cause problems too. Fixed in second answer, not applicable in first.

Calling Multiple functions simultaneously

I'm trying to call two different functions for two different HTML elements at the same time, but the second function isn't being read at all. I'm also trying to use the id to specify which corresponding elements to grab data from. Here's what I have:
function changeImage(id)
{
var s = document.getElementById('showcase');
var simg = s.getElementsByTagName('img');
var slen = simg.length;
for(i=0; i < slen; i++)
{
simg[i].style.display = 'none';
}
$('#' + id).fadeIn('slow', 0);
function createComment(jim)
{
//alert('hello?');
var d = document.getElementById('description');
var dh = document.getElementsByTagName('p');
var dlen = dh.length;
//alert(dh);
for(i=0; i < dlen; i++)
{
alert(dh);
dh[i].style.display = 'none';
}
$('#' + jim).fadeIn('slow', 0);
}
It appears you are missing the closing bracket} at the end of your changeImage function.
Also you could shorten your script substantially using jQuery:
function changeImage(id)
{
$('#showcase img').hide();
$('#' + id).fadeIn('slow');
}
function createComment(jim)
{
$('#description p').hide();
$('#' + jim).fadeIn('slow');
}
Also, I'm not sure why you have a zero inside the fadeIn() function? If you want the img/p to show instantly, just use .show()

Categories