代码之家  ›  专栏  ›  技术社区  ›  user23745914

能够访问javascript中的dom元素,而无需显式定义查询选择器

  •  0
  • user23745914  · 技术社区  · 1 年前

    在我的代码中,我正在制作一个简单的库应用程序,在我的javaScript代码中,出于某种原因,在没有检查的情况下,我假设我已经通过变量名定义了一个查询选择器 阅读 对于添加书本按钮弹出菜单中的复选框输入,但我没有,然后我在**提交和取消事件侦听器**中引用了它,没有出现错误。我很困惑为什么会发生这种情况,因为我认为除非使用定义的文档方法之一(例如querySelector())选择元素,否则无法访问它们

    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>Javascript Library</title>
      <link rel="stylesheet" href="style.css">
    </head>
    <body>
      <!-- popup form -->
      <div class="popup-form">
        <button class="cancel">x</button>
        <form class="form">
          <ul>
            <li>
              <label for="title">Title*</label>
              <input type="text" id="title" required>
            </li>
            <li>
              <label for="author">Author*</label>
              <input type="text" id='author' required>
            </li>
            <li>
              <label for="pages">Pages*</label>
              <input type="number" id="pages" min="0" required>
            </li>
            <li>
              <label for="read">Read</label>
              <input type="checkbox" id = 'read'>
            </li>
            <button type='button' class="submit">Submit</button>
          </ul>
        </form>
      </div>
    
      <!-- header -->
      <header>
        <h1 class="title">Fkhadim's Library</h1>
      </header>
      <!-- add book button -->
      <button class="add-book">Add Book</button>
    
      <!-- main article -->
      <div class="book-grid">
        
      </div>
      <script src="script.js"></script>
    </body>
    </html>
    

    CSS

    @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
    
    /* general */
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    li {
      list-style-type: none;
    }
    
    body {
      background-color: rgb(240, 232, 232);
      font-family: 'Poppins', sans-serif;
    }
    
    /* header */
    
    header {
      background-color: #fff;
      height: 15vh;
      display: flex;
      align-items: center;
      justify-content: center;
      color: black;
      font-family: 'Poppins', sans-serif;
      font-size: 25px;
    }
    
    h1 {
      text-align: center;
    }
    
    /* add book button */
    
    .add-book:active {
      background-color: black;
      color: #fff;
      transition-duration: 300ms;
    }
    
    .add-book {
      display: block;
      margin: 0 auto;
      padding: 10px 35px;
      font-size: 22px;
      margin-top: 20px;
      background-color: #fff;
      border: none;
      border: 2px solid black;
      border-radius: 5px;
    }
    
    /* book grid and card styling */
    
    .book-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
      gap: 20px;
      margin: 0 auto;
      margin-top: 20px;
      max-width: 70vw;
      align-items: stretch;
    }
    
    .card {
      background-color: #fff;
      padding: 30px;
      padding-top: 20px;
      display: grid;
      grid-template-columns: 6fr 4fr;
      gap: 10px;
      border: 2px solid black;
    }
    
    .card-title {
      font-size: 30px;
      font-weight: 700;
    }
    
    .card-author {
      font-size: 16px;
      font-weight: 500;
    }
    
    .card-pages {
      font-size: 20px;
    }
    
    .card-read {
      font-size: 18px;
    }
    
    .card-buttons {
      display: flex;
      gap: 10px;
      align-items: flex-end;
    }
    
    .card-buttons button {
      flex: 1;
      height: 25%;
      max-height: 50px;
      background-color: #fff;
      border: none;
      border: 1px solid black;
      border-radius: 3px;
      padding: 0 10px;
    
    }
    
    .card-buttons button:hover {
      background-color: black;
      color: #fff;
      transition-duration: 200ms;
    }
    
    /* popup form */
    .popup-form {
      position: fixed;
      background-color: rgb(240, 232, 232);
      display: none; /*switches to display flex in javascript */
      flex-direction: column;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      border: 2px solid black; 
      border-radius: 10px;
    }
    
    .cancel {
      align-self: flex-end;
      font-size: 20px;
      padding: 3.5px 10px;
      margin-top: 10px;
      margin-right: 10px;
      background-color: red;
      border: none;
      border-radius: 15px;
      border: 1px solid black;
    }
    
    .cancel:active {
      background-color: rgb(175, 13, 13);
    }
    
    .popup-form form ul li label {
      font-size: 25px;
    }
    
    .popup-form form ul li {
      margin-bottom: 10px;
    }
    
    .popup-form form ul li label {
      display: block;
      margin-bottom: 5px;
    }
    
    .popup-form form ul li input {
      padding: 5px;
      border-radius: 3px;
      height: 30px;
      border: 1px solid #ccc;
      font-size: 20px;
    }
    
    .popup-form form ul li:nth-child(4) {
      width: 100%;
      display: flex;
      align-items: center;
      gap: 20px;
    }
    
    #read {
      margin-left: 20px;
    }
    
    form {
      padding: 0 30px;
      padding-bottom: 25px;
    }
    
    .submit {
      padding: 5px 20px;
      font-size: 22px;
      background-color: #fff;
      border: none;
      border: 2px solid black;
      border-radius: 5px;
    }
    
    .submit:active {
      background-color: black;
      color: #fff;
      transition-duration: 200ms;
    }
    
    /* media queries */
    @media (max-width: 640px){
      .book-grid{
        grid-template-columns: 1fr;
      }
      .card-buttons {
        flex-direction: column;
        align-items: stretch;
        justify-content: center;
        height: 100%;
    
      }
      .card {
        padding: 20px;
      }
    }
    
    

    JAVASCRIPT

    const addBook = document.querySelector('.add-book');
    const popupForm = document.querySelector('.popup-form');
    const form = document.querySelector('.form');
    const cancel = document.querySelector('.cancel');
    const submit = document.querySelector('.submit');
    const title = document.querySelector('#title');
    const pages = document.querySelector('#pages');
    const author = document.querySelector('#author');
    const bookgrid = document.querySelector('.book-grid');
    
    function Book(title, author, pages, read){
      this.title = title;
      this.author = author;
      this.pages = pages;
      this.read = read;
    }
    
    Book.prototype.addCard = function(){
      let card = document.createElement('div');
      let cardDesc = document.createElement('div');
      let cardButtons = document.createElement('div');
      let cardTitle = document.createElement('div');
      let cardAuthor = document.createElement('div');
      let cardPages = document.createElement('div');
      let cardRead = document.createElement('div');
      let read = document.createElement('button');
      let del = document.createElement('button');
      card.classList.add('card');
      cardDesc.classList.add('card-desc');
      cardButtons.classList.add('card-buttons');
      cardTitle.classList.add('card-title');
      cardAuthor.classList.add('card-author');
      cardPages.classList.add('card-pages');
      cardRead.classList.add('card-read');
      read.classList.add('read');
      del.classList.add('delete');
    
      read.addEventListener('click', () => {
        if(this.read){
          cardRead.textContent = 'not read'
          this.read = false;
        }
        else {
          cardRead.textContent = 'read'
          this.read = true;
        }
      })
      del.addEventListener('click', () => {
        card.remove();
      })
    
      cardTitle.textContent = this.title;
      cardAuthor.textContent = this.author;
      cardPages.textContent = this.pages;
      cardRead.textContent = this.read ? 'read': 'Not Read'
    
      read.textContent = 'Read';
      del.textContent = 'Delete';
    
      cardDesc.appendChild(cardTitle);
      cardDesc.appendChild(cardAuthor);
      cardDesc.appendChild(cardPages);
      cardDesc.appendChild(cardRead);
    
      cardButtons.appendChild(read);
      cardButtons.appendChild(del);
    
      card.appendChild(cardDesc);
      card.appendChild(cardButtons);
    
      bookgrid.appendChild(card);
    }
    
    
    addBook.addEventListener('click', () => {
      popupForm.style.display = 'flex';
    })
    
    cancel.addEventListener('click', () => {
      popupForm.style.display = 'none';
        title.value = '';
        pages.value = '';
        author.value = '';
        read.checked = false
        
    }) 
    
    submit.addEventListener('click', () => {
      if(form.checkValidity()){
        popupForm.style.display = 'none';
        const newBook = new Book(title.value, author.value, pages.value, read.checked)
        title.value = '';
        pages.value = '';
        author.value = '';
        read.checked = false;
        newBook.addCard()
      }
    })
    
    // example book
    const theHobbit = new Book('The Hobbit', 'George R.R Martin', 576, true);
    theHobbit.addCard();
    

    我试着用不同的方法来记录read变量,但我没能找到这是怎么发生的。我问了chaggpt,它不能给我一个直接的答案,所以我只想了解这是什么。我觉得这可能与我对这种面向对象的编程风格不熟悉有关。

    1 回复  |  直到 1 年前
        1
  •  1
  •   Phix    1 年前

    不确定它在规范中的位置,但添加一个“id”属性会将其分配给窗口。

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <div id="read">I am READ</div>
        <script>
          console.log(read);
        </script>
      </body>
    </html>

    假设这些存在是不好的做法,所以最好使用DOM选择器。