Set innerHTML of box to element of one of multiple arrays - javascript

I'm trying to create a website (for fun) that will be an Ultimate Frisbee strategy tutorial (unimportant, but if you were curious, that's what it'll be).
I want the user to be able to select a topic, and then I will be using jQuery to create a moving diagram of a field, but for now, I am trying to have multiple JavaScript arrays, and when the user hits the button "Next", a < p > tag's innerHTML will change to an element of that array.
However, I want to be able to use only one function in order to cycle through any possible array of instructions. If this made any sense, I'm impressed. If you do know what I mean and have any ideas, please tell me. Here's the code below. It all works except for currentNumber, or much more likely currentArray.
var basicManGuide = new Array();
basicManGuide[0] = "First, we will look at the handlers. The handlers are the two people who will typically have the disc.";
basicManGuide[1] = "Volvo";
basicManGuide[2] = "BMW";
var currentNum = 0;
document.getElementById("basicMan").onclick = function() {
var currentArray = basicManGuide.slice();
document.getElementById("menuStuff").style.display = "none";
document.getElementById("buttons").style.display = "block";
document.getElementById("players").style.display = "block";
document.getElementById("description").innerHTML = currentArray[currentNum];
++currentNum;
}
document.getElementById("cancel").onclick = function() {
document.getElementById("menuStuff").style.display = "inline";
document.getElementById("buttons").style.display = "none";
document.getElementById("players").style.display = "none";
}
document.getElementById("next").onclick = function() {
document.getElementById("description").innerHTML = currentArray[currentNum];
++currentNum;
}

currentArray is only in the click handler for basicMan (local scoped). Move that variable outside of the click handler for it to be available to the other events as a global variable.
Obviously, there other areas that need to be addressed, but this should answer your question. (E.g., why slice the array when you are not passing in indices to slice?)
var basicManGuide = new Array();
basicManGuide[0] = "First, we will look at the handlers. The handlers are the two people who will typically have the disc.";
basicManGuide[1] = "Volvo";
basicManGuide[2] = "BMW";
var currentNum = 0;
var currentArray = basicManGuide.slice(); // <-- this was moved.
document.getElementById("basicMan").onclick = function() {
document.getElementById("menuStuff").style.display = "none";
document.getElementById("buttons").style.display = "block";
document.getElementById("players").style.display = "block";
document.getElementById("description").innerHTML = currentArray[currentNum];
++currentNum;
}
document.getElementById("cancel").onclick = function() {
document.getElementById("menuStuff").style.display = "inline";
document.getElementById("buttons").style.display = "none";
document.getElementById("players").style.display = "none";
}
document.getElementById("next").onclick = function() {
document.getElementById("description").innerHTML = currentArray[currentNum];
++currentNum;
}

Related

InnerHTML dissapearing on setInterval Function

I have written a simple script and it's job is to change a innerHTML of a random element in one section of the page. Somehow when I call the function, and set it to fire every 1 second, when innerHTML of a specific element is changed, it doesn't stay that way , it just clears itself and moves on to another element. Can anyone help me with this. Here is the code, thanks in advance.
window.onload = function() {
var box1 = document.getElementById("one");
var box2 = document.getElementById("two");
var box3 = document.getElementById("three");
var box4 = document.getElementById("four");
var box5 = document.getElementById("five");
var box6 = document.getElementById("six");
var box7 = document.getElementById("seven");
var box8 = document.getElementById("eight");
var headingArray = ["RAVE", "RUN", "PAINT"];
var iconArray = ["ion-usb", "ion-android-walk", "ion-android-color-palette"];
var paragraphArray = ["Wanna good time? <br> Check out nearest party centres","Check out running tracks", "Ckeck out painting places"];
var boxArray = [box1,box2,box3,box4,box5,box6,box7,box8];
var heading = document.createElement("h2");
var icon = document.createElement("i");
var paragraph = document.createElement("p");
function getRandomNumberForContent() {
var randomHeading = Math.round(Math.random()*2) + 0;
return randomHeading;
}
function getRandomNumberForBox() {
var randomNumber = Math.round(Math.random()*7) + 0;
return randomNumber;
}
function changeBox() {
var random = getRandomNumberForContent();
heading.innerHTML = headingArray[random];
icon.className = "icon "+iconArray[random]+" big";
paragraph.innerHTML = paragraphArray[random];
var randomNum = getRandomNumberForBox();
boxArray[randomNum].innerHTML = "";
boxArray[randomNum].appendChild(heading);
boxArray[randomNum].appendChild(icon);
boxArray[randomNum].appendChild(paragraph);
}
setInterval(changeBox,1000);
}
You are somewhat moving the element to the new div each time the function is called, because you are assigning as a child the same element, not a copy of it.
You should create the new element inside the changeBox function.
That's the answer. If you create it outside the function, they will be a unique element that you are assigning either to one div or another.
I assume that it moves to another element because you append the same elements somewhere else. You could clone the elements when you append them:
boxArray[randomNum].appendChild(heading.cloneNode(true));
boxArray[randomNum].appendChild(icon.cloneNode(true));
boxArray[randomNum].appendChild(paragraph.cloneNode(true));

