Я работаю над назначением Javascript, которое разбивает страницу на два элемента div, а затем добавляет div слева с случайно размещенными изображениями, затем я использовал .cloneNode()
для дублирования справа, минус последнее дочернее изображение.
Эта часть работает отлично, но я должен добавить обработчик события к последнему элементу левого div, но когда я пытаюсь это сделать, метод lastElementChild()
возвращает значение null, даже если div имеет ожидаемые дочерние узлы. Код ниже, и я прокомментировал, где проблема. Любая помощь будет оценена!
<!DOCTYPE html>
<html>
<head>
<style>
img {position: absolute}
div {position: absolute; height: 500px; width: 500px}
#right {border-left: solid black; left: 500px}
</style>
<script>
<!-- everything here works fine -->
function generateFaces(){
var theLeftSide = document.getElementById("left");
var numberFaces = 5;
for (i = 0; i < numberFaces; i++){
var random_x = Math.random()*400;
var random_y = Math.random()*400;
var image = document.createElement("img")
image.src = "smile.png";
image.setAttribute("style","top: " + random_y + "px;" + "left: " + random_x + "px;");
theLeftSide.appendChild(image);
}
var theRightSide = document.getElementById("right");
leftSideImages = theLeftSide.cloneNode(true);
theRightSide.appendChild(leftSideImages);
theRightSide.lastChild.removeChild(theRightSide.lastChild.lastChild);
}
</script>
</head>
<body onload = "generateFaces()">
<h1> Game </h1>
<p> Instructions </p>
<div id = "right"></div>
<div id = "left"> </div>
<script>
<!-- problem script here -->
var temp = document.getElementById("left");
console.log(temp); // displays <div> with its children <img>
var temp2 = temp.lastElementChild;
console.log(temp2); // returns null
</script>
</body>
</html>
onload
тела не срабатывает до тех пор, пока не запустится javascript в вашем "проблемном скрипте".
Порядок выполнения здесь в основном:
h1
, p
, #left
и #right
добавляются в DOM
запускается сценарий # 1, регистрируется пустой #left
div и null
lastElementChild.
body onload
event fire и сценарий # 2 generateFaces()
функция generateFaces()
). На этом этапе теги <img>
вставляются в DOM.
Исправление состоит в том, чтобы убедиться, что сценарий №1 работает после # 2:
<body onload="handleLoad()">
и JS:
function handleLoad() {
generateFaces()
logStuff()
}
function logStuff() {
var temp = document.getElementById("left");
console.log(temp); // displays <div> with its children <img>
var temp2 = temp.lastElementChild;
console.log(temp2); // logs <img>
}
Может показаться, что в консоли на #left
есть изображения в то время, когда запускается сценарий №1. Это просто причуда консоли; фактическое ведение журнала происходит асинхронно, и поскольку переменная, на которую ссылается, изменяется тем временем, фактически зарегистрированное значение отличается от того, что было при console.log()
.
Вы можете увидеть это поведение, setTimeout
продолжительность setTimeout
на вызов функции generateFaces()
:
function generateFaces() {
var theLeftSide = document.getElementById("left");
var numberFaces = 5;
for (i = 0; i < numberFaces; i++) {
var random_x = Math.random() * 400;
var random_y = Math.random() * 400;
var image = document.createElement("img")
image.src = "smile.png";
image.setAttribute("style", "top: " + random_y + "px;" + "left: " + random_x + "px;");
theLeftSide.appendChild(image);
}
var theRightSide = document.getElementById("right");
leftSideImages = theLeftSide.cloneNode(true);
theRightSide.appendChild(leftSideImages);
theRightSide.lastChild.removeChild(theRightSide.lastChild.lastChild);
}
var temp = document.getElementById("left");
console.log(temp); // displays <div> with its children <img>
var temp2 = temp.lastElementChild;
console.log(temp2); // returns null
setTimeout(generateFaces, 250) // play with this value
img {
position: absolute
}
div {
position: absolute;
height: 500px;
width: 500px
}
#right {
border-left: solid black;
left: 500px
}
<h1> Game </h1>
<p> Instructions </p>
<div id="right"></div>
<div id="left"> </div>
О, и обратите внимание, что ваша функция generateFaces()
настоящее время создает несколько элементов в DOM с тем же идентификатором. Ты собираешься это исправить.
Функция generateFaces() вызывается при загрузке тела. но ваш второй скрипт запускается при загрузке окна.
Поэтому, когда запускается второй скрипт, нет temp.lastElementChild, и вы получаете null.
Вы можете slove, как это
<!DOCTYPE html>
<html>
<head>
<style>
img {position: absolute, height: 30px; width: 30px;}
div {position: absolute; height: 500px; width: 500px}
#right {border-left: solid black; left: 500px}
</style>
</head>
<body onload = "generateFaces()">
<h1> Game </h1>
<p> Instructions </p>
<div id = "right"></div>
<div id = "left"> </div>
<script>
function generateFaces()
{
console.log('y');
var theLeftSide = document.getElementById("left");
var numberFaces = 5;
for (i = 0; i < numberFaces; i++){
var random_x = Math.random()*400;
var random_y = Math.random()*400;
var image = document.createElement("img")
image.src = "smile.png";
image.setAttribute("style","top: " + random_y + "px;" + "left: " + random_x + "px;");
theLeftSide.appendChild(image);
}
var theRightSide = document.getElementById("right");
leftSideImages = theLeftSide.cloneNode(true);
theRightSide.appendChild(leftSideImages);
theRightSide.lastChild.removeChild(theRightSide.lastChild.lastChild);
loaded();
}
<script>
function loaded() {
var temp = document.getElementById("left");
console.log(temp);
var temp2 = temp.lastElementChild;
console.log(temp2);
}
generateFaces()
вызывается после вашегоconsole.log(temp2)
. Когда вы#left
систему,#left
по-прежнему пустойdiv