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));
Related
I'm trying to code a dynamically created select box within a dynamically created div that are both created on load of the page. My attempts to add an onchange Event Listener to the select box only trigger when the page is loaded, how do I go about fixing this? I'm new to both html and JavaScript so my code is intentionally basic. Here is my code:
function createDiv()
{
var div = document.createElement('div');
div.className = 'main-div';
div.id = 'mainDiv';
div.setAttribute('title', 'Main Div');
var divText = document.createTextNode("Select a Number ");
div.appendChild(divText);
var select = document.createElement('select')
select.options[0] = new Option("1");
select.options[1] = new Option("2");
select.options[2] = new Option("3");
select.options[3] = new Option("4");
select.options[4] = new Option("5");
select.options[5] = new Option("6");
select.options[6] = new Option("7");
select.options[7] = new Option("8");
select.options[8] = new Option("9");
select.options[9] = new Option("10");
//select.addEventListener("change", alert("changed!"));
div.appendChild(select);
document.body.appendChild(div);
console.log(div);
}
<body onload = createDiv()>
<h1 id = "heading1">Test</h1>
<br>
<script src="js/main.js"></script>
</body>
The method addEventListener need a function in second parameter, and you didn't pass a function but the result of the alert() function (that is void).
Change: alert("changed!") to
function() {alert("changed!")}
(that can be shortened by () => alert("changed!") since ES6):
function createDiv() {
var div = document.createElement('div');
div.className = 'main-div';
div.id = 'mainDiv';
div.setAttribute('title', 'Main Div');
var divText = document.createTextNode("Select a Number ");
div.appendChild(divText);
var select = document.createElement('select')
for (var i = 1; i <= 10; i++) {
select.options[i] = new Option(i);
}
select.addEventListener("change", function() {alert("changed to "+select.value)});
div.appendChild(select);
document.body.appendChild(div);
}
<body onload = createDiv()>
<h1 id = "heading1">Test</h1>
</body>
I got a working function, but i think it should become a lot smaller and better but i aint seeing it. can someone help me improve this function make it better:
I am making a new li-item in a unordered list. in there there is omse info in 3 divisions who get a class making them float left to eachother.
this is the code i used, its all listed out, it can probly be make a lot better, and i hope to learn to refactor my code more, so help is apriciated.
// making new li item inn <ul>
function addproduction(){
// getting info from form
var startdatum_form = document.getElementById('startdatum').value;
var uren_form = document.getElementById('uren').value;
var ordernummer_form = document.getElementById('ordernummer').value;
// new li element
var newli = document.createElement('li');
newli.setAttribute('class', 'ui-state-default');
var div1 = document.createElement('div');
div1.setAttribute('class', 'div1');
var sortableicon = document.createElement('span');
sortableicon.setAttribute('class', 'ui-icon ui-icon-arrowthick-2-n-s');
// count current li elements in UL:
var number = 0;
var ullist = document.getElementById('sortable');
for(i=0;i< ullist.childNodes.length;i++){
if(ullist.childNodes[i].nodeName=='LI'){
number++;
}
}
newli.setAttribute('id', 'p'+(number+1));
// text node (item x)
var nrText = document.createTextNode('Item ' + (number+1));
div1.appendChild(sortableicon)
div1.appendChild(nrText);
var div2 = document.createElement('div');
div2.setAttribute('class', 'div1');
var indiv1 = document.createElement('div');
indiv1.appendChild(document.createTextNode('Title'));
var indiv2 = document.createElement('div');
indiv2.appendChild(document.createTextNode('Start'));
var indiv3 = document.createElement('div');
indiv3.appendChild(document.createTextNode('End'));
var indiv4 = document.createElement('div');
indiv4.appendChild(document.createTextNode('Uren'));
div2.appendChild(indiv1);
div2.appendChild(indiv2);
div2.appendChild(indiv3);
div2.appendChild(indiv4);
var div3 = document.createElement('div');
div3.setAttribute('class', 'div3');
var indiv5 = document.createElement('div');
indiv5.appendChild(document.createTextNode(ordernummer_form));
var indiv6 = document.createElement('div');
indiv6.appendChild(document.createTextNode(startdatum_form));
var indiv7 = document.createElement('div');
indiv7.appendChild(document.createTextNode('end'));
var indiv8 = document.createElement('div');
indiv8.appendChild(document.createTextNode(uren_form));
div3.appendChild(indiv5);
div3.appendChild(indiv6);
div3.appendChild(indiv7);
div3.appendChild(indiv8);
newli.appendChild(div1);
newli.appendChild(div2);
newli.appendChild(div3);
// add new production to list
document.getElementById('sortable').appendChild(newli);
saveNewEntry( (number+1), ordernummer_form, startdatum_form, uren_form );
}
A small example which could be applied to other parts of your code as well
var startdatum_form = document.getElementById('startdatum').value;
var uren_form = document.getElementById('uren').value;
var ordernummer_form = document.getElementById('ordernummer').value;
could be
var startdatum_form = get_value('startdatum');
var uren_form = get_value('uren');
var ordernummer_form = get_value('ordernummer');
function get_value( field ) {
return document.getElementById(field).value;
}
No matter how hard I am trying to get the right loop using JavaScript for this I fail. As you can see in the code below I have several things repeating an I want to put it in a for loop. But is there actually a way to get all these things into one for loop and how?
As you can see I have: sub1(), push1, "mydiv"+1 and other things repeated... Thank you in advance and sorry cause I am rookie :)
function sub1() {
push1++;
var myfield = document.createElement("textarea");
myfield.name = "rex" + 1 + push1;
var div = document.createElement("div");
div.innerHTML = myfield.outerHTML;
document.getElementById("mydiv"+1).appendChild(div);
}
function sub2() {
push2++;
var myfield = document.createElement("textarea");
myfield.name = "rex" + 2 + push2;
var div = document.createElement("div");
div.innerHTML = myfield.outerHTML;
document.getElementById("mydiv"+2).appendChild(div);
}
Is this what you are looking for?
var push = [];
function sub(num) {
push[num] = (push[num] || 0) + 1;
var myfield = document.createElement("textarea");
myfield.name = "rex" + num + push[num];
var div = document.createElement("div");
div.innerHTML = myfield.outerHTML;
document.getElementById("mydiv"+num).appendChild(div);
}
sub(1);
sub(2);
This question may be a bit long winded but bear with me.
I am trying to update and array every time a user hits the save button.
When they click save an image of a canvas on the page is created.
These DataURI values are kept in an array.
Once the value is saved a thumbnail of sorts is created and added at the bottom of the screen.
Clicking the X icon on those images calls a function to remove the correct image from the array.
The images should then be redrawn with the update array values, thus removing it from the
screen.
I have included images to try and demonstrate:
Image #1 (when save is clicked and image added below):
http://postimg.org/image/cybazwydf/
Image #2 (after closing the on screen images, adding a new image adds the deleted ones again along with the new one):
http://postimg.org/image/gi5pcornl/
That is the issue, that it re-adds the deleted values.
I will post the code for it below:
function getDataUrl () {
var a = document.getElementById("theCanvas");
var context = a.getContext("2d");
var dataURL = a.toDataURL();
save(dataURL);
}
var theImages = new Array();
//Add dataURL to array:
function save(URL) {
theImages.push(URL);
var x = JSON.stringify(theImages);
localStorage.setItem('images', x);
drawImages(x);
}
function drawImages(array){
var array = localStorage.getItem("images");
array = JSON.parse(array);
//If an image is saved, display the saveArea div:
if (array.length > 0){
document.getElementById("saveArea").style.visibility="visible";
}
//Clear the elements that might already be in the div so they don't appear twice:
var theDiv = document.getElementById("saveArea");
while (theDiv.firstChild) {
theDiv.removeChild(theDiv.firstChild);
}
for (var x=0; x < array.length; x++){
//Create image for each value in array:
var divimg = document.createElement("div");
divimg.style.marginRight="10px";
//divimg.style.border = "1px dotted red";
divimg.className = "saveContainer";
divimg.style.width = 300+"px";
divimg.style.padding = 5+"px";
divimg.style.marginRight="10px";
divimg.style.height = 150+"px";
divimg.style.display="inline-block";
divimg.style.marginRight="35px";
document.getElementById("saveArea").appendChild(divimg);
var img = document.createElement("img");
img.src = array[x];
img.width = 300;
img.height = 150;
img.setAttribute("id", "theImageId");
img.style.marginRight="10px";
img.className = "saveImg";
//Add each image to the containing div:
divimg.appendChild(img);
//Create close button:
var close = document.createElement("img");
close.src="close.png";
close.width = 50;
close.height = 50;
close.border = 0;
close.style.position="relative";
close.style.bottom=115+"px";
close.style.right=40+"px";
close.className="closeButton";
//close.style.cssFloat="right";
//close.style.right= 0+"px";
var link = document.createElement("a");
link.href = "#";
link.appendChild(close);
link.nameIndex = x;
//WHEN THE USER CLICKS THE CLOSE ICON:
link.onclick = (function (x) {
var imageNum = this.nameIndex;
alert("You clicked to close image "+(imageNum+1));
//Remove the image:
array.splice(x,1);
alert("The length of this array is: "+array.length);
//Update localStorage:
localStorage.removeItem('images');
array = JSON.stringify(array);
localStorage.setItem('images', array);
drawImages(array);
} );
//Add the close button the the containing div:
divimg.appendChild(link);
//divimg.appendChild(close);
} //End Loop
} //End drawImages();
I've been trying to solve this for hours but no luck..
After removing the image from the array you are not storing it anywhere so the splice result is lost and the array remains the same
array.splice(x,1);
needs to be
array = array.splice(x,1);
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 :)