JSHint returning odd errors

I have the following script that i created with some help from the people here on stacks for creating a calculator and updating the DOM correspondingly. I recently have changed my editor to one that has JSHint. I has given me some odds errors which I'm hoping someone could provide insight into.
The main one is "Don't make functions with in a loop" That is referring to the .addEventListener array push. Why is this a problem and why should I be doing it this way?
var currentFunction = [];
function pushToArray(v){
currentFunction.push(v);
addtoScreen(v);
}
function addtoScreen(vTag){
var screen = document.getElementById("screen");
if(currentFunction.length == 1){
var newCalc = document.createElement("p");
newCalc.className = "calc";
var opInt = document.createElement("span");
opInt.innerHTML = vTag;
newCalc.appendChild(opInt);
screen.appendChild(newCalc);
}else if(vTag == "="){
var opInt = document.createElement("span");
opInt.innerHTML = vTag;
}else{
var opInt = document.createElement("span");
opInt.innerHTML = vTag;
newCalc = screen.lastChild;
if(newCalc){
newCalc.appendChild(opInt);
}else{
screen.appendChild(opInt);
}
}
}
var numbers = document.getElementsByTagName("button");
for(var i = 0; i < numbers.length; i++){
if(numbers.item(i).id != "equalButton"){
numbers.item(i)
.addEventListener("click", function(){pushToArray(this.value);});
}
}
The function will be constructed on every iteration if it is within the loop. Declare the function outside the loop and call it within the loop.
Or you can add loopfunc : true tag for jshint ignore.

Adding a counter to a prev/next image slideshow(javascript/css only)?

