В процессе рефакторинга кода после создания класса Сard в консоли выдает ошибку, не видит функции открытия попапа картинки, лайка и удаления

Рейтинг: 0Ответов: 1Опубликовано: 13.07.2023

Помогите плиз завершить рефакторинг кода. Подскажите в чем ошибка, почему не удается "починить" код. Почему не идентифицирует нужные функции? После клика на изображение не открывает попап с картинкой, не нажимается кнопка лайка и не удаляется карточка нажатием на иконку мусорного бака. Есть два файла - index.js и Card.js. После создания класса карточки с названием и изображением код сломался и не функционирует нормально. Скорее всего я делаю что-то не так, но не понимаю где. Буду благодарен за помощь и указание на ошибки.

import { Card } from './Card.js';

// new Card('#element-template', handleCardClick, toggleLike, handleCardDelete);

import { FormValidator } from './FormValidator.js';

const formValidator = new FormValidator({
  formSelector: '.popup__form',
  inputSelector: '.popup__input',
  submitButtonSelector: '.popup__submit-button',
  inactiveButtonClass: 'popup__submit-button_disabled',
  inputErrorClass: 'popup__input-error',
  errorClass: 'popup__input-error'
});

formValidator.enableValidation();

//---------------------ОБЩИЕ-------------------//
const closeButtons = document.querySelectorAll('.popup__close-button');
//-----------------------------ПОПАП ПРОФИЛЬ-----------------------------------------------------//
const buttonOpenPopupProfile = document.querySelector('.profile__edit-button');
const popupProfile = document.querySelector('#profilePopup');
const profileName = document.querySelector('.profile__name');
const profileDetails = document.querySelector('.profile__details');
const inputNameFormProfile = document.querySelector('#profileName-input');
const inputDetailsFormProfile = document.querySelector('#profileDetails-input');
const formProfile = document.querySelector('#profile-form');

//-----------ПОПАП ДОБАВЛЕНИЕ КАРТОЧКИ--------------//
const buttonOpenPopupAddNewCard = document.querySelector('.profile__add-button');
const popupAddNewCard = document.querySelector('#addNewCardPopup');
const formAddNewCard = document.querySelector('#addNewCard-form');
const nameInputFormAddNewCard = document.querySelector('#newCardName-input');
const linkInputFormAddNewCard = document.querySelector('#newCardLink-input');
const buttonSubmitAddNewCard = document.querySelector('#submit-button');

//----------ШАБЛОН КАРТОЧКИ-----------------//
const template = document.querySelector('#element-template');
const templateContent = template.content;
const popupFullImage = document.querySelector('#fullImagePopup');
const popupFullImagePicture = document.querySelector('.popup__fullImage');
const popupFullImageTitle = document.querySelector('.popup__fullImageTitle');
const cardImageTitle = document.querySelector('.element__place-name');
const cardImage = document.querySelector('.element__image');
const popupOverlayElement = document.querySelector('.popup_overlay');
const newCardElement = templateContent.querySelector('.element');
const cardElements = document.querySelector('.elements');

//---------ПОПАП КАРТИНКИ В ПОЛНОМ РАЗМЕРЕ (в классе Card)--------------------------//

function openPopupProfile() {
  inputNameFormProfile.value = profileName.textContent;
  inputDetailsFormProfile.value = profileDetails.textContent;
  openPopup(popupProfile);
}

buttonOpenPopupProfile.addEventListener('click', openPopupProfile);

closeButtons.forEach(button => {
  const popup = button.closest('.popup');
  button.addEventListener('click', () => closePopup(popup));
});

formProfile.addEventListener('submit', function (event) {
  event.preventDefault();
  profileName.textContent = inputNameFormProfile.value;
  profileDetails.textContent = inputDetailsFormProfile.value;
  closePopup(popupProfile);
});

const keyOfEsc = 27;
function handleEscKey(evt) {
  if (evt.keyCode === keyOfEsc) {
    const popup = document.querySelector('.popup_opened');
    closePopup(popup);
  }
}

function handleOverlayClick(evt) {
  const popup = document.querySelector('.popup_opened');
  if (evt.target === popup) {
    closePopup(popup);
  }
}

export function openPopup(popup) {
  popup.classList.add('popup_opened');
  document.addEventListener('keydown', handleEscKey);
  document.addEventListener('mousedown', handleOverlayClick);
}

function closePopup(popup) {
  popup.classList.remove('popup_opened');
  document.removeEventListener('keydown', handleEscKey);
  document.removeEventListener('mousedown', handleOverlayClick);
}

export function handleCardClick(link, name) {
  const popupFullImagePicture = document.querySelector('.popup__fullImage');
  const popupFullImageTitle = document.querySelector('.popup__fullImageTitle');
  const cardImage = this.querySelector('.element__image').src;
  popupImage.src = cardImage;

  popupFullImagePicture.src = link;
  popupFullImagePicture.alt = name;
  popupFullImageTitle.textContent = name;

  openPopup(popupFullImage);
}

