У меня есть работающий кусок кода, настроенный следующим образом. Файл .html, содержащий в основном только 2 элемента div, обозначенных «id». «Head» ссылается на внешний файл .css, а в конце «body» ссылается на внешний .js. Эта комбинация работает.

Но когда я перемещаю ссылку .js в «голову», код не работает. В частности, определение функции .onclick (responseShapeId.onclick) для одного из элементов div не устанавливается с помощью errmsg «TypeError: Невозможно установить свойство« onclick »для null». Потому что, будучи помещенным в голову, код .js еще не знает о divs (responseShape) в теле, то есть responseShapeId имеет значение null.

Как правильно избежать / справиться с такой зависимостью? Мой код .js ниже. Благодарю.

var reactionShapeId = document.getElementById("reactionShape"); var createdTime, clickedTime; var maxDelay = 5000; // milliseconds console.log(reactionShapeId); // set absolute limits to the shape - equilateral is assumed var maxLength = Math.min(300,window.innerWidth,window.innerHeight); var minLength = Math.min(50,maxLength); var minOpacity = 0.25; // dynamically determined shape variables var shapeLength; var shapeBorderRadius; // square or circle var posX, posY; var colourRed, colourGreen, colourBlue, colourOpacity; // statistics var maxTrials = 10; var trialResults = new Array(); var trialCounter = 0; var trialTotal = 0; var trialAverage; function makeShape() { trialCounter = trialCounter   1; // first determine properties for shape shapeLength = minLength   (maxLength-minLength) * Math.random(); if (Math.round(Math.random()) == 1) { shapeBorderRadius = 0; } else { shapeBorderRadius = shapeLength / 2; } posX = (projectReactionTester.offsetWidth - shapeLength) * Math.random(); posY = (projectReactionTester.offsetHeight - shapeLength) * Math.random(); colourRed = Math.floor(256 * Math.random()); colourGreen = Math.floor(256 * Math.random()); colourBlue = Math.floor(256 * Math.random()); colourOpacity = minOpacity   (1-minOpacity) * Math.random(); // tidy up if (colourRed==256) colourRed=255; if (colourGreen==256) colourGreen=255; if (colourBlue==256) colourBlue=255; console.log(shapeLength, shapeBorderRadius, posX, posY, colourRed, colourGreen, colourBlue, colourOpacity, trialCounter, trialTotal); // setting of properties must be done altogether reactionShapeId.setAttribute("style", "width:"   shapeLength   "px;"   "height:"   shapeLength   "px;"   "border-radius:"   shapeBorderRadius   "px;"   "position: relative;"   "left:"   posX   "px;"   "top:"   posY   "px;"   "background-color:rgba("   colourRed   ","   colourGreen   ","   colourBlue   ","   colourOpacity   ");"); // then set delay timer // .display must be set to "block" instead of "inline" var delayTime = maxDelay * Math.random(); console.log(delayTime); setTimeout(function() { createdTime = Date.now(); reactionShapeId.style.display = "block"; },delayTime); } reactionShapeId.onclick = function() { clickedTime = Date.now(); trialResults[trialCounter] = clickedTime - createdTime; trialTotal = trialTotal   trialResults[trialCounter]; this.style.display = "none"; document.getElementById("reactionTime").innerHTML = trialResults[trialCounter]; // display statistics {amp}amp; re-initialize if (trialCounter == maxTrials) { trialAverage = trialTotal / trialCounter; alert("Your average response time over "   trialCounter   " trials is "   trialAverage   " ms"); trialCounter = 0; trialTotal = 0; } // next trial makeShape(); } makeShape(); 

Проблема в том, что когда исполняется ваш js, DOM загружается не полностью, особенно элемент, к которому вы добавляете событие onclick. Когда вы помещаете это в конец тела, к этому времени загружается DOM. Для этого вызовите makeShape () внутри функции готовности документа jquery. Если вы не используете jquery, вы можете включить событие onload.

 {amp}lt;body onload="makeShape()"{amp}gt; 

Примечание: здесь я предполагаю, что makeShape — это функция, которую вы собираетесь вызывать, иначе замените ее на вашу функцию

РЕДАКТИРОВАТЬ

Если вышеуказанное решение не работает, в голову положите

 {amp}lt;script{amp}gt; document.addEventListener("DOMContentLoaded", function() { makeShape(); }); {amp}lt;/script{amp}gt; 

Если вы используете JQuery:

 $(document).ready(function(){ makeShape(); }) 

Здесь вы пытаетесь получить доступ к элементу, который не существует / загружен / добавлен в DOM

  • Вы можете включить js-код после html-контента (вы хотите сослаться на JS-код).
  • Вы можете использовать событие onload, чтобы проверить, загружен ли DOM, выполнить js, чтобы убедиться, что загружены все элементы DOM.

Рекомендуется загружать JavaScript в нижней части страницы, прямо перед закрывающим тегом.

Для более подробного объяснения, обратитесь к этому блогу здесь

HTML

 {amp}lt;body{amp}gt; {amp}lt;div id="showText"{amp}gt;{amp}lt;/div{amp}gt; {amp}lt;button type="button" onclick="myFunction()"{amp}gt;Click Here{amp}lt;/button{amp}gt; {amp}lt;button type="button" onclick="GLOBAL.myNewFunction()"{amp}gt;Click Here{amp}lt;/button{amp}gt; {amp}lt;script src="js/index.js"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;/body{amp}gt; 

JavaScript — index.js (внешний файл)

 //The First Method window.myFunction = function(){ alert("It's working!"); document.getElementById("showText").innerHTML = "This line is written by JavaScript." } //The Second Method (function(GLOBAL){ function myNewFunction(){ alert("It's working!"); document.getElementById("showText").innerHTML = "This line is written by JavaScript." } GLOBAL.myNewFunction = myNewFunction; })(window.GLOBAL || (window.GLOBAL={}));