I have created a "prev/next" slideshow using javascript, now I want to add a counter(1/10, 2/10, 3/10...) beside my "prev/next" buttons but nothing seemed to work.
This is my first time attempting to make a website, I know nothing about jQuery, so please stick with html+javascript if possible. Here is my script
var image = new Array(
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg")
var imgNumber=1
var numberOfImg=2
function previousImage(){
if(imgNumber>1){
imgNumber--
}
else{
imgNumber = numberOfImg
}
document.slideImage.src = image[imgNumber-1]
}
function nextImage(){
if(imgNumber < numberOfImg){
imgNumber++
}
else{
imgNumber = 1
}
document.slideImage.src = image[imgNumber-1]
}
if(document.images){
var image1 = new Image()
image1.src = "http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg"
var image2 = new Image()
image2.src = "http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg"
}
Script+html: http://jsfiddle.net/nLHY9/5/
(Prev/Next buttons seem not to be working on this----they work fine when I launched them from laptop to browser.)
you could have used some existing javascript image sliders, for example, sliderman slider, for your current code, you can do like, add an element like span, to hold the count, and you could add a function like:
function changeCounter(cur, total) {
document.getElementById("counter").innerHTML = cur + "/" + total;
}
and call it in your previousImage() and nextImage() functions, as in this demo jsfiddle
There are many pure css slideshows that are beautiful and can do impressive things. However, as you try to support older browsers, the pure css slideshows get less and less impressive or even impossible. JavaScript is the most flexible and powerful way to go. That being, I wanted to help you clean up your code. I only had a few minutes, so this is a quickly thrown together plugin, but it should get you on the right track.
First, a few notes on your code:
//you're missing semicolons everywhere. ";"
/* "var image" is very unclear.
* it's an array, so it should be plural "images"
* there aren't images in this array - it's image urls or sources
* instead of "new Array" you could just use "[]"
*/
var image = new Array(
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg")
var imgNumber=1 //the name doesn't mean anything. I have to assume that you mean "currentImgNumber" or something to that effect
var numberOfImg=2 //this could be determined by checking the length of your array - myArray.length
And here's my exampe plugin:
Live demo here (click).
/***** This section is how you use the plugin. I start writing with the usage and then I make it mean something *****/
window.onload = function() { //when the page is loaded
var fooElem = document.getElementById('foo'); //get an element where we will attach the plugin
var foo = Object.create(slideshow); //create a new slideshow object
foo.create({ //create a slideshow with the given options
element: fooElem, //the element where the slideshow will be
sources: [ //image urls
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/_MG_7747.jpg",
"http://i990.photobucket.com/albums/af24/callmeaaaaj/AJ/1109163s.jpg"
]
});
//we can make more of these and with different options
var barElem = document.getElementById('bar');
var bar = Object.create(slideshow);
bar.create({
element: barElem,
sources: [
"http://eggboss.com/wp-content/uploads/2013/09/The-Gentleman-233x300.png",
"http://fc07.deviantart.net/fs71/f/2013/040/8/a/profile_picture_by_classy_like_a_sir-d5uf426.jpg"
]
});
};
/**** now let's create the plugin and make it work as it is used above *****/
var slideshow = {
currentIndex: 0,
imgs: [],
create: function(options) {
options.element.className+= ' slideshow'; //add a class to the main element for styling
this.imgs = this.getImgs(options.sources); //make img html
var controls = this.getControls(); //make controls
//add the html to the element from the options
var frag = document.createDocumentFragment();
this.imgs.forEach(function(img) {
frag.appendChild(img);
});
frag.appendChild(controls);
options.element.appendChild(frag);
},
getImgs: function(sources) {
var imgs = [];
sources.forEach(function(src, i) {
var img = document.createElement('img');
img.src = src;
imgs.push(img);
if (i > 0) {
img.style.display = 'none'; //hide all but first image
}
});
return imgs;
},
getControls: function() {
var that = this; //so that we can access "this" within the click functions
var controls = document.createElement('div');
controls.className = 'controls';
var counter = document.createElement('span');
counter.className = 'counter';
this.setCounter(counter);
var prev = document.createElement('a');
prev.textContent = 'Prev';
prev.className = 'prev';
prev.addEventListener('click', function() {
newIndex = (that.currentIndex) ? that.currentIndex-1 : that.imgs.length-1;
that.changeImg(newIndex, counter);
});
var next = document.createElement('a');
next.textContent = 'Next';
next.className = 'next';
next.addEventListener('click', function() {
newIndex = (that.currentIndex !== that.imgs.length-1) ? that.currentIndex+1 : 0;
that.changeImg(newIndex, counter);
});
controls.appendChild(prev);
controls.appendChild(next);
controls.appendChild(counter);
return controls;
},
changeImg: function(newIndex, counter) {
this.imgs[this.currentIndex].style.display = 'none';
this.imgs[newIndex].style.display = 'inline';
this.currentIndex = newIndex;
this.setCounter(counter);
},
setCounter: function(counter) {
counter.textContent = (this.currentIndex+1)+' / '+this.imgs.length;
}
};

localStorage clearing when I use split()

I want to create an array of names based on localStorage variable called "names". I use the String.split() to detect a new line which seems to work well, but not if I refresh the page more than once.
var names = localStorage.names;
if (!names) {
textArea.style.display = "block";
mybutton.style.display = "block";
} else {
textSplit = localStorage.names.split(/\n/);
copyInput1.innerHTML = textSplit[0];
copyInput2.innerHTML = textSplit[1];
copyInput3.innerHTML = textSplit[2];
}
document.getElementById("textArea").focus();
var showText = function() {
var text = textArea.value;
localStorage.names = text;
textSplit = localStorage.names.split(/\n/);
copyInput1.innerHTML = textSplit[0];
copyInput2.innerHTML = textSplit[1];
copyInput3.innerHTML = textSplit[2];
}
mybutton.onclick = showText;
clearbutton.onclick = localStorage.clear();
Any help appreciated.
You are executing clear() on localStorage which explains why it clears:
clearbutton.onclick = localStorage.clear();
Change this to:
clearbutton.onclick = localStorage.clear;
This way you're referencing the function instead.

Need help passing a single array value to an attached function on a dynamically created element

I'm having trouble putting an array's value into the function call of an added event on a dynamically created element.
So here's the hard-coded version that works just fine:
var parent_item = document.getElementById("developers_container");
var part = document.createElement('div');
part.id = "developer_A";
part.name = "developer_A";
part.className = "developer_block_un";
part.onmouseover = function() { hilight_dev('A',true)};
part.onmouseout = function() { hilight_dev('A',false)};
parent_item.appendChild(part);
var parent_item = document.getElementById("developer_A");
var part = document.createElement('span');
part.id = "developer_title_A";
part.name = "developer_title_A";
part.className = "developer_un";
part.innerHTML = "John Doe";
part.onclick = function() { select_dev('A')};
parent_item.appendChild(part);
Basically what this does is create a listing of users for selecting. Each user's listing has mouseover, mouseoff and onclick events. The meat of the above code is currently being duplicated for every user.
I want to replace the duplication with an array-based function:
var dev_id = new Array();
var dev_fn = new Array();
var dev_ln = new Array();
document.getElementById("developers_container").innerHTML = "";
dev_id[0] = "A";
dev_fn[0] = "John";
dev_ln[0] = "Doe";
dev_id[1] = "B";
dev_fn[1] = "John";
dev_ln[1] = "Smith";
dev_id[2] = "C";
dev_fn[2] = "John";
dev_ln[2] = "Jones";
dev_id[3] = "D";
dev_fn[3] = "John";
dev_ln[3] = "Yougetthepoint";
document.getElementById("developers_container").innerHTML = "";
for(var i = 0; i < dev_id.length; i++)
{
var parent_item = document.getElementById("developers_container");
var part = document.createElement('div');
part.id = "developer_"+dev_id[i];
part.name = "developer_"+dev_id[i];
part.className = "developer_block_un";
part.onmouseover = function() { hilight_dev(dev_id[i],true)};
part.onmouseout = function() { hilight_dev(dev_id[i],false)};
parent_item.appendChild(part);
var parent_item = document.getElementById("developer_"+dev_id[i]);
var part = document.createElement('span');
part.id = "developer_title_"+dev_id[i];
part.name = "developer_title_"+dev_id[i];
part.className = "developer_un";
part.innerHTML = dev_fn[i]+"<BR>"+dev_ln[i];
part.onclick = function() { select_dev(dev_id[i])};
parent_item.appendChild(part);
}
Every bit of that is working just fine, save for the added events. Where "dev_id[i]" is being used within the function code (as in "part.onmouseover = function() { hilight_dev(dev_id[i],true)};"), it doesn't seem to be doing anything. The event fires off and the function is called, but the variable that's being passed is coming through as "undefined" instead of that user's id like it should be.
I'm hoping someone here knows how to get this to work. Googling was not very helpful, and this is one of those silly little issues that's cost me half a day trying to figure out. Any and all help is greatly appreciated.
Thanks
part.onmouseover = function(i) {
return function() { hilight_dev(dev_id[i],true) }
}(i)
The variable i that you have in the loop is undefined at the time the function is invoked, you need to form a closure over it in order to keep it's value. Please refer to "JavaScript, the Good Parts" by Douglas Crockford for a detailed explanation on this
Err.. after Neil's comment.. yes.. i is not undefined.. it will always be the length of dev_id.. in any case, it's not what the op wants :)

Categories