Вопрос по dom, html, javascript – Uncaught TypeError: Невозможно прочитать свойство 'lastChild' из null

1

<!DOCTYPE html>
<html>
<head>
	<title>Face Matching Game</title>
	<h2>Matching Game</h2>
	<p>Click on the EXTRA face on the left side</p>
	<style type="text/css">
		div { position: absolute; width: 640px; height: 550px; background-color: maroon }
		img { position: absolute; width: 100px; height: 100px}
		#rightSide { left: 650px; border-left: 2px solid black; }
	</style>
	<script type="text/javascript">
		var NUM_OF_FACES = 0;
		var THE_LEFT_SIDE, THE_RIGHT_SIDE;
		//Function to generate faces
		function generateFaces() {
			THE_LEFT_SIDE = document.getElementById("leftSide");
			THE_RIGHT_SIDE = document.getElementById("rightSide");
			NUM_OF_FACES += 5;
			var image;
			while(NUM_OF_FACES>0){
				image = document.createElement("img");
				image.src = "smile.png";
				image.style.top = Math.floor(Math.random()* (THE_LEFT_SIDE.offsetHeight - 100)) + "px";
				image.style.left = Math.floor(Math.random()* (THE_LEFT_SIDE.offsetWidth - 100)) + "px";
				THE_LEFT_SIDE.appendChild(image);
				NUM_OF_FACES -= 1;
				//console.log(image.style.top, image.style.left )
			}
			var leftSideImages = THE_LEFT_SIDE.cloneNode(true);
			leftSideImages.removeChild(leftSideImages.lastChild);
			THE_RIGHT_SIDE.appendChild(leftSideImages);
		}//end generatefaces()

		function deleteFaces(argument) {
			while(THE_LEFT_SIDE.firstChild){
				THE_LEFT_SIDE.removeChild(THE_LEFT_SIDE.firstChild);
			}
			while(THE_RIGHT_SIDE.firstChild){
				THE_RIGHT_SIDE.removeChild(THE_RIGHT_SIDE.firstChild);
			}
		}//end deleteFaces()

		var theBody = document.getElementsByTagName("body")[0];
		THE_LEFT_SIDE = document.getElementById("leftSide");
		THE_RIGHT_SIDE = document.getElementById("rightSide");
		//Event handling
		THE_LEFT_SIDE.lastChild.onclick = function goToNextLevel() {
			alert("You clicked on correct face.");
			deleteFaces();
			generatefaces();
		};
		theBody.onclick = function gameOver() {
			alert("Game Over!!");
			theBody.onclick = null;
			THE_LEFT_SIDE.lastChild.onclick = null;
		};
	</script>
</head>
<body onload="generateFaces()">
	<div id="leftSide"></div>
	<div id="rightSide"></div>
</body>
</html>

Я новичок в Javascript и столкнулся с проблемой при выполнении задания. Это игра с подбором фактов, и вы должны нажать на дополнительное лицо с левой стороны, и игра продолжается, пока вы не нажмете где-нибудь еще, кроме дополнительного лица слева. Выше находится файл HTML, и в него встроен код JS.

Я получаю ошибку как:Uncaught TypeError: Cannot read property 'lastChild' of null в строке № 48, котораяonclick функция обработчика событий включенаlastChild изTHE_LEFT_SIDE дела. Я не знаю, как это происходит и в чем проблема с моим кодом? Любые выводы будут оценены.

ПохожеTHE_LEFT_SIDE является нулевым в то время, когда вы пытаетесь добавить слушателя. Попробуйте поместить добавления слушателя в функцию, которая выполняется послеgenerateFaces() Todd
THE_LEFT_SIDE пусто доgenerateFaces функция вызываетсяonload изbody, Положилevent handlers код внутри<body> в последнем или внутриgenerateFaces функция. n4m31ess_c0d3r

Ваш Ответ

1   ответ
2

Вы пытаетесь получить доступ к элементу с идентификаторомleftSide прежде чем он был добавлен в DOM.

Если вы переместите свой скрипт в конец тела страницы, вы больше не увидите эту ошибку, а вместо этого другую, не связанную:

<!DOCTYPE html>
<html>
<head>
	<title>Face Matching Game</title>
	<h2>Matching Game</h2>
	<p>Click on the EXTRA face on the left side</p>
	<style type="text/css">
		div { position: absolute; width: 640px; height: 550px; background-color: maroon }
		img { position: absolute; width: 100px; height: 100px}
		#rightSide { left: 650px; border-left: 2px solid black; }
	</style>
 
</head>
<body onload="generateFaces()">
	<div id="leftSide"></div>
	<div id="rightSide"></div>

   	    <script type="text/javascript">
		var NUM_OF_FACES = 0;
		var THE_LEFT_SIDE, THE_RIGHT_SIDE;
		//Function to generate faces
		function generateFaces() {
			THE_LEFT_SIDE = document.getElementById("leftSide");
			THE_RIGHT_SIDE = document.getElementById("rightSide");
			NUM_OF_FACES += 5;
			var image;
			while(NUM_OF_FACES>0){
				image = document.createElement("img");
				image.src = "smile.png";
				image.style.top = Math.floor(Math.random()* (THE_LEFT_SIDE.offsetHeight - 100)) + "px";
				image.style.left = Math.floor(Math.random()* (THE_LEFT_SIDE.offsetWidth - 100)) + "px";
				THE_LEFT_SIDE.appendChild(image);
				NUM_OF_FACES -= 1;
				//console.log(image.style.top, image.style.left )
			}
			var leftSideImages = THE_LEFT_SIDE.cloneNode(true);
			leftSideImages.removeChild(leftSideImages.lastChild);
			THE_RIGHT_SIDE.appendChild(leftSideImages);
		}//end generatefaces()

		function deleteFaces(argument) {
			while(THE_LEFT_SIDE.firstChild){
				THE_LEFT_SIDE.removeChild(THE_LEFT_SIDE.firstChild);
			}
			while(THE_RIGHT_SIDE.firstChild){
				THE_RIGHT_SIDE.removeChild(THE_RIGHT_SIDE.firstChild);
			}
		}//end deleteFaces()

		var theBody = document.getElementsByTagName("body")[0];
		THE_LEFT_SIDE = document.getElementById("leftSide");
		THE_RIGHT_SIDE = document.getElementById("rightSide");
		//Event handling
		THE_LEFT_SIDE.lastChild.onclick = function goToNextLevel() {
			alert("You clicked on correct face.");
			deleteFaces();
			generatefaces();
		};
		theBody.onclick = function gameOver() {
			alert("Game Over!!");
			theBody.onclick = null;
			THE_LEFT_SIDE.lastChild.onclick = null;
		};
	</script>
</body>
</html>

Да уж. Это почему? vvs14
Это потому что этоonclick обработчик события может быть вызван, даже если загружена полная страница? Есть ли какие-нибудь стандарты, как лучше писать обработчики событий и куда их писать? vvs14
Как я уже сказал, один выполняется до создания полного дерева DOM, другой - после. Если элемент, с которым вы пытаетесь работать, еще не существует, вы не можете добавить к нему обработчики событий. Timo
Я поместил этот обработчик событий THE_LEFT_SIDE.lastChild.onclick внутрь generateFaces (), и он работает нормально. Какая разница, и чем она отличается от предыдущей? vvs14
Ваш код выполняется последовательно. Если браузер обнаруживает JavaScript перед элементами HTML, JavaScript выполняется до отображения элементов HTML. Переместите свой код в телоonload обработчик событий, чтобы избежать этого - он будет выполнен после того, как будет обработано все тело. Timo

Похожие вопросы