// export function toggleLike(event) {
//   const likeButton = event.target;
//   likeButton.classList.toggle('element__like-button_active');
// }
export function toggleLike() {
  const cardLike = newElement.querySelector('.element__like-button');
  cardLike.addEventListener('click', function (event) {
    event.target.classList.toggle('element__like-button_active');
  });
}
// export function handleCardDelete(event) {
//   const deleteButton = event.target;
//   const card = deleteButton.closest('.element');
//   card.remove();
// }
export function handleDeleteCard() {
  const cardDelete = newElement.querySelector('.element__delete-button');
  cardDelete.addEventListener('click', function (event) {
    event.target.closest('.element').remove();
  });
}

function disableSubmitButton() {
  const submitButton = formAddNewCard.querySelector('.popup__submit-button');
  submitButton.setAttribute('disabled', 'true');
  submitButton.classList.add('popup__submit-button_disabled');
}

buttonOpenPopupAddNewCard.addEventListener('click', function () {
  openPopup(popupAddNewCard);
});

formAddNewCard.addEventListener('submit', event => {
  event.preventDefault();
  const form = event.target;

  const item = {
    name: nameInputFormAddNewCard.value,
    link: linkInputFormAddNewCard.value
  };

  const newCard = new Card(item, '#element-template');
  const cardElement = newCard.generateCard();
  document.querySelector('.elements').prepend(cardElement);

  closePopup(popupAddNewCard);

  disableSubmitButton();

  event.target.reset(form);
});
    //------------------------Класс Card--------------------//
       export const items = [
  {
    name: 'Архыз',
    link: 'https://pictures.s3.yandex.net/frontend-developer/cards-compressed/arkhyz.jpg'
  },
  {
    name: 'Челябинская область',
    link: 'https://pictures.s3.yandex.net/frontend-developer/cards-compressed/chelyabinsk-oblast.jpg'
  },
  {
    name: 'Иваново',
    link: 'https://pictures.s3.yandex.net/frontend-developer/cards-compressed/ivanovo.jpg'
  },
  {
    name: 'Камчатка',
    link: 'https://pictures.s3.yandex.net/frontend-developer/cards-compressed/kamchatka.jpg'
  },
  {
    name: 'Холмогорский район',
    link: 'https://pictures.s3.yandex.net/frontend-developer/cards-compressed/kholmogorsky-rayon.jpg'
  },
  {
    name: 'Байкал',
    link: 'https://pictures.s3.yandex.net/frontend-developer/cards-compressed/baikal.jpg'
  }
];

const popupElement = document.querySelector('#fullImagePopup');
const popupImage = document.querySelector('.popup__fullImage');
const popupImageTitle = document.querySelector('.popup__fullImageTitle');
const cardElements = document.querySelector('.elements');

export { popupElement, popupImage, popupImageTitle };

export class Card {
  constructor(data, templateSelector, handleCardClick, toggleLike, handleDeleteCard) {
    this._name = data.name;
    this._link = data.link;
    this._templateSelector = templateSelector;
    this._handleCardClick = handleCardClick;
    this._toggleLike = toggleLike;
    this._handleDeleteCard = handleDeleteCard;
  }

  _getTemplate() {
    const cardElement = document
      .querySelector(this._templateSelector)
      .content.querySelector('.element')
      .cloneNode(true);

    return cardElement;
  }
  generateCard() {
    this._element = this._getTemplate();

    this._cardImage = this._element.querySelector('.element__image');
    this._cardImage.src = this._link;
    this._cardImage.alt = this._name;
    this._cardDeleteButton = this._element.querySelector('.element__delete-button');
    this._cardLikeButton = this._element.querySelector('.element__like-button');
    this._element.querySelector('.element__place-name').textContent = this._name;

    this._setEventListeners();

    return this._element;
  }

  _handleCardClick() {
    openPopup(popupElement);
  }

  _toggleLike(event) {
    event.target.classList.toggle('element__like-button_active');
  }
  _handleDeleteCard() {
    this._element.remove();
  }

  _setEventListeners() {
    this._cardImage.addEventListener('click', () => {
      this._handleCardClick(this._link, this._name);
    });
    this._cardDeleteButton.addEventListener('click', () => {
      this._handleDeleteCard(this);
    });
    this._cardLikeButton.addEventListener('click', () => {
      this._toggleLike(this);
    });
  }
  // _createCard(items) {
  //   const card = new Card(items, '#element-template');
  //   const cardElement = card.generateCard();
  //   return cardElement;
  // }
}

items.forEach(item => {
  const card = new Card(item, '#element-template');
  const cardElement = card.generateCard();
  cardElements.prepend(cardElement);
});

//-------------HTML---------------//
 <header class="header">
      <img class="header__logo" src="./images/logo__image.svg" alt="логотип Mesto Russia" />
    </header>
    <main class="main">
      <section class="profile">
        <img class="profile__avatar" src="./images/avatar__image.jpg" alt="аватар" />
        <div class="profile__info">
          <h1 class="profile__name">Жак-Ив Кусто</h1>
          <button aria-label="Open" type="button" class="profile__edit-button"></button>
          <p class="profile__details">Исследователь океана</p>
        </div>
        <button aria-label="Open" type="button" class="profile__add-button"></button>
      </section>

      <section class="elements"></section>
      <!--вставляем сюда шаблон-->
    </main>

    <footer class="footer">
      <p class="footer__text">© 2023 Mesto Russia</p>
    </footer>

    <div id="profilePopup" class="popup">
      <div class="popup__container">
        <form name="add-form" id="profile-form" class="popup__form" novalidate>
          <h2 class="popup__title">Редактировать профиль</h2>
          <input
            name="profileName"
            id="profileName-input"
            type="text"
            class="popup__input"
            minlength="2"
            maxlength="40"
            required
          />
          <p class="popup__span-paragraph">
            <span class="popup__input-error profileName-input-error"></span>
          </p>
          <input
            name="profileDetails"
            id="profileDetails-input"
            type="text"
            class="popup__input"
            minlength="2"
            maxlength="200"
            required
          />
          <p class="popup__span-paragraph">
            <span class="popup__input-error profileDetails-input-error"></span>
          </p>
          <button type="submit" class="popup__submit-button">Сохранить</button>
        </form>
        <button
          aria-label="Close"
          type="button"
          class="popup__close-button popup__close-button_profile"
        ></button>
      </div>
    </div>

    <div id="addNewCardPopup" class="popup">
      <div class="popup__container">
        <form name="new-card" id="addNewCard-form" class="popup__form" novalidate>
          <h2 class="popup__title">Новое место</h2>
          <input
            name="item-name"
            id="newCardName-input"
            type="text"
            class="popup__input"
            minlength="2"
            maxlength="30"
            required
            placeholder="Название"
          />
          <p class="popup__span-paragraph">
            <span class="popup__input-error newCard-input-error"></span>
          </p>
          <input
            name="item-link"
            id="newCardLink-input"
            type="url"
            class="popup__input"
            placeholder="Ссылка на картинку"
            required
          />
          <p class="popup__span-paragraph">
            <span class="popup__input-error newCardLink-input-error"></span>
          </p>
          <button type="submit" id="submit-button" class="popup__submit-button" disabled>
            Создать
          </button>
        </form>
        <button
          aria-label="Close"
          type="button"
          class="popup__close-button popup__close-button_addNewCard"
        ></button>
      </div>
    </div>

    <template id="element-template" class="template">
      <article class="element">
        <img class="element__image" src="#" title="" alt="#" />
        <button class="element__delete-button"></button>
        <div class="element__place">
          <h3 class="element__place-name"></h3>
          <button type="button" class="element__like-button"></button>
        </div>
      </article>
    </template>

    <div id="fullImagePopup" class="popup popup_overlay">
      <div class="popup__container popup__container_zoom">
        <button
          aria-label="Close"
          type="button"
          class="popup__close-button popup__close-button_fullImage"
        ></button>
        <img class="popup__fullImage" src="#" title="" alt="#" />
        <figcaption class="popup__fullImageTitle"></figcaption>
      </div>
    </div>
  </body>
</html>
введите сюда описание изображения

Ответы

▲ 0

Импортируйте items из Card и перенесите вызов в конец index.js, при вызове добавьте функции которые ожидает класс (handleCardClick, toggleLike, handleDeleteCard):

items.forEach(item => {
  const card = new Card(item, '#element-template', handleCardClick, toggleLike, handleDeleteCard);
  const cardElement = card.generateCard();
  cardElements.prepend(cardElement);
});

У функции handleCardClick неправильная константа:

const cardImage = this.querySelector('.element__image').src; //Неправильно
const cardImage = document.querySelector('.element__image').src; //Правильно

На следующей строке сразу же несуществующая переменная, вы перепутали popupImage с popupFullImage:

popupImage.src = cardImage; //Ошибка popupImage is not defined
popupFullImage.src = cardImage; //Теперь всё нормально

Когда вешали обработчик ошиблись в имени функции, handleCardDelete не существует:

formAddNewCard.addEventListener('submit', event => {
  //...
  const newCard = new Card(item, '#element-template', handleCardClick, toggleLike, handleCardDelete); //а, вот handleDeleteCard существует
  //...
});

В функциях toggleLike и handleDeleteCard происходит поиск элементов в несуществующей переменной:

export function toggleLike() {
  const cardLike = newElement.querySelector('.element__like-button'); //newElement is not defined
//...
}

export function handleDeleteCard() {
  const cardDelete = newElement.querySelector('.element__delete-button'); //newElement is not defined
//...
}

P.S. Судя по внешнему виду сайта вы проходите онлайн курс, можете смело задавать вопросы в чате своей группы, вам точно помогут и возможно даже быстрее чем здесь.