#javascript
Вопрос:
Я работаю над Буткампом веб-разработчика Коула Стила на Udemy #264. Бурлящее Событие. Я пытаюсь создать функцию, которая позволит передавать один или несколько объектов и выполнять одно и то же действие (переключить список классов «скрыть», чтобы кнопка «Нажмите здесь, чтобы скрыть» исчезла, и появилась кнопка «Нажмите здесь, чтобы показать») для каждого из них.
Я могу заставить это работать, вызвав функцию отдельно, например
const container = document.querySelector('#container')
const show = document.querySelector('#show')
function hideOneElement(ele){
ele.classList.toggle('hide');
}
show.addEventListener('click', function () {
hideOneElement(container);
hideOneElement(show);
})
Однако, когда я пытаюсь вызвать функцию с обоими контейнерами (div с надписью «Нажмите здесь, чтобы скрыть») и показать одновременно, я не могу заставить ее работать. Я попытался написать функцию скрытия как для…, например
function hideElements(elements){
for (const ele of elements) {
ele.classList.toggle('hide')
}
}
let stuffToHide = [container,show]
hideElements(stuffToHide)
Однако это, похоже, не работает. Я также попытался передать два отдельных аргумента, но это тоже, похоже, не работает:
function hideElements(ele1, ele2) {
ele1.classList.toggle('hide');
ele2.classList.toggle('hide')
}
hideElements(container, show);
На данный момент я не уверен, куда идти, и мой Google-джитсу не находит ничего полезного. На самом деле это не является частью упражнения курса, но, похоже, мне в корне не хватает чего-то в вызове функций.
Полный код и HTML ниже:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.hide {
display: none;
}
</style>
</head>
<body>
<section onclick="alert('sectopm clicked')">
<p onclick="alert('paragraph clicked')">I am a paragraph
<button onclick="alert('button clicked')">Click</button>
</p>
</section>
<div id="container">
Click to Hide
<button id="colorbtn">Change Color</button>
</div>
<div id="show">
Click here to Show
</div>
<script src="app.js"></script>
</body>
</html>
const makeRandColor = () => {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return (`rgb(${r},${g},${b})`);
}
const button = document.querySelector('#colorbtn')
const container = document.querySelector('#container')
const show = document.querySelector('#show')
function hideElements(ele1, ele2) {
// for (const ele of elements) {
// ele.classList.toggle('hide')
// }
// elements.classList.toggle('hide')
ele1.classList.toggle('hide');
ele2.classList.toggle('hide')
}
function hideOneElement(ele){
ele.classList.toggle('hide');
}
//hideElements(show); //run function once to toggle on the 'hide' class so that this is not shown by default.
hideElements(show)
button.addEventListener('click', function (e) {
container.style.backgroundColor = makeRandColor();
e.stopPropagation();
})
container.addEventListener('click', function () {
hideElements(container, show);
//hideElements(container, show); //hide the 'click here to hide' stuff
})
show.addEventListener('click', function () {
hideElements(container);
hideElements(show);
})
show.addEventListener('click', function () {
hideOneElement(container);
hideOneElement(show);
})
Ответ №1:
«Я пытаюсь создать функцию, которая позволит передавать один или несколько объектов», поэтому вам нужно иметь возможность вызывать hideElements либо как hideElements(ele1), либо как hideElements(ele1, ele2)?
В этом случае вам нужно будет передать массив по отдельным переменным. Вы были на правильном пути с закомментированным кодом здесь:
// for (const ele of elements) {
// ele.classList.toggle('hide')
// }
// elements.classList.toggle('hide')
Но вы не пытались передать их в виде массива, и вы не можете перебирать отдельный элемент (есть только один). Если вы заключите свои переменные в массив с помощью [], это должно решить ваши проблемы.
Пример:
function hideElements(elements) {
for (const ele of elements) {
ele.classList.toggle('hide')
}
}
hideElements([show]); //run function once to toggle on the 'hide' class so that this is not shown by default.
container.addEventListener('click', function() {
hideElements([container, show]);
})
show.addEventListener('click', function() {
hideElements([container, show]);
})
Рабочий Пример:
const makeRandColor = () => {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return (`rgb(${r},${g},${b})`);
}
const button = document.querySelector('#colorbtn')
const container = document.querySelector('#container')
const show = document.querySelector('#show')
function hideElements(elements) {
for (const ele of elements) {
ele.classList.toggle('hide')
}
}
function hideOneElement(ele) {
ele.classList.toggle('hide');
}
hideElements([show]); //run function once to toggle on the 'hide' class so that this is not shown by default.
button.addEventListener('click', function(e) {
container.style.backgroundColor = makeRandColor();
e.stopPropagation();
})
container.addEventListener('click', function() {
hideElements([container, show]);
})
show.addEventListener('click', function() {
hideElements([container, show]);
})
.hide {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<section onclick="alert('sectopm clicked')">
<p onclick="alert('paragraph clicked')">I am a paragraph
<button onclick="alert('button clicked')">Click</button>
</p>
</section>
<div id="container">
Click to Hide
<button id="colorbtn">Change Color</button>
</div>
<div id="show">
Click here to Show
</div>
<script src="app.js"></script>
</body>
</html>
Комментарии:
1. Большое вам спасибо! Массивы-это проклятие моего существования!
Ответ №2:
Некоторые блоки точно не будут работать — поскольку вы вызываете hideElements с одним аргументом — второй аргумент будет неопределенным, и, конечно, в списке неопределенных нет списка классов (вызывает ошибку).
А также это очень сбивает с толку, потому что вы дважды добавляете прослушиватель событий в элемент show..
Скопировано с вашего поста и добавлено комментариев:
//hideElements(show); //run function once to toggle on the 'hide' class so that this is not shown by default.
hideElements(show) // - this will error like I said above as elem2 will be undefined..
button.addEventListener('click', function (e) {
container.style.backgroundColor = makeRandColor();
e.stopPropagation();
})
container.addEventListener('click', function () {
hideElements(container, show);
//hideElements(container, show); //hide the 'click here to hide' stuff
})
//below you make same event listener twice which is very confusing :
show.addEventListener('click', function () {
hideElements(container);
hideElements(show);
})
show.addEventListener('click', function () {
hideOneElement(container);
hideOneElement(show);
})