Javascript: move new element after createElement - javascript

I have created a zombie img in my banner div but I can't get the img to move to the left after it has been created.
createZombie function is on a timer:
createZombieTimer = window.setInterval(createZombie, 1000);
That is in an init() that loads with the body.
function createZombie(){
var imgElem = document.createElement("img");
imgElem.src = "img/zombie_walk_right.gif";
var newZom = document.getElementById('banner').appendChild(imgElem);
newZom.style.height = "40px";
newZom.style.width = "auto";
newZom.style.display = "block";
newZom.style.marginLeft = "50px";
var zomPos = parseInt(newZom.style.marginLeft);
if (zomPos > 0) {
newZom.style.marginLeft = (zomPos + 50) + "px";
}
}

Since it's clear from the comments now what you want to do, I'll post it here as the answer.
You can do this with plain javascript as well. What you will have to do, is use setInterval(). This will execute a function every second, in which you can update the position of the elements.
Example:
// Function to move the zombie by 50 pixels
function moveZombie()
{
// Select the zombie element (will need additional logic to select all of them, just an example)
zomElement = document.getElementById('zombie1');
zomPos = parseInt(zomElement.style.marginLeft);
zomElement.style.marginLeft = (zomPos + 50) + 'px';
}
// Call this function every second
setInterval(moveZombie(), 1000);

Related

JS for -loop always use last element - scope issues

var url_array = ["ulr1", "ulr2", "ulr3", "ulr4", "ulr5"];
var img = document.createElement('img');
for (i = 0; i < url_array.length; i++){
var div = document.createElement('div');
div.setAttribute("id", "div"+i);
document.getElementById('main').appendChild(div);
document.getElementById('div'+i).style.width = ImageWidth+5+"px";
document.getElementById('div'+i).style.height = ImageHeight+5+"px";
console.log("\ncreate all the DIVs. \nFor loop count: "+i);
img.src = loadImage(url_array[i], ImageWidth, ImageHeight);
try{throw img}
catch(c_img) {
document.getElementById('div'+i).appendChild(c_img);
console.log("after load, and append, in Catch: "+img.src);
console.log("div NR = "+document.getElementById('div'+i).id);
console.log(document.getElementById('div'+i).childNodes.length);
} //catch
} // FOR
function loadImage(URL, h, w)
{
console.log("loadImage callaed with URL = "+URL);
return url = URL+Date.now().toString(10);
}
For-Loop is supposed to retrieve urls address of an images (from camera) and append them to DIV. DIV and IMGs are created on the fly. Problem is that only last DIV become image holder.
I am using catch-try to force execute code immediately so each separate Div+i will have distinctive image. Also construction like this one (immediately invoked function expression):
(function(){
something here;
})();
for creating "private" scope gives no hope. Either "Let" - which supposed to define variable locally is not helping. *My knowledge here is limited and I'm relying on data found on web site (can give link later if it is not against rules).
Output of console.log() is not helping much.
Everything goes as it should, except for the childNodes.length which is 1 for each for-loop iteration - that means each DIV have its IMG child I guess... If so - why I can't see them?
I feel I am close to what I want to achieve - using Intervals() refresh each DIV with new camera snapshot, but I need to solve this current issue.
Example of code ready to use:
js.js:
var url_array = [
"https://images.pexels.com/photos/104827/cat-pet-animal-domestic-104827.jpeg",
"https://images.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg",
"https://images.pexels.com/photos/617278/pexels-photo-617278.jpeg"
];
var ImageWidth = 640;
var ImageHeight = 480;
var img = document.createElement('img');
for (i = 0; i < url_array.length; i++){
var div = document.createElement('div');//.setAttribute("id", "div0");
div.setAttribute("id", "div"+i);
document.getElementById('main').appendChild(div);
document.getElementById('div'+i).style.width = ImageWidth+5+"px";
document.getElementById('div'+i).style.height = ImageHeight+5+"px";
var color = ((Math.floor(Math.random() * (16777215)) + 1).toString(16)); // from 1 to (256^3) -> converted to HEX
document.getElementById('div'+i).style.background = "#"+color;
document.getElementById('div'+i).style.width = ImageWidth+5+"px";
document.getElementById('div'+i).style.height = ImageHeight+5+"px";
console.log("\ncreate all the DIVs. \nFor loop count: "+i);
img.src = loadImage(url_array[i], ImageWidth, ImageHeight);
try{throw img}
catch(c_img) {
document.getElementById('div'+i).appendChild(c_img);
console.log("after load, and append, in Catch: "+img.src);
console.log("div NR = "+document.getElementById('div'+i).id);
console.log(document.getElementById('div'+i).childNodes.length);
} // catch
} // FOR
function loadImage(URL, h, w)
{
console.log("loadImage callaed with URL = "+URL);
return url = URL+"?auto=compress&h="+h+"&w="+w;
}
HTML:
<html>
<head>
<meta charset="utf-8">
<STYLE>
div#main {
padding: 5px;
background: black;
}
</STYLE>
</head>
<body>
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "js.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
<div id="main"></div>
</body>
</html>
The problem is that your
var img = document.createElement('img');
is outside the loop - you're only ever creating one img. When appendChild is called on an element that already exists in the DOM (such as on the second, third, fourth, etc iteration), the element gets removed from its previous location and inserted into the new location.
Create the image inside the loop instead, and try not to implicitly create global variables - when declaring new variables, always use let or const.
Also, when you do
var div = document.createElement('div');
you have a reference to the div you just created - there's no need to assign an id to it in order to select it with
document.getElementById('div'+i)
in below lines in the same scope. Instead, just keep referencing the div:
const ImageWidth = 200;
const ImageHeight = 200;
const main = document.getElementById('main');
var url_array = ["ulr1", "ulr2", "ulr3", "ulr4", "ulr5"];
for (let i = 0; i < url_array.length; i++){
const img = document.createElement('img');
const div = document.createElement('div');
main.appendChild(div);
div.style.width = ImageWidth+5+"px";
div.style.height = ImageHeight+5+"px";
img.src = loadImage(url_array[i], ImageWidth, ImageHeight);
div.appendChild(img);
}
console.log(main.innerHTML);
function loadImage(URL, h, w) {
return URL+Date.now().toString(10);
}
div#main {
padding: 5px;
background: black;
}
<div id="main">
</div>

