#javascript #html
Вопрос:
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>View Review</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="content">
<h1 id = "ourReview">Our Reviews</h1>
</div>
</body>
<script src="app.js"></script>
<script src="script.js"></script>
</html>
данные
const reviews = [
{
id: 1,
name: "susan smith",
job: "web developer",
img:
"https://res.cloudinary.com/diqqf3eq2/image/upload/v1586883334/person-1_rfzshl.jpg",
text:
"I'm baby meggings twee health goth 1. Bicycle rights tumeric chartreuse before they sold out chambray pop-up. Shaman humblebrag pickled coloring book salvia hoodie, cold-pressed four dollar toast everyday carry",
},
{
id: 2,
name: "anna johnson",
job: "web designer",
img:
"https://res.cloudinary.com/diqqf3eq2/image/upload/v1586883409/person-2_np9x5l.jpg",
text:
"Helvetica artisan kinfolk thundercats lumbersexual blue bottle. Disrupt glossier gastropub deep v vice franzen hell of brooklyn twee enamel pin fashion axe.photo booth jean shorts artisan narwhal.",
},
{
id: 3,
name: "peter jones",
job: "intern",
img:
"https://res.cloudinary.com/diqqf3eq2/image/upload/v1586883417/person-3_ipa0mj.jpg",
text:
"Sriracha literally flexitarian irony, vape marfa unicorn. Glossier tattooed 8-bit, fixie waistcoat offal activated charcoal slow-carb marfa hell of pabst raclette post-ironic jianbing swag.",
},
{
id: 4,
name: "bill anderson",
job: "the boss",
img:
"https://res.cloudinary.com/diqqf3eq2/image/upload/v1586883423/person-4_t9nxjt.jpg",
text:
"Edison bulb put a bird on it humblebrag, marfa pok pok heirloom fashion axe cray stumptown venmo actually seitan. VHS farm-to-table schlitz, edison bulb pop-up 3 wolf moon tote bag street art shabby chic. ",
},
];
JS
const ourReview = document.getElementById("ourReview");
let count = 0;
const divElem = document.createElement("div");
function loadPerson(personNum, arr = reviews) {
divElem.className = "review-modal";
divElem.innerHTML = `
<img src="${arr[personNum].img}" alt="${arr[personNum].name}"/>
<h2>${arr[personNum].name}</h2>
<span>${arr[personNum].job}</span>
<p>${arr[personNum].text}</p>
<div id="arrow-button">
<button id="frd-btn"><</button>
<button id="bck-btn">></button>
</div>
<button id="suprise">Suprise me</button>
</div>`;
ourReview.parentNode.append(divElem);
}
window.addEventListener("DOMContentLoaded", loadPerson(0));
// here these let constants are not registering new values by new modal
let frdBtn = document.getElementById("frd-btn");
let bckBtn = document.getElementById("bck-btn");
let suprise = document.getElementById("suprise");
frdBtn.addEventListener("click", () => {
if (count == 0) {
count = reviews.length - 1;
}
count--;
loadPerson(count);
});
bckBtn.addEventListener("click", () => {
if (count > reviews.length - 1) {
count = 0;
}
count ;
loadPerson(count);
});
suprise.addEventListener("click",() => {
const randomNum = Math.floor(Math.random()*reviews.length)
console.log(randomNum);
loadPerson(randomNum);
})
В приведенном выше коде я пытаюсь
let frdBtn = document.getElementById("frd-btn");
let bckBtn = document.getElementById("bck-btn");
let suprise = document.getElementById("suprise");
обновите эти прослушиватели переменных и событий запуска до новой кнопки ,но frdBtn ,bckBtn, suprise не обновляются, а списки событий привязаны к исходным кнопкам, которые создаются в окне.addEventListener(«DOMContentLoaded», loadPerson(0));
Ответ №1:
В вашем коде есть несколько проблем.
Сначала вы должны указать a function
в качестве параметра window.addEventListener
. В настоящее время вы передаете возвращаемое значение функции после ее выполнения, а это не то, что вы хотите:
window.addEventListener("DOMContentLoaded", () => loadPerson(0));
После этого вы должны переместить прослушиватели событий внутри loadPerson
функции, потому что в противном случае они выполняются до того, как элементы появятся (они добавляются асинхронно).
Последнее, что вам следует сделать: не идентифицируйте узлы с an id
, когда их несколько копий (несколько человек). Это делает HTML недействительным и в этом случае document.getElementById
извлекает только первый соответствующий элемент.
Кроме того, const divElem = document.createElement("div");
они тоже должны войти внутрь loadPerson
. В противном случае вы удаляете его с того места, где он был, прежде чем добавлять его снова.
Вы могли бы, например, использовать document.createElement('button')
затем прикрепить прослушиватель событий, а затем добавить их divElem
. И если есть CSS, применяемый с #id
помощью селектора, вместо этого используйте классы.
Ответ №2:
Так много вещей здесь не так.
Во-первых, ваше DOMContentLoaded
загруженное событие выполняется не так, как вы думаете.
window.addEventListener("DOMContentLoaded", loadPerson(0));
Вы вызываете loadPerson
и присваиваете возвращаемое значение (которое будет неопределенным, поскольку вы ничего не возвращаете из loadPerson
функции) и назначаете его в качестве действия для запуска при DOMContentLoaded
возникновении события.
Измените его на
window.addEventListener("DOMContentLoaded", () => loadPerson(0));
Это вызовет анонимную функцию при DOMContentLoaded
срабатывании события.
Во-вторых, ваш код применяет прослушиватели событий при первом запуске сценария. Что на самом деле работает только из-за вашей ошибки с DOMContentLoaded
проблемой, описанной выше.
Вам нужно выполнить весь свой код на DOMContentLoaded
событии (честно говоря, проще и лучше просто убедиться, что ваш файл сценария JS является последним элементом, загружаемым на страницу).
Теперь о ваших кнопках и их логике. Вам нужно знать, что прослушиватели событий JS не являются «постоянными», иначе говоря, если вы создаете новую кнопку, вам нужно сообщить JS, чтобы он применил прослушиватель к вашей вновь созданной кнопке.
На вашем месте я бы создавал элементы программно, а не вручную вводил HTML-элементы в качестве значения innerHTML
. Aka
divElem.className = "review-modal";
divElem.innerHTML = `
<img src="${arr[personNum].img}" alt="${arr[personNum].name}"/>
<h2>${arr[personNum].name}</h2>
<span>${arr[personNum].job}</span>
<p>${arr[personNum].text}</p>
<div id="arrow-button">
<button id="frd-btn"><</button>
<button id="bck-btn">></button>
</div>
<button id="suprise">Suprise me</button>
</div>`;
ourReview.parentNode.append(divElem);
Может быть
divElem.classList.add('review-modal');
const elements = {
img: document.createElement('img'),
name: document.createElement('h2'),
job: document.createElement('span'),
text: document.createElement('p'),
buttonContainer: document.createElement('div'),
buttons: {
frd: document.createElement('button'),
bck: document.createElement('button'),
surprise: document.createElement('button')
}
}
elements.img.setAttribute('src', arr[personNum].img);
elements.img.setAttribute('alt', arr[personNum].name);
elements.name.innerText = arr[personNum].name;
elements.job.innerText = arr[personNum].job;
elements.text.innerText = arr[personNum].text;
elements.buttonContainer.id = 'arrow-button';
elements.buttons.frd.innerText = '<';
elements.buttons.frd.addEventListener('click', () => {
// Logic Here
});
elements.buttons.bck.innerText = '>';
elements.buttons.bck.addEventListener('click', () => {
// Logic Here
});
elements.buttons.surprise.id = 'surprise';
elements.buttons.surprise.addEventListener('click', () => {
// Logic Here
});
elements.buttonContainer.append(...Object.values(elements.buttons));
divElem.append(
elements.img,
elements.name,
elements.job,
elements.text,
elements.buttonContainer
);
ourReview.parentNode.append(divElem);
Это должно войти в функцию, которая обрабатывает создание этих элементов. Кроме того, ВСЕ атрибуты идентификатора должны быть уникальными независимо ни от чего. Вы можете либо переключить их на соответствующие имена классов JS (они же добавлены js--
или что-то, что вы можете идентифицировать как связанные с JS), либо просто убедиться, что идентификаторы уникальны (добавьте номер). Я не советую последнее, так как это может привести к путанице.