Не могу найти ошибку в сделанной "карусели" на JS
я сделал небольшой тест на проверку английского и для удобства решил сделать карусель, чтобы задание прокручивалось и пользователь получал следующее. Код без использования базы данных через API у меня работает. Подскажите, пожалуйста, в чем может быть проблема?
Что я сделал.
Во втором случае я пишу код на laravel и использую api.Если по конкретнее, то проблема в элементе listElems. Если вывести его в консоль, в первом коде без апи - выходит массив с "li". А во втором коде с api- у меня пустой массив Nodelist. Вся проблема в нем. Почему так происходит- не пойму.
let list = carousel.querySelector('ul');
const question = {
answers: []
}
class Api {
constructor(url) {
this.url = url;
}
async getApi() {
const response = await fetch(`${this.url}`);
if (!response.ok) {
throw new Error(`Ошибка по адресу ${url}, статус ошибки ${response}`);
}
return await response.json();
};
}
const taskApi = new Api('https://617e6ebc2ff7e600174bd7c2.mockapi.io/english');
const page = document.querySelector('.page');
const testContainer = document.querySelector('.test-container');
const resultContainer = document.querySelector('.result-container');
const startOver = document.querySelector('.start-over');
const testCard = document.querySelector('.test-card');
const nextVopros = () => {
position -= width * count;
position = Math.max(position, -width * (listElems.length - count));
list.style.marginLeft = position + 'px';
question.answers = [];
}
const stepClicks = () => {
setTimeout(nextVopros(), 1000);
}
const checkAnswers = (a, b) => {
return a.map((item, idx) => item === b[idx]);
}
const renderCard = (
questionsRus,
buttonTextVariant1,
buttonTextVariant2,
buttonTextVariant3,
questionsEng
) => {
const placeCard = document.createElement('li');
const image = document.createElement('div');
const testContainer = document.createElement('div');
const vopros = document.createElement('div');
const voprosText = document.createElement('div');
const otvetProverka = document.createElement('div');
const otvetVariant = document.createElement('div');
const text1 = document.createElement('p');
const text2 = document.createElement('p');
const text3 = document.createElement('p');
const otvet = document.createElement('div');
const text4 = document.createElement('button');
const text5 = document.createElement('button');
const text6 = document.createElement('button');
const buttonProverka = document.createElement('button');
buttonProverka.textContent = "проверить"
//Классы
//placeCard.classList.add('place-card');
image.classList.add('image');
testContainer.classList.add('test-container');
vopros.classList.add('vopros');
voprosText.classList.add('vopros');
otvetVariant.classList.add("otvet-variant");
text1.classList.add("display-none", "btn", "btn-margin", "btn-primary");
text2.classList.add("display-none", "btn", "btn-margin", "btn-primary");
text3.classList.add("display-none", "btn", "btn-margin", "btn-primary");
text4.classList.add("btn", "btn-margin", "btn-warning");
text5.classList.add("btn", "btn-margin", "btn-warning");
text6.classList.add("btn", "btn-margin", "btn-warning");
buttonProverka.classList.add("btn", "btn-success");
otvet.classList.add('otvet');
otvetProverka.classList.add("otvet-proverka");
//placeCard.appendChild(image);
placeCard.appendChild(testContainer);
testContainer.appendChild(vopros);
testContainer.appendChild(voprosText);
testContainer.appendChild(otvetVariant);
otvetVariant.appendChild(text1);
otvetVariant.appendChild(text2);
otvetVariant.appendChild(text3);
testContainer.appendChild(otvet);
otvet.appendChild(text4);
otvet.appendChild(text5);
otvet.appendChild(text6);
testContainer.appendChild(otvetProverka);
otvetProverka.appendChild(buttonProverka);
voprosText.textContent = questionsRus;
text4.textContent = buttonTextVariant1;
text5.textContent = buttonTextVariant2;
text6.textContent = buttonTextVariant3;
const pushed1 = () => {
let res = question.answers.push(buttonTextVariant1);
text1.textContent = buttonTextVariant1;
text4.classList.add("display-none")
text1.classList.remove("display-none");
otvetVariant.appendChild(text1);
return res;
}
const pushed2 = () => {
let res = question.answers.push(buttonTextVariant2);
text2.textContent = buttonTextVariant2;
text5.classList.add("display-none");
text2.classList.remove("display-none");
otvetVariant.appendChild(text2);
return res;
}
const pushed3 = () => {
let res = question.answers.push(buttonTextVariant3);
text3.textContent = buttonTextVariant3;
text6.classList.add("display-none");
text3.classList.remove("display-none");
otvetVariant.appendChild(text3);
return res;
}
text4.addEventListener("click", pushed1);
text5.addEventListener("click", pushed2);
text6.addEventListener("click", pushed3);
const proverka = () => {
let res = checkAnswers(question.answers, questionsEng);
if (question.answers.length !== 3) {
buttonProverka.setAttribute("disabled", "disabled");
alert('Составьте предложение полностью')
}
if (question.answers.length === 3) {
if ((res[0] && res[1] && res[2]) === false) {
} else {
console.log('1')
}
if (res[0] === false) {
text1.classList.add('btn-danger');
} else {
text1.classList.add('btn-success');
};
if (res[1] === false) {
text2.classList.add('btn-danger');
} else {
text2.classList.add('btn-success')
};
if (res[2] === false) {
text3.classList.add('btn-danger')
} else {
text3.classList.add('btn-success')
};
text1.classList.remove('btn-warning');
text2.classList.remove('btn-warning');
text3.classList.remove('btn-warning');
stepClicks();
}
}
buttonProverka.addEventListener("click", proverka);
return placeCard;
}
function shewCards() {
taskApi.getApi()
.then(json =>
json.forEach(function(item) {
card(item.questionsRus,
item.buttonTextVariant[0],
item.buttonTextVariant[1],
item.buttonTextVariant[2],
item.questionsEng);
}))
}
shewCards();
function card(
questionsRus,
buttonTextVariant1,
buttonTextVariant2,
buttonTextVariant3,
questionsEng) {
const placeCard = renderCard(
questionsRus,
buttonTextVariant1,
buttonTextVariant2,
buttonTextVariant3,
questionsEng);
list.appendChild(placeCard);
}
let listElems = document.querySelectorAll('li');
let i = 1;
for (let li of carousel.querySelectorAll('li')) {
li.style.position = 'relative';
li.insertAdjacentHTML('beforeend', `<span style="position:absolute;left:0;top:0">${i}</span>`);
i++;}
/* конфигурация */
let width = 300;
let count = 1;
//let list = carousel.querySelector('ul');
let position = 0; // положение ленты прокрутки
.page {
display: flex;
flex-direction: column;
padding: 50px;
justify-content: center;
align-items: center;
}
.place-card{
display: inline-block;
}
.test-container {
display: flex;
flex-direction: column;
align-content: space-between;
justify-content: space-around;
min-height: 200px;
max-width: 400px;
}
.proverka {
display: flex;
justify-content: center;
text-align: center;
}
.block-size {
max-width: 100px;
}
.vopros {
display: flex;
justify-content: center;
text-align: center;
}
.otvet {
display: flex;
justify-content: center;
text-align: center;
}
.otvet-proverka {
display: flex;
justify-content:center;
text-align: center;
}
.btn-margin {
margin-right: 10px;
}
.border-red {
border: solid red 1px;
}
.border-green {
border: solid 1px green;
}
.otvet-variant {
display: flex;
justify-content: center;
text-align: center;
}
.otvet-text {
margin-right: 10px;
}
.otvet-text5 {
margin-right: 10px;
}
.otvet-text6 {
margin-right: 10px;
}
.vopros-text1 {
margin-right: 10px;
}
.vopros-text2 {
margin-right: 10px;
}
.display-none {
display: none;
}
.image {
max-width: 500px;
min-height: 300px;
background-repeat: no-repeat;
background-size: contain;
}
.carousel {
position: relative;
width: 398px;
padding: 10px 40px;
border: 1px solid #CCC;
border-radius: 15px;
background: #eee;
}
.carousel img {
width: 80%;
height: 130px;
display: block;
}
.arrow {
position: absolute;
top: 60px;
padding: 0;
background: #ddd;
border-radius: 15px;
border: 1px solid gray;
font-size: 24px;
line-height: 24px;
color: #444;
display: block;
}
.arrow:focus {
outline: none;
}
.arrow:hover {
background: #ccc;
cursor: pointer;
}
.prev {
left: 7px;
}
.next {
right: 7px;
}
.gallery {
width: 300px;
overflow: hidden;
}
.gallery ul {
height: 300px;
width: 9999px;
margin: 0;
padding: 0;
list-style: none;
transition: margin-left 250ms;
/* удаляем пустое пространство между элементами li, у которых установлен inline-block */
/* http://davidwalsh.name/remove-whitespace-inline-block */
font-size: 20px;
}
.gallery li {
display: inline-block;
width: 300px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<link rel="stylesheet" href="./index.css" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
</head>
<body class="page container">
<div id="carousel" class="carousel ">
<div class="gallery">
<ul>
</ul>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
Ответы (1 шт):
Автор решения: Pavel
→ Ссылка
Решил свой вопрос сам добавив проверку if(document !== null) в функцию
const nextVopros=()=> {
if(document !== null){
let listElems = document.querySelectorAll('li');
let i = 1;
for(let li of carousel.querySelectorAll('li')) {
li.style.position = 'relative';
li.insertAdjacentHTML('beforeend', `<span style="position:absolute;left:0;top:0">${i}</span>`);
i++;
}
position -= width * count;
// последнее передвижение вправо может быть не на 3, а на 2 или 1 элемент
position = Math.max(position, -width * (listElems.length - count));
list.style.marginLeft = position + 'px';
question.answers=[];}
}