Make a multiple objects with javascript and png

I'm trying to get a spaceship animation scene with a group of comets going down.
//Create a comet div with img attached to it
var cometScene = function(spaceNo){
var b = document.createElement('div');
b.id = 'cometio';
var cometImage = document.createElement('img');
cometImage.setAttribute('src', 'images/comet1.png');
b.appendChild(cometImage);
document.getElementById('wrap').appendChild(b);
}
//Comet move
function cometMove(){
var comet = document.getElementById('cometio');
var pos = 0;
var interval = setInterval(scene, 3);
function scene(){
if (pos === 1000){
clearInterval(interval);
} else {
pos++;
comet.style.top = pos + 'px';
comet.style.left = pos + 'px';
}
}
setInterval(scene, 3)
}
But when I call a function cometScene(3) I'm not getting 3 similar objects. Also how these objects can be allocated across the whole screen as this is just a single div.
function main(){
var w = document.createElement('div');
w.id = 'wrap';
document.querySelector('body').appendChild(w);
astronautScene();
cometScene();
shaceshipScene();
cometMove();
astronautMove();
}
This it what I would do:
Give the comets a class instead of an id, because there can be more of them.
Because there can be multiple use a loop to iterate through them
To give them the ability to move freely, they need to have position:absolute or something similiar
Don't use the same variable for the position of all comets, because they could be in different positions
To get the current position just parse the currect top and left value to a Number
//Create a comet div with img attached to it
var cometScene = function(spaceNo) {
var b = document.createElement('div');
b.className = 'cometio';
var cometImage = document.createElement('img');
cometImage.setAttribute('src', 'images/comet1.png');
b.appendChild(cometImage);
document.getElementById('wrap').appendChild(b);
}
//Comet move
function cometMove() {
var comets = document.getElementsByClassName('cometio');
for (let i = 0; i < comets.length; i++) {
const comet = comets[i];
comet.style.top = "0px";
comet.style.left = "0px";
comet.style.position = "absolute";
var interval = setInterval(scene, 3);
function scene() {
let x = parseInt(comet.style.left);
let y = parseInt(comet.style.top);
if (x === 1000) {
clearInterval(interval);
} else {
comet.style.top = (1 + x) + 'px';
comet.style.left = (1 + y) + 'px';
}
}
}
//setInterval(scene, 3)don't start the interval twice
}
function main() {
var w = document.createElement('div');
w.id = 'wrap';
document.querySelector('body').appendChild(w);
//astronautScene();
cometScene();
//shaceshipScene();
cometMove();
//astronautMove();
}
main();

Remove div's with almost the same id once a certain top value is reached

So I've got this code to create a rectangular div every 800ms which falls down the screen.
Now I'd like to be able to remove a div once it reaches a certain top value, otherwise it'll
get too cluttered with div's. Now I have no idea how to exactly do that, considering the id's I've given them. I'd also like to know how I could end up removing every single one of those div's once it's game over. This is what I have so far all together: http://student.howest.be/pieter-jan.vandenb1/crossdodger/Game.html. I'm pretty new at javascript so thanks in advance!
var idNumber = 0;
SpawnBlock();
function SpawnBlock()
{
UpdateBlock();
setTimeout(SpawnBlock, 800);
}
function UpdateBlock()
{
var block = document.createElement("div");
block.style.width = "25px";
block.style.height = "25px";
block.style.background = "lightgrey"
block.style.top = "-25px";
block.style.left = Math.random() * 455 + "px";
block.style.position = "absolute";
block.id = "block" + ++idNumber;
//block.speed = 0.5;
sym.$("Stage").append(block);
sym.$("#block"+idNumber).transition({top:"800px"},8000,"linear");
}
It's made in Adobe Edge, hence the "sym." namespace.
This worked for me in a similar environment:
var bl = document.getElementById("block" + (idNumber));
bl.parentNode.removeChild(bl);
var idNumber = 0;
SpawnBlock();
var divblocks = [];
function SpawnBlock()
{
UpdateBlock();
setTimeout(SpawnBlock, 800);
}
function UpdateBlock()
{
var block = document.createElement("div");
block.style.width = "25px";
block.style.height = "25px";
block.style.background = "lightgrey"
block.style.top = "-25px";
block.style.left = Math.random() * 455 + "px";
block.style.position = "absolute";
block.id = "block" + ++idNumber;
//block.speed = 0.5;
sym.$("Stage").append(block);
sym.$("#block"+idNumber).transition({top:"800px"},8000,"linear");
divblocks.push(block.id);
if (divblocks.length > 800)
{
$(divblocks[0]).Remove();
}
}

Stopping setTimeout loop

I have this function to create an animation of dropping box:
function dropBox(y, width, height) {
var img_box = new Image();
img_box.src = 'images/gift_box_small.png';
var box_y_pos = y;
if(y==0)
box_y_pos = y-img_box.naturalHeight;
img_box.onload = function(){
ctx_overlay.save();
ctx_overlay.clearRect(0,0,width,height);
ctx_overlay.drawImage(img_box, (width/2)-(img_box.naturalWidth/2), box_y_pos);
ctx_overlay.restore();
}
box_y_pos += 3;
var loopTimer = setTimeout(function() {dropBox(box_y_pos, width, height)},24);
}
I want to stop the animation when the box reaches a certain Y position and call for other function. I can't have a code to check for Y position before the setTimeout declaration, since it hasn't been declared yet, and I can't have it after, since it'll be unreachable. So how can it be done?
Simply pass pass extra variable of the stop_y position to your function. And call setTimeout() only if box did not reach yet this position:
function dropBox(y, width, height, stop_y) {
var img_box = new Image();
img_box.src = 'http://corkeynet.com/test/images/gift_box_small.png';
var box_y_pos = y;
if(y==0)
box_y_pos = y-img_box.naturalHeight;
img_box.onload = function(){
ctx_overlay.save();
ctx_overlay.clearRect(0,0,width,height);
ctx_overlay.drawImage(img_box, (width/2)-(img_box.naturalWidth/2), box_y_pos);
ctx_overlay.restore();
}
box_y_pos += 3;
if (box_y_pos < stop_y) {
var loopTimer = setTimeout(function() {dropBox(box_y_pos, width, height, stop_y)},24);
}
}
Edited your code here: http://jsfiddle.net/93jwqf2j/

Why does my setInterval function not work second time? (JavaScript)

I made a div and I want to make it animate in a specific direction every 1 second. In the code that I have provided there's a function called resetPosition() don't worry about that, it's from my other js file that I linked in the head section(That works perfectly). I just want to know why setInterval() doesn't work correctly?
Here's my code:-
<!DOCTYPE html>
<html>
<head>
<title>Animtion</title>
<link rel="icon" href="http://3.bp.blogspot.com/-xxHZQduhqlw/T-cCSTAyLQI/AAAAAAAAAMw/o48rpWUeg2E/s1600/html-logo.jpg" type="image/jpg">
<script src="easyJs.js"></script>
<style type="text/css">
div{height:100px; width:100px; background:cyan;}
</style>
</head>
<body onload="">
<div id="demo"></div>
</body>
<script type="text/javascript">
setInterval(function(){var x = new element('demo');
x.resetPosition('absolute', '100px', '10px');}, 1000);
</script>
</html>
Here's easyJs:-
function element(elementId){
this.myElement = document.getElementById(elementId);
this.resetColor = changeColor;
this.resetSize = changeSize;
this.resetBackground = changeBackground;
this.resetPosition = changePosition;
this.resetBorder = changeBorder;
this.resetFontFamily = changeFont;
this.resetFontSize = changeFontSize;
this.resetFontStyle = changeFontStyle;
this.resetZindex = changeZindex;
this.resetClass = changeClass;
this.resetTitle = changeTitle;
this.resetMarginTop = changeMarginTop;
this.resetMarginLeft = changeMarginLeft;
this.resetSource = changeSource;
this.resetInnerHTML = changeInnerHTML;
this.resetHref = changeHref;
this.resetTextDecoration = changeTextDecoration;
this.resetFontWeight = changeFontWeight;
this.resetCursor = changeCursor;
this.resetPadding = changePadding;
this.getValue = getTheValue;
this.getName = getTheName;
this.getHeight = getTheHeight;
}
function changeColor(color){
this.myElement.style.color = color;
}
function changeSize(height, width){
this.myElement.style.height = height;
this.myElement.style.width = width;
}
function changeBackground(color){
this.myElement.style.background = color;
}
function changePosition(pos, x, y){
this.myElement.style.position = pos;
this.myElement.style.left = x;
this.myElement.style.top = y;
}
function changeBorder(border){
this.myElement.style.border = border;
}
function changeFont(fontName){
this.myElement.style.fontFamily = fontName;
}
function changeFontSize(size){
this.myElement.style.fontSize = size;
}
function changeZindex(indexNo){
this.myElement.style.zIndex = indexNo;
}
function changeClass(newClass){
this.myElement.className = newClass;
}
function changeTitle(newTitle){
this.myElement.title = newTitle;
}
function changeMarginTop(top){
this.myElement.style.marginTop = top;
}
function changeMarginLeft(left){
this.myElement.style.marginLeft = left;
}
function changeSource(newSource){
this.myElement.src = newSource;
}
function changeHref(newHref){
this.myElement.href = newHref;
}
function changeInnerHTML(newHTML){
this.myElement.innerHTML = newHTML;
}
function changeTextDecoration(decoration){
this.myElement.style.textDecoration = decoration;
}
function changeFontWeight(weight){
this.myElement.style.fontWeight = weight;
}
function changeFontStyle(style){
this.myElement.style.fontStyle = style;
}
function changeCursor(cursor){
this.myElement.style.cursor = cursor;
}
function changePadding(padding){
this.myElement.style.padding = padding;
}
function getTheValue(){
var theValue = this.myElement.value;
return theValue;
}
function getTheName(){
var theName = this.myElement.name;
return theName;
}
function getTheHeight(){
var theHeight = this.myElement.offsetHeight;
return theHeight;
}
This might help you see what and how. (Scroll down to bottom of code):
Fiddle
// Create a new EasyJS object
var el = new element('demo');
// x and y position of element
var x = 0, y = 0;
// Interval routine
setInterval(function(){
x = x + 1; // Increment x by 1
y = y + 1; // Increment y by 1
// Move element to position xy
el.resetPosition('absolute', x + 'px', y + 'px');
// Add text inside element showing position.
el.resetInnerHTML(x + 'x' + y);
// Run five times every second
}, 1000 / 5);
Explanation of original code:
setInterval(function() {
// Here you re-declare the "x" object for each iteration.
var x = new element('demo');
// Here you move the div with id "demo" to position 100x10
x.resetPosition('absolute', '100px', '10px');
// Once every second
}, 1000);
The HTML div element demo initially has no positioning styling (CSS). As such it is rendered in the default position according to the browser defaults.
In first iteration you change the style option position to absolute. That means you can move it anywhere. Secondly you move it to offset 100x10.
On the second and every iteration after that the element has position set to absolute, and it reside at 100x10. Then you say it should be moved to 100x10 – as in same place as it is.
If you do not change either x or y position (left / top), it will stay at 100x10, no mather how many times you run the loop. Run it 100 times a second for a year and it will still be at 100x10 ;-)
Think about it. Everytime the interval runs, it creates a new instance of element "demo".
This demo variable has all the default values your elements object sets it to (if any), and runs the same function each time. That's why it only moves once.
Hoist your element higher and you won't be re-declaring each interval.
<script type="text/javascript">
var x = new element('demo');
setInterval(function(){
x.resetPosition('absolute', '100px', '10px');}, 1000);
</script>
The problem isn't in the setInterval, because a copypasta'd fiddle of the same expression worked properly, so it's probably either an issue with resetPosition or maybe easyJS, though I doubt the latter.
Also, it's unclear whether demo appears on-page, as it's not added anywhere visibly.
EDIT:
If demo is appended somewhere behind the scenes, it's still piling a new demo on that spot every second

Categories