#javascript #html
#javascript #HTML
Вопрос:
Я столкнулся с этой проблемой, когда они не реагируют одинаково. В основном html и css (или вы можете напрямую перейти на javascript. Я включу html и css для контекста).
<body>
<div class="container">
<div class="box green"></div>
<div class="box red"></div>
<div class="box blue"></div>
<div class="box yellow"></div>
<div class="box pink"></div>
<div class="box orange"></div>
<div class="box yellow"></div>
<div class="box red"></div>
<div class="box blue"></div>
<div class="box pink"></div>
<div class="box green"></div>
<div class="box orange"></div>
</div>
<div class="score">"Your Score"</div>
</body>
Это CSS
body{
height: 100vh;
background: #00aaaa;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.container{
background: rgba(0, 200, 200, .5);
display: grid;
grid-template-columns: repeat(4, 100px);
grid-template-rows: repeat(3, 100px);
grid-gap: 5px;
}
.box:hover{
border: 2.5px solid black;
}
.green{background: green;}
.red{background: red;}
.blue{background: blue;}
.yellow{background: yellow;}
.pink{background: pink;}
.orange{background: orange;}
.score{
margin-top: 12px;
width: 415px;
text-align: center;
}
Окно показывает его цвет в течение 3 секунд после загрузки страницы. И становится серым. Javascript устроен так, что всякий раз, когда вы нажимаете на каждое поле, оно показывает его цвет. Вот javascript.
let $$ = document.querySelectorAll.bind(document);
let $ = document.querySelector.bind(document);
window.addEventListener("load", setTimeout(colorReset, 3000));
function colorReset(){
$$(".box").forEach((boxColor)=>{
boxColor.style.background = "grey";
});
}
function revealColor(x){
x.style.background = x.classList[1];
}
$$(".box").forEach((boxWithColor)=>{
boxWithColor.addEventListener("click", ()=>{
revealColor(boxWithColor);
});
});
Приведенный выше скрипт не отображает цвет окна при нажатии. Но я заменяю window.addEvenListener(«загрузка», функция) на window.onload = setTimeout(«colorReset», 3000); Теперь это работает. Итак, мой вопрос в том, реагируют ли они по-разному?
Комментарии:
1.
window.addEventListener("load", setTimeout(colorReset, 3000));
— это не делает то, что вы думаете.2. Вы ждете 3 секунды после загрузки окна при использовании setTimeout
3. @Dshiz Да, это то, что я пытаюсь сделать. Также через 3 секунды фон каждого окна становится серым. А затем, когда я нажимаю на поле, оно показывает соответствующий цвет. Это то, что я пытаюсь сделать. Но когда я нажимаю, это не соответствует цвету. Он остается серым.
4. Вам также необходимо запустить остальную часть скрипта (особенно
$$(".box").forEach((boxWithColor)=>{
часть вDOMContentLoaded
обработчике, а не в теле корневого скрипта.
Ответ №1:
В вашем скрипте как есть есть две основные ошибки:
- Вы
setTimeout
неправильно используетеaddEventListener
. - Вы выполняете оценку
$$(".box")
до того, как HTML был полностью загружен, поэтомуdocument.querySelectorAll
вернет пустые или неполные результаты.
Часть 1: addEventListener
с setTimeout
:
Ваш код должен передавать ссылку на функцию addEventListener
, но ваш код фактически передает number
значение, потому что вы вызываете setTimeout
на сайте вызова, а не передаете ссылку на setTimeout
(что в любом случае не сработает, поскольку addEventListener
функция обратного вызова должна иметь один Event
параметр, а исходное number
значение из setTimeout
которого возвращает «timer-id» вы можете перейти clearTimeout
к отмене активного таймера).
Измените это:
window.addEventListener("load", setTimeout(colorReset, 3000));
на это:
// ES3-style:
window.addEventListener("load", function( e ) { setTimeout(colorReset, 3000); } );
// ES5-style (arrow-function, lambda-function):
window.addEventListener("load", e => setTimeout(colorReset, 3000) );
Кроме того, вам следует избегать использования свойств событий в стиле старого стиля (очень, очень старого стиля) onload
/ onclick
/ etc, потому что они не поддерживают множественную отправку (по крайней мере, без некоторых грубых хаков).
Часть 2. Пройдите по DOM только после его загрузки.
- Я предполагаю, что на вашей HTML-странице ваш скрипт находится во встроенном
<script>
элементе (не используется<script src="">
, который находится в<head>
.- Это означает, что браузер запустится
$$(".box").forEach((boxWithColor)=>{
, когда он немедленно столкнется со сценарием. - Это не сработает, потому что при вычислении вышеуказанного селектора *
div.box
в DOM еще не загружены элементы!
- Это означает, что браузер запустится
Чтобы исправить это, переместите весь ваш скрипт в отдельный function
и передайте его addEventListener( 'DOMContentLoaded' )
. Также рассмотрите возможность использования for-of
вместо NodeList.forEach
и перемещения setTimeout
вызова в функцию, например:
const $$ = document.querySelectorAll.bind(document);
const $ = document.querySelector.bind(document);
function onDOMLoaded( e ) {
for( const box of $$('.box') ) {
boxWithColor.addEventListener( 'click', ce => revealColor( ce.currentTarget ) );
}
setTimeout( colorReset, 3000 );
}
window.addEventListener( "DOMContentLoaded", onDOMLoaded );
function colorReset() {
$$(".box").forEach((boxColor)=>{
boxColor.style.background = "grey";
});
}
function revealColor(x){
x.style.background = x.classList[1];
}
Комментарии:
1. все еще не сработало. Теперь фон даже не меняется на серый. Сначала он изменил весь свой цвет на серый после отображения цвета для каждого поля в течение 3 секунд.
2. @LForLaddu Я подозреваю, что происходит что-то еще. Пожалуйста, обновите свой вопрос, чтобы включить весь ваш код в виде интерактивного фрагмента или JSFiddle.
3. @LForLaddu Я нашел другую проблему и обновил свой ответ.