Я вызываю прослушиватель событий на кнопке, и он не создаст html-элемент в моем DOM

#javascript #html #css #class

#javascript #HTML #css #класс

Вопрос:

У меня есть несколько <li> тегов под <ul> в моем HTML-коде. Они <li> оформлены с помощью CSS для создания карточек с заголовком и описанием.

Я создал кнопку с прослушивателем событий, в которой я хочу создать новый <li> элемент под <ul> тегом в HTML, когда я нажимаю кнопку.

Я извлекаю <ul> и пытаюсь appendChild() создать новый <li> . Это все в классе в JS. Я не уверен, почему новые <li> карточки не отображаются при нажатии кнопки.

 ```     
    
     class DOMHelper {
      static clearEventListeners(element) {
        const clonedElement = element.cloneNode(true);
        element.replaceWith(clonedElement);
        return clonedElement;
      }
    
    
  //receives element ID and a New destination in the DOM and sends the 
    //card to that destination Via Append.
      static moveElement(elementId, newDestinationSelector) {
        const element = document.getElementById(elementId);
        const destinationElement = 
    document.querySelector(newDestinationSelector);
        destinationElement.append(element);
      }
    }
    
    class Tooltip {}
    
    class ProjectItem {
      constructor(id, updateProjectListsFunction, type) {
        this.id = id;
        this.updateProjectListsHandler = updateProjectListsFunction;
        this.connectMoreInfoButton();
        this.connectSwitchButton(type);
      }
    
      connectMoreInfoButton() {}
    
    
      //retreives the button of the given DOM element and adds an event 
      //listener to it that executes updateProjectListHandler
      //recieves from: update () {}
      //runs updateProjectListsHandler --> this.switchProject --> 
      
  connectSwitchButton(type) {
        const projectItemElement = document.getElementById(this.id);
        let switchBtn = projectItemElement.querySelector('button:last-of- 
   type');
        switchBtn = DOMHelper.clearEventListeners(switchBtn);
        switchBtn.textContent = type === 'active' ? 'Finish' : 'Activate';
        switchBtn.addEventListener(
          'click', 
          this.updateProjectListsHandler.bind(null, this.id)
        );
      }
    
      update(updateProjectListsFn, type) {
        this.updateProjectListsHandler = updateProjectListsFn;
        this.connectSwitchButton(type);
      }
    }
    
    class ProjectList {
      projects = [];
    
      constructor(type) {
        //selects all of the li elements under the `#${type}-projects DOM 
        //element depending on the element input type 
        //and creates a new ProjectItem for every li element it found. 
        this.type = type;
        const prjItems = document.querySelectorAll(`#${type}-projects 
       li`);
        for (const prjItem of prjItems) {
          this.projects.push(
            new ProjectItem(prjItem.id, this.switchProject.bind(this), 
    this.type)
          );
        }
       
        //new DayOfWeek('Monday');
        console.log(this.projects);
      }
    
      setSwitchHandlerFunction(switchHandlerFunction) {
        this.switchHandler = switchHandlerFunction;
      }
    
    
      //pushes project to the projects array. Project input is "new 
    //ProjectList('finished');"
      addProject(project) {
        this.projects.push(project);
        DOMHelper.moveElement(project.id, `#${this.type}-projects ul`);
        project.update(this.switchProject.bind(this), this.type);
      }
    
      //finds every project id in projects with the id matching constant 
      //projectId
      //filters out every dom object with id that does not equal the 
      //projected input to the function
      switchProject(projectId) {
        // const projectIndex = this.projects.findIndex(p => p.id === 
    projectId);
        // this.projects.splice(projectIndex, 1);
        this.switchHandler(this.projects.find(p => p.id === projectId));
        this.projects = this.projects.filter(p => p.id !== projectId);
        console.log('Testing this button')
      }
    
    
      switchDayHandler() {
        const selectDayOfWeek = document.getElementById('p4');
        //const dayOfWeek = selectDayOfWeek.querySelector('li')
        selectDayOfWeek.addEventListener(
          'click',
          this.updateDayInfoHandler()
        );
        console.log(selectDayOfWeek);
      }
    
      updateDayInfoHandler () {
        console.log('TEST TEST TEST');
    
      }
    
    }
    
    class DayOfWeek {
    
    projectList = {
      monday: [
        {
          title: 'test',
          description: "test"
        }
      ]
    }
    
    
    constructor(day) {
    
    this.createNewButton;
    
    
    
          switch (day) {
              case ( 'Monday' ):
                //this.addNewListItemHandler();   
                  break;
              case ( 'Tuesday' ):      
                console.log('Tuesday');
                  break;
              case ( 'Wednesday' ):
                console.log('Wednesday');
                  break;
              case ( 'Thursday' ):
                console.log('Thursday');
                  break;
              case ( 'Friday' ):
                  console.log('Friday');
                  break;
              //default:
                //  ingredient = null;
          }
         
      }
    
    
    
    addNewListItemHandler() {
          
          const projectItem = document.getElementById('active');
          const newListItem = document.createElement('li');
          newListItem.innerHTML = `id="p2"
          data-extra-info="Not really a business topic but still 
          important."
          class="card"
          >
                <h2>MONDAY ITEM</h2>
                <p>Don't forget to pick up groceries today.</p>
                <button class="alt">More Info</button>
                <button>Finish</button>
                `;
          projectItem.appendChild(newListItem);
      }
    
      createNewButton() {
        const newButton = document.getElementById('addButton');
        newButton.addEventListener( 'click', this.addNewListItemHandler);
      
      }
    
    
    }
    
    
    
    
    
    class App {
      static init() {
        const activeProjectsList = new ProjectList('active');
        const finishedProjectsList = new ProjectList('finished');
        
        activeProjectsList.setSwitchHandlerFunction(
          finishedProjectsList.addProject.bind(finishedProjectsList)
        );
        finishedProjectsList.setSwitchHandlerFunction(
          activeProjectsList.addProject.bind(activeProjectsList)
        );
      }
    }

    App.init();

   ```

    <body>
  
    <header id="main-header">
      <h1>Project Planner</h1>
    </header>

    <div>
    <section id="days-projects">
      <header>
        <h2>Days</h2>
      </header>
      <ul>
        <li
          id="p4"
          data-extra-info="Super important conference! Fictional but 
          still!"
          class="card"
        >
          <h2>Monday</h2>
        </li>
        <li
          id="p5"
          data-extra-info="Super important conference! Fictional but 
           still!"
          class="card"
        >
          <h2>Tuesday</h2>
        </li>
        <li
          id="p6"
          data-extra-info="Super important conference! Fictional but 
          still!"
          class="card"
        >
          <h2>Wednesday</h2>
        </li>
        <li
          id="p7"
          data-extra-info="Super important conference! Fictional but 
          still!"
          class="card"
        >
          <h2>Thursday</h2>
        </li>
        <li
          id="p8"
          data-extra-info="Super important conference! Fictional but 
          still!"
          class="card"
        >
          <h2>Friday</h2>
        </li>
      </ul>
    </section>
    <section id="active-projects">
      <header>
        <h2>Active Projects</h2>
      </header>
      <ul id = 'active'>
        <li
          id="p1"
          data-extra-info="Got lifetime access, but would be nice to 
          finish it soon!"
       class="card"
        >
          <h2>Finish the Course</h2>
          <p>Finish the course within the next two weeks.</p>
          <button class="alt">More Info</button>
          <button>Finish</button>
        </li>
        <li
          id="p2"
          data-extra-info="Not really a business topic but still 
          important."
          class="card"
        >
          <h2>Buy Groceries</h2>
          <p>Don't forget to pick up groceries today.</p>
          <button class="alt">More Info</button>
          <button>Finish</button>
        </li>
      </ul>
     </section>

     <section id="finished-projects">
      <header>
        <h2>Finished Projects</h2>
      </header>
      <ul>
        <li
          id="p3"
          data-extra-info="Super important conference! Fictional but 
          still!"
          class="card"
        >
          <h2>Book Hotel</h2>
          <p>
            Academind conference takes place in December, don't forget to 
            book a hotel.
          </p>
          <button class="alt">More Info</button>
          <button>Activate</button>
        </li>
      </ul>
     </section>

   

     </div>
    
      <button id = "addButton" class='add_Button'>ADD NEW</button>
    
    < /body>
    </html>

    ```css
    * {
      box-sizing: border-box;
    }

    html {
      font-family: sans-serif;
    }

    body {
      margin: 0;
    }

    #main-header {
      width: 100%;
      height: 6rem;
      display: flex;
      justify-content: center;
      align-items: center;
      background: #a3d2ca;
    }

    #main-header h1 {
      color: white;
      margin: 0;
    }

    footer {
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      text-align: center;
    }

    ul {
      list-style: none;
      margin: 0;
      padding: 0;
    }

    li {
      margin: 1rem 0;
      
    }

    section {
      margin: 1rem auto;
      width: 40rem;
      max-width: 90%;
      height: 100%;
      border-radius: 10px;
      
      
    }

    section ul {
      padding: 1rem;
      max-height: 30rem;
      overflow: scroll;
    }

    .Days {
      padding: 1rem;
      max-height: 20rem;
      
      background: #d49a89;
      padding: 1rem;
      display: flex;
      justify-content: space-between;
      align-items: center;
      /*border: 1px solid #ff0062;*/
      margin: 0;
    }

    section > h2 {
      color: white;
      margin: 0;
      border-radius: 10px;
    }

    button {
      font: inherit;
      background: #f7d1ba;
      color: white;
      border: 1px solid #f7d1ba;
      padding: 0.5rem 1.5rem;
      cursor: pointer;
    }

    button.alt {
      background: white;
      color: #ff0062;
    }

    button:focus {
      outline: none;
    }

    button:hover,
    button:active {
      background: #f7d1ba;
      border-color: #5eaaa8;
      color: white;
    }

    .card {
      border-radius: 10px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
      padding: 1rem;
      background: white;
      
    }

    #active-projects {
      border: 2px solid #d49a89;
      margin: 10px;
      width: 30%;
      border-radius: 10px;

    }

    #active-projects > header {
      background: #d49a89;
      padding: 1rem;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    #active-projects header h2 {
      color: white;
      margin: 0;
    }

    #finished-projects {
      border: 2px solid #d49a89;
      margin: 10px;
      width: 30%;
      border-radius: 10px;

    }

    #finished-projects > header {
      background: #d49a89;
      padding: 1rem;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    #finished-projects header h2 {
      color: white;
      margin: 0;
      border-radius: 10px;
    }

    div {
      display: flex;
      flex-direction: row;
      align-items: stretch;
      justify-content: center;
      height: 35rem;
      
      
    }


    #days-projects {
      border: 2px solid #d49a89;
      margin: 10px;
      width: 30%;
      border-radius: 10px;


    }

    #days-projects > header {
      background: #d49a89;
      padding: 1rem;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    #days-projects header h2 {
      color: white;
      margin: 0;
    }

    #days-projects li:hover {
      background: #5eaaa8;
    }

    .add_Button {
      align-items: center;
      border: solid red;
    }
 ```
  

Комментарии:

1. вы создаете другой <li></li> внутри <li> тега?

2. Пожалуйста, добавьте HTML и CSS, связанные с этим — возможно, это центральная проблема

3. Хорошо, я добавлю. Спасибо! и если кажется, что я создаю другой <li> внутри <li>, то это не мое намерение. Я просто хочу создать его в <ul>

4. Вы где-нибудь создаете экземпляр класса DayOfWeek?

5. Нет, я не такой? Где было бы правильное место для этого? Я думаю, что это может быть проблемой…

Ответ №1:

Похоже, что может возникнуть несколько проблем (как упоминает @CodeCreate, вы добавляете li внутри li, и я не уверен, почему вы дважды вызываете createNewButton), но я подозреваю, что основная проблема, о которой вы спрашиваете, связана с вашим вызовом addEventListener.

Вам нужно передать addEventListener функцию для запуска при срабатывании события.

Вы пытаетесь передать this.addNewListItemHandler, но поскольку вы добавили круглые скобки в его конце, вы немедленно вызываете функцию, а не подключаете ее к запуску при нажатии кнопки.

Попробуйте переписать свой метод createNewButton как:

newButton.addEventListener( ‘click’, this.addNewListItemHandler );

Комментарии:

1. Я пытался использовать newButton.addEventListener( ‘click’, this.addNewListItemHandler ); но это все равно не сработало. Я буду продолжать пытаться. Это странно … даже если я попытаюсь что-то console.log() вместо вызова функции на кнопке… это все еще не работает

Ответ №2:

Попробуйте создать экземпляр класса после его определения:

пусть DaysOfWeek = новый DaysOfWeek

Вероятно, для начала это не обязательно должен быть класс, но поскольку это скорее дизайнерское решение, я оставлю это для вас, чтобы исследовать и решить.

Комментарии:

1. Мне также было интересно, должен ли он быть в классе. Я использовал классы для практики ООП, но это может быть случай, когда это не нужно, я попробую вашу рекомендацию. Спасибо!