The new child element contains the parent JS error - javascript

I encountered a little problem. I have:
html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="chart.css">
<script type="text/javascript" src="chart.js"></script>
<title>Chart</title>
</head>
<body>
<div id="lifespan-chart">
<div id="lifespan-chart-content"></div>
</div>
</body>
</html>
javascript:
class Polyline {
constructor(input) {
this.input = input;
this.nodes = this.convertNodes(input["nodes"]);
this.color = input["color"];
this.width = input["width"];
this.height = input["height"];
if (input["fill"] === undefined) {
this.fill = "";
} else {
this.fill = input["fill"];
}
if (input["stroke"] === undefined) {
this.stroke = "black";
} else {
this.stroke = input["stroke"];
}
if (input["stroke_width"] === undefined) {
this.stroke_width = "1.5";
} else {
this.stroke_width = input["stroke_width"];
}
// for (var key in input) {
// console.log(input[key]);
// }
}
changeParams(input) {
if ("nodes" in input) {
this.nodes = this.convertNodes(input["nodes"]);
}
if ("color" in input) {
this.color = input["color"];
}
if ("width" in input) {
this.width = input["width"];
}
if ("height" in input) {
this.height = input["height"];
}
if ("fill" in input) {
this.fill = input["fill"];
}
if ("stroke" in input) {
this.stroke = input["stroke"];
}
if ("stroke_width" in input) {
this.stroke_width = input["stroke_width"];
}
}
convertNodes(list) {
let result = "";
let i = 0;
while (i < list.length) {
result += list[i];
result += ",";
result += list[i+1];
result += " ";
i = i + 2;
}
return result;
}
setSvg() {
this.svg = `
<svg height='${this.height}', width='${this.width}'>
<polyline points='${this.nodes}', style='fill:${this.fill}, stroke:${this.stroke},stroke-width:${this.stroke_width}' />
</svg>
`;
//console.log(this.svg);
}
loadChart() {
var div = document.getElementById('lifespan-chart-content');
div.innerHTML = this.svg;
document.getElementById('lifespan-chart-content').appendChild(div);
}
}
window.addEventListener('load', function() {
input = {
"nodes" : [0,0,50,50,100,100,200,200,300,300,350,350,450,500,550,650],
"color" : "red",
"width" : 500,
"height": 300,
"fill" : "bisque",
"stroke" : "orange",
"stroke_width" : 2
};
p1 = new Polyline(input);
p1.setSvg();
p1.loadChart(); // ??? error on this place
})
And everything is ok, but when I want to add block to html in function loadChart I see an error in console:
Uncaught DOMException: Failed to execute 'appendChild' on 'Node': The new child element contains the parent. at Polyline.loadChart. What I should do to avoid such an error? I commented a place where error occures. Thanks in advance!
EDIT 1 : Forgot to execute setSvg before loadChart, I added it above, now it draws ok, but error is still here. Is it ok?

You are appending the div lifespan-chart-content to itself.
This will append a div with only the svg to lifespan-chart-content
loadChart() {
var div = document.createElement('div');
div.innerHTML = this.svg;
document.getElementById('lifespan-chart-content').appendChild(div);
}

Related

Javascript Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')

I'm trying to make a Farm Clicker game myself with javascript. In other words, as you click the Add Gold button, the player will have more gold and will be able to buy new animals with the gold he has earned. But in my code I come across the following error: script.js:42 Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')
at addGold (script.js:42:54)
at HTMLButtonElement. (script.js:11:42)
What is this error caused by? I leave the codes below.
// global variables
const myContent = document.getElementById("content");
var gold = 0;
let animals = {};
var goldToAdd = 0;
// global functions
function addGoldButton() {
let myButton = document.createElement("button");
myButton.addEventListener("click", () => addGold(1)); // add one
myButton.innerHTML = "Add Gold!";
myContent.appendChild(myButton);
}
function passiveGold() {
if (animals.goats > 0) {
goldToAdd += animals.goats * 5; //50=>5 10=>1
}
if (animals.pigs > 0) {
goldToAdd += animals.pigs * 10; //90=>10 9=>1
}
if (animals.cows > 0) {
goldToAdd += animals.cows * 15; //120=>15 8=>1
}
addGold(goldToAdd);
}
addGoldButton();
function addGold(goldToAdd) {
console.trace();
if (gold = null) {
gold = goldToAdd;
let goldCounter = document.createElement("h2");
goldCounter.id = "goldCounter";
goldCounter.innerHTML = "Gold: " + gold;
myContent.appendChild(goldCounter);
} else {
gold += goldToAdd;
document.getElementById("goldCounter").innerHTML = "Gold: " + gold;
}
// check for events on current gold level
checkGold();
}
function checkGold() {
if (gold >= 50 && document.getElementById("goatBuyButton") == null) {
let buttonBar = document.createElement("div");
buttonBar.id = "buttonBar";
let buyButton = document.createElement("button");
buyButton.id = "goatBuyButton";
buyButton.innerHTML = "Buy Goat (50g)";
buyButton.addEventListener("click", () => buyAnimal("goat"));
myContent.appendChild(buttonBar);
buttonBar.appendChild(buyButton);
}
if (gold >= 90 && document.getElementById("pigBuyButton") == null) {
let buttonBar = document.getElementById("buttonBar");
let buyButton = document.createElement("button");
buyButton.id = "pigBuyButton";
buyButton.dinnerHTML = "Buy Pig (90g)";
buyButton.addEventListener("click", () => buyAnimal("pig"));
buttonBar.appendChild(buyButton);
}
if (gold >= 120 && document.getElementById("cowBuyButton") == null) {
buttonBar = document.getElementById("buttonBar");
let buyButton = document.createElement("button");
buyButton.id = "cowBuyButton";
buyButton.innerHTML = "Buy Cow (120g)";
buyButton.addEventListener("click", () => buyAnimal("cow"));
buttonBar.appendChild(buyButton);
}
function buyAnimal(animal) {
let itemBar = document.getElementById('itemBar');
if (itemBar == null) {
itemBar = document.createElement("div");
itemBar.id != "itemBar";
myContent.appendChildren(itemBar);
}
switch (animal) {
//do something, don't and forget the break;
case "goat":
if (gold >= 50) {
addGold(-50);
if (animals.goats == null) {
animals.goats = 1;
let myElement = document.createElement("div");
myElement.id = "goats";
myElement.innerHTML = "Goat Quantity: " + animals.goats;
itemBar.appendChild(myElement);
} else {
animals.goats += 1;
document.getElementById("goats").innerHTML = "Goat Quantity: " + animals.goats;
}
}
break;
case "pig":
if (gold >= 90) {
addGold(-90);
if (animals.pigs == null) {
animals.pigs = 1;
let myElement = document.createElement("div");
myElement, id = "pigs";
myElement.innerHTML = "Pig Quantity: " + animals.pigs;
itemBar.appendChild(myElement);
} else {
animals.pigs += 1;
document.getElementById("pigs").innerHTML = "Pig Quantity: " + animals.pigs;
}
}
break;
case "cow":
if (gold >= 120) {
addGold(-120);
if (animals.cows == null) {
animals.cows = 1;
let myElement = document.createElement("div");
myElement.id = "cows";
myElement.innerHTML = "Cow Quantity: " + animals.cows;
itemBar.appendChild(myElement);
} else {
animals.cows += 1;
document.getElementById("cows").innerHTML = "Cow Quantity: " + animals.cows;
}
}
break;
default:
console.log("geen dier gevonden");
}
}
// add elements
// start application
setInterval(passiveGold, 5000);
}
<div id="content"></div>
<!--<script src="script.js"></script> script is referenced right before </body> -->
the element goldCounter is never going to be added to your dom, that's why it says "Cannot set properties of null". At line number 33, in the if statement there is an error.
Replace line 33, this
if (gold = null) {
with
if (gold == 0) {
Hope, it helps!!
The null do not equals to 0, so if the gold contents 0, gold==null will return false and try find the element with goldCounter id (but the easyest way if(!gold))
At the passiveGold function, you do not have to check the animals bigger than 0, because n*0=0, so nothing will happen (it just make your code nicer).
And the buyAnimal function's front: not appendChildren (perhaps you just misspelled it)

Javascript Next and Previous images

Code is supposed to show next image when clicking on next arrow and previous image when clicked on previous arrow. It does not work though. (error occurs while assigning img.src=imgs[this.i]; it says Cannot set property 'src' of null
at collection.next) .
Javascript code :
var arr = new collection(['cake.png', 'image2.png', 'image3.png', 'image1.png']);
function collection(imgs) {
this.imgs = imgs;
this.i = 0;
this.next = function(element) {
var img = document.getElementById('element')
this.i++;
if (this.i == imgs.length) {
this.i = 0;
}
img.src = imgs[this.i].src;
}
this.prev = function(element) {
var img = document.getElementById('element');
this.i--;
if (this.i < 0) {
this.i = imgs.length - 1;
}
img.src = imgs[this.i].src;
}
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input type='button' value='<' name='next' onclick="arr.next('mainImg')" />
<img id='mainImg' src="cake.png">
<input type='button' value='>' name='prev' onclick="arr.prev('mainImg')" />
</body>
</html>
Not using jquery. I do not have enough experience in js either. Thank you for your time
You had three mistakes:
You referenced the images as img.src = imgs[this.i].src; and you just had an array of strings, not an array of objects with a src property. img.src = imgs[this.i]; is the correct way to get the URL.
You used
var img = document.getElementById('element');
when you should have used
var img = document.getElementById(element);
element is an argument coming from your onclick event. It holds the id of your image that you should be using. "element" is just a string. You try to find an element with id equal to element which doesn't exist.
Edit: You should also use < and > to represent < and >. Otherwise your HTML might get screwed up. More on that here.
var arr = new collection(['http://images.math.cnrs.fr/IMG/png/section8-image.png', 'https://www.w3.org/MarkUp/Test/xhtml-print/20050519/tests/jpeg444.jpg', "http://saturnraw.jpl.nasa.gov/multimedia/images/raw/casJPGFullS72/N00183828.jpg"]);
function collection(imgs) {
this.imgs = imgs;
this.i = 0;
this.next = function(element) {
var img = document.getElementById(element);
this.i++;
if (this.i >= imgs.length) {
this.i = 0;
}
img.src = imgs[this.i];
};
this.prev = function(element) {
var img = document.getElementById(element);
this.i--;
if (this.i < 0) {
this.i = imgs.length - 1;
}
img.src = imgs[this.i];
};
this.next("mainImg"); // to initialize with some image
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input type='button' value='<' name='next' onclick="arr.next('mainImg')" />
<img id='mainImg' src="cake.png">
<input type='button' value='>' name='prev' onclick="arr.prev('mainImg')" />
</body>
</html>
This is how I'd personally do it:
var myCollection = new Collection([
"http://images.math.cnrs.fr/IMG/png/section8-image.png",
"https://www.w3.org/MarkUp/Test/xhtml-print/20050519/tests/jpeg444.jpg",
"http://saturnraw.jpl.nasa.gov/multimedia/images/raw/casJPGFullS72/N00183828.jpg"
], "mainImg");
document.getElementById("next_btn").onclick = function() {
myCollection.next();
};
document.getElementById("prev_btn").onclick = function() {
myCollection.prev();
}
function Collection(urls, imgID) {
var imgElem = document.getElementById(imgID);
var index = 0;
this.selectImage = function() {
imgElem.src = urls[index];
};
this.next = function() {
if (++index >= urls.length) {
index = 0;
}
this.selectImage();
};
this.prev = function(element) {
if (--index < 0) {
index = urls.length - 1;
}
this.selectImage();
};
// initialize
this.selectImage();
}
<!DOCTYPE html>
<html>
<head>
<title>photos</title>
<script src="photos.js"></script>
</head>
<body>
<input id="next_btn" type='button' value='<' />
<img id='mainImg'>
<input id="prev_btn" type='button' value='>' />
</body>
</html>
Why sending string into arr.next('mainImg') function ?
your img element always have the same id, only change src.
and document.getElementById(element) is also the same img element.
html: <img id='mainImg' src="cake.png">
js: document.getElementById('mainImg')
consider img element as a container, and id is it's identifiler.
var start_pos = 0;
var img_count = document.getElementsByClassName('icons').length - 1;
var changeImg = function(direction){
pos = start_pos = (direction == "next")? (start_pos == img_count)? 0 : start_pos+1 : (start_pos == 0)? img_count : start_pos-1;
console.log(pos)
}
document.getElementById('left').onclick = function(){ changeImg("previous"); }
document.getElementById('right').onclick = function(){ changeImg("next"); }

Ext JS custom Tooltip class not working

I went of Ext's QuickTips to make this custom tooltip, that should show a tooltip when over an element with a 'my_tip' attribute.
For example,
<div class="some class" my_tip="This is my tip text">
When the page is loaded, it adds the following markup to the HTML, which is correct:
<div class="x-layer my_tool_tip_layer" id="ext-gen7" style="position: absolute; z-index: 20000; visibility: hidden; left: -10000px; top: -10000px;">
<div class="my_tool_tip" id="ext-gen8"> </div>
</div>
What should happen is when I hover the mouse over the element with the 'my_tip' attribute, it should update the above div's style attribute and replace &nbsp with the contents of the my_tip class.
Like this:
<div class="x-layer my_tool_tip_layer displayed" id="ext-gen7" style="position: absolute; z-index: 20000; visibility: visible; left: 160px; top: 30px;">
<div class="my_tool_tip" id="ext-gen8">This is my tip text</div>
</div>
I have a css file handling the styling of the tooltip, but my problem now is just getting the html to update to the correct events, which it is not doing.
Below is the javascript for the tooltip. Any help would be very much appreciated.
Thank you
myToolTips=function()
{
var mytt_ext_lyr=null;
var mytt_text_el=null;
var mytt_visible=false;
var mytt_hide_proc=null;
var mytt_show_proc=null;
var mytt_tip_text='';
var mytt_hide_delay = 10000;
var mytt_show_delay = 200;
var mytt_started = false;
var mytt_last_xy = null;
var mytt_mouse_y_offset = 20;
var mytt_track_mouse = false;
var mytt_initialized = false;
var mytt_singleton = null;
var mytt_max_search_depth = 5;
var on_over = function(evt) {
var target = evt.target;
var depth = 0;
while (target && target.nodeType == 1 && !target.getAttribute('my_tip') && depth < mytt_max_search_depth) {
++depth;
target = target.parentNode;
}
if (!target || target.nodeType != 1 || !target.getAttribute('my_tip')) {
if (mytt_visible)
hide();
return;
}
var new_tip = target.getAttribute('my_tip');
if (new_tip != mytt_tip_text && mytt_visible)
hide();
if (target.getAttribute('clip_tip') && target.getAttribute('clip_tip') == 'true') {
for (var i = 0; i < target.childNodes.length; ++i) {
var child = target.childNodes[i];
if (child.scrollWidth <= child.offsetWidth) {
return;
} else {
break;
}
}
}
if (target.getAttribute('clip_tip') && target.getAttribute('clip_tip') == 'this_node') {
if (target.scrollWidth <= target.offsetWidth)
return;
}
var mouse_xy = evt.getXY();
var tip = {mouse_xy: mouse_xy, new_tip: new_tip, target: target}
mytt_show_proc = show.defer(mytt_show_delay, mytt_singleton, [tip]);
mytt_started = true;
};
var on_move = function (evt) {
if (mytt_visible) {
if (mytt_track_mouse) {
var mouse_xy = evt.getXY();
mouse_xy[1] += mytt_mouse_y_offset;
mytt_ext_lyr.setXY(mouse_xy);
}
}
else if (mytt_started)
mytt_last_xy = evt.getXY();
};
var on_out=function(evt) {
hide();
};
var on_click = function(evt) {
var target = evt.target;
var depth = 0;
while (target && target.nodeType == 1 && !target.getAttribute('my_tip') && depth < mytt_max_search_depth) {
++depth;
target = target.parentNode;
}
if (!target || target.nodeType != 1 || !target.getAttribute('my_tip'))
hide();
};
var show=function(mytt) {
var tip=mytt.new_tip;
var mouse_xy=mytt.mouse_xy;
if(mytt_last_xy)
mouse_xy=mytt_last_xy;
if(!mytt_visible) {
if(tip) {
mytt_tip_text=tip;
mytt_text_el.update(mytt_tip_text.replace(/\[\[/g,"<").replace(/\]\]/g,">"));
}
mytt_ext_lyr.show();
mytt_ext_lyr.addClass('displayed');
mytt_visible=true;
if(!mytt_hide_proc)
mytt_hide_proc=setTimeout(hide,mytt_hide_delay);
}
var db=Ext.get(document.body);
var dw=db.getWidth();
var dh=db.getHeight();
if (mytt.target.getAttribute('top_tip') === 'true') {
var telm = Ext.get(mytt.target);
var left = telm.getLeft();
var width_diff = db.getWidth() - (left + mytt_ext_lyr.getWidth());
if (width_diff < 5)
left+=width_diff-15;
mytt_ext_lyr.dom.style.right='';
mytt_ext_lyr.dom.style.top='';
mytt_ext_lyr.dom.style.left=left+'px';
mytt_ext_lyr.dom.style.bottom=(dh-telm.getTop())+'px';
mytt_ext_lyr.sync();
}
else {
mouse_xy[1]+=mytt_mouse_y_offset;
var width_diff=db.getWidth()-(mouse_xy[0]+mytt_ext_lyr.getWidth());
if(width_diff<5)
mouse_xy[0]+=width_diff-15;
mytt_ext_lyr.setXY(mouse_xy);
}
if(mytt_show_proc) {
clearTimeout(mytt_show_proc);
mytt_show_proc=null;
}
};
var hide=function() {
mytt_ext_lyr.hide();
mytt_ext_lyr.removeClass('displayed');
mytt_visible=false;
mytt_started=false;
mytt_last_xy=null;
if(mytt_hide_proc) {
clearTimeout(mytt_hide_proc);
mytt_hide_proc=null;
}
if(mytt_show_proc) {
clearTimeout(mytt_show_proc);
mytt_show_proc=null;
}
};
return {
init:function() {
mytt_singleton=myToolTips;
if(!mytt_initialized) {
if(!Ext.isReady) {
Ext.onReady(myToolTips.init,myToolTips);
return;
}
mytt_ext_lyr=new Ext.Layer({cls:'my_tool_tip_layer',shim:true,constrain:true});
mytt_ext_lyr.fxDefaults={stopFx:true};
mytt_ext_lyr.update('<div class="my_tool_tip"> </div>');
mytt_text_el=mytt_ext_lyr.child('div.my_tool_tip');
mytt_text_el.update(' ');
var doc=Ext.get(document);
doc.on('mouseover',on_over);
doc.on('mouseout',on_out);
doc.on('mousemove',on_move);
doc.on('click',on_click);
mytt_initialized=true;
}
},
ready:function() {
return mytt_initialized;
}
};
}();
// make tooltips work
myToolTips.init();

How to make expand all/collapse all button in this certain script?

i would like to ask for help in a simple task i really need to do at my work (I am a javascript newbie). I made a simple collapsible list with script provided by this guy http://code.stephenmorley.org/javascript/collapsible-lists/ but what i need right now are two simple buttons as stated in the title: expand all and collapse whole list. Do you guys know if something like that can be implemented in this certain script? Please help :)
var CollapsibleLists = new function () {
this.apply = function (_1) {
var _2 = document.getElementsByTagName("ul");
for (var _3 = 0; _3 < _2.length; _3++) {
if (_2[_3].className.match(/(^| )collapsibleList( |$)/)) {
this.applyTo(_2[_3], true);
if (!_1) {
var _4 = _2[_3].getElementsByTagName("ul");
for (var _5 = 0; _5 < _4.length; _5++) {
_4[_5].className += " collapsibleList";
}
}
}
}
};
this.applyTo = function (_6, _7) {
var _8 = _6.getElementsByTagName("li");
for (var _9 = 0; _9 < _8.length; _9++) {
if (!_7 || _6 == _8[_9].parentNode) {
if (_8[_9].addEventListener) {
_8[_9].addEventListener("mousedown", function (e) {
e.preventDefault();
}, false);
} else {
_8[_9].attachEvent("onselectstart", function () {
event.returnValue = false;
});
}
if (_8[_9].addEventListener) {
_8[_9].addEventListener("click", _a(_8[_9]), false);
} else {
_8[_9].attachEvent("onclick", _a(_8[_9]));
}
_b(_8[_9]);
}
}
};
function _a(_c) {
return function (e) {
if (!e) {
e = window.event;
}
var _d = (e.target ? e.target : e.srcElement);
while (_d.nodeName != "LI") {
_d = _d.parentNode;
}
if (_d == _c) {
_b(_c);
}
};
};
function _b(_e) {
var _f = _e.className.match(/(^| )collapsibleListClosed( |$)/);
var uls = _e.getElementsByTagName("ul");
for (var _10 = 0; _10 < uls.length; _10++) {
var li = uls[_10];
while (li.nodeName != "LI") {
li = li.parentNode;
}
if (li == _e) {
uls[_10].style.display = (_f ? "block" : "none");
}
}
_e.className = _e.className.replace(/(^| )collapsibleList(Open|Closed)( |$)/, "");
if (uls.length > 0) {
_e.className += " collapsibleList" + (_f ? "Open" : "Closed");
}
};
}();
It is important to understand why a post-order traversal is used. If you were to just iterate through from the first collapsible list li, it's 'children' may (will) change when expanded/collapsed, causing them to be undefined when you go to click() them.
In your .html
<head>
...
<script>
function listExpansion() {
var element = document.getElementById('listHeader');
if (element.innerText == 'Expand All') {
element.innerHTML = 'Collapse All';
CollapsibleLists.collapse(false);
} else {
element.innerHTML = 'Expand All';
CollapsibleLists.collapse(true);
}
}
</script>
...
</head>
<body>
<div class="header" id="listHeader" onClick="listExpansion()">Expand All</div>
<div class="content">
<ul class="collapsibleList" id="hubList"></ul>
</div>
</body>
In your collapsibleLists.js
var CollapsibleLists =
new function(){
...
// Post-order traversal of the collapsible list(s)
// if collapse is true, then all list items implode, else they explode.
this.collapse = function(collapse){
// find all elements with class collapsibleList(Open|Closed) and click them
var elements = document.getElementsByClassName('collapsibleList' + (collapse ? 'Open' : 'Closed'));
for (var i = elements.length; i--;) {
elements[i].click();
}
};
...
}();

Javascript not working while inserting image object in html

MAJOR EDIT: Re-Did a lot of things. But similar error.
var white = 1;
var turn = white;
var table = document.getElementById("game");
function createTable(table, white) {
var i,j,tr;
for(i=0;i<8;i++)
{
tr = document.createElement('tr');
for(j=0;j<8;j++)
tr.appendChild(document.createElement('td')).id = String.fromCharCode( (white == 1 ? j : 8-j) +97)+(white == 1 ? 8-i : i+1);
table.appendChild(tr);
}
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
table.rows[i].cells[j].setAttribute("class","cell");
}
}
}
function onImageLoad(t) {
console.log(t);
}
function createImageArray() {
var w,c,p;
var image = new Array(2);
for(w=0;w<2;w++)
{
image[w] = new Array(2);
for(c=0;c<2;c++)
{
image[w][c] = new Array(6);
for(p=0;p<6;p++)
{
image[w][c][p] = new Array(2);
}
}
}
return image;
}
function createBlankimageArray() {
var blank = new Array(2);
return blank;
}
function bufferImages(image,blank) {
var w, c, p, s, word;
for(w=0;w<2;w++)
{
for(c=0;c<2;c++)
{
for(p=0;p<6;p++)
{
for(s=0;s<2;s++)
{
word = w.toString() + c.toString() + (p+1).toString() + s.toString() + ".png";
//console.log(word);
image[w][c][p][s] = new Image();
image[w][c][p][s].onload = onImageLoad(word);
image[w][c][p][s].src='final images/'+ word;
}
}
}
}
for(i=0;i<2;i++)
{
blank[i] = new Image();
word = i.toString() + '.png';
blank[i].onload = onImageLoad(word);
blank[i].src= 'final images/'+ word;
}
}
function intializeState() {
var x,y,temp;
var state = new Array(8);
for(y=0;y<8;y++)
{
state[y] = new Array(8);
for(x=0;x<8;x++)
{
state[y][x] = new Array(3);
// Set Cell White or Black.
state[y][x][0] = (x+y)%2;
if(y==1 || y == 6)
{
temp = 0;
state[y][x][1] = temp;
state[y][x][2] = ( white==1 ? 0 : 1);
}
else if(x==0 || x==7) {temp = 1;}
else if(x==1 || x==6) {temp = 2;}
else if(x==2 || x==5) {temp = 3;}
else if(x==3) {temp = 4;}
else if(x==4) {temp = 5;}
if(temp!=0)
{
if(y==0)
{
state[y][x][1] = temp;
state[y][x][2] = (white == 1 ? 0 : 1);
}
else if(y==7)
{
state[y][x][1] = temp;
state[y][x][2] = (white == 1 ? 1 : 0);
}
else
{
state[y][x][1] = 7;
state[y][x][2] = 7;
}
}
}
}
return state;
}
function drawState(table,state,image,blank) {
var y,x;
//var table = document.getElementById("game");
var w,c,p;
for(y=0;y<8;y++)
{
for(x=0;x<8;x++)
{
c = state[y][x][0];
w = state[y][x][1];
p = state[y][x][2];
if(p!=7)
{
table.rows[y].cells[x].appendChild(image[w][c][p][0]);
}
else
{
table.rows[y].cells[x].appendChild(blank[c]);
}
}
}
}
var state = intializeState();
var image = createImageArray();
var blank = createBlankimageArray();
createTable(table, white);
bufferImages(image,blank);
intializeState(state);
drawState(table,state,image,blank);
HTML code:
<!DOCTYPE html>
<html>
<head>
<title>Anti Chess</title>
<link rel="stylesheet" type="text/css" href="screen2.css">
</head>
<body>
<h1 id="game_title">Anti Chess by theManikJindal</h1>
Visit Blog!
<br />
<br />
<table id="game"></table>
<script src="req_logic.js"></script>
</body>
</html>
The above script is required to create a chess board in the initial position.
The problem that I am encountering is in the drawState function.
Console: (has printed out all the image names after loading them) After that:
Uncaught TypeError: Cannot read property '1' of undefined req_logic.js:154
Which is the line: table.rows[y].cells[x].appendChild(image[w][c][p][0]);
so where have I gone wrong.
EDIT: jsFiddle.net link : http://jsfiddle.net/8H3Ha/1/
Change the definition ot initializeState() to:
function intializeState() {
var x,y,temp;
var state = new Array(8);
for(y=0;y<8;y++)
{
state[y] = new Array(8);
for(x=0;x<8;x++)
{
state[y][x] = new Array(3);
// Set Cell White or Black.
state[y][x][0] = (x+y)%2;
if(y==1 || y == 6)
{
temp = 0;
state[y][x][1] = temp;
state[y][x][2] = ( white==1 ? 0 : 1);
}
else if(x==0 || x==7) {temp = 1;}
else if(x==1 || x==6) {temp = 2;}
else if(x==2 || x==5) {temp = 3;}
else if(x==3) {temp = 4;}
else if(x==4) {temp = 5;}
if(temp!=0)
{
if(y==0)
{
state[y][x][1] = temp;
state[y][x][2] = (white == 1 ? 0 : 1);
}
else if(y==7)
{
state[y][x][1] = temp;
state[y][x][2] = (white == 1 ? 1 : 0);
}
else
{
state[y][x][1] = 7;
state[y][x][2] = 7;
}
}
}
}
return state;
}
Then call it as:
state = initializeState();
The problem is that the parameter variable named state was shadowing the global variable with the same name inside initializeState.
I also suggest that the elements of the state array should be objects, not arrays. Arrays should be used when the elements are uniform, but each of these sub-elements have different purposes: [0] is the cell color, [1] is the piece, and [2] is the piece color.

Categories