为什么新对象的输入值未定义?

Why is the input value of the new object is undefined?

我想获取表单输入中的值并在“歌曲”数组中创建一个新的歌曲对象。 我只是为了好玩而尝试制作一个音乐应用程序,但我被卡住了。 这是我的 HTML 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="music.app.js"></script>
    <link rel="stylesheet" href="music.app.try.css">
    <title>Music App</title>
</head>
<body>
    <div class="add-song-continer" id="add-song-continer">
        <form id="add-song-form">
          <button class="close-btn" id="close-add-song">X</button>
          <h1 class="h1-add-Song" >Add your song </h1>
          <br>
          <input type="text" class="song-name-add" placeholder="Song Name" value=""><br>
          <br>
          <input type="text" class="artist-name-add" placeholder="Artist Name"><br>
          <br>
          <input type="text" class="albom-name-add" placeholder="Albom Name"><br>
          <br>
          <input type="text" class="mp3-file-add" placeholder="Song File"><br>
          <br>
          <input type="text" class="img-add" placeholder="Image"><br>
          <button class="add-song-btn" id = "add-song-btn"> Add Song</button>
        </form>
      </div>
</body>
</html>

这是CSS代码

.add-song-continer {
    margin:0;
    background-color: #FFF;
    position: fixed;
    display: flex;
    top:20%;
    left:50%;
    width:45%;
    min-width: 250px;
    max-width: 250px;
    height: 460px;
    border: 1px solid black;
    box-shadow: 0.5rem 1rem 2rem grey ;
    transform:translateX(-50%) translateY(00%)
    }

.add-song-continer input{
    margin-left: 2.5rem;
    margin-bottom: 0rem;
    padding: 0.5rem;
    background-color: rgb(241, 239, 239);
    border: 1px solid gray;
   }
.add-song-continer label{
    margin: 2.5rem;
    padding-top: 1rem;
   }
.add-song-continer  h1{
    margin: 1rem;
    padding: 0.5rem;
    text-align: center;
   }
   .add-song-btn{
    position: relative;
    margin: auto;
    margin-top: 5%;
    margin-bottom: 10%;
    padding: 0.4rem;
    left: 50%;
    background: linear-gradient(to right, #66ccff 0%, #cc99ff 100%);
    border:1px solid lightgrey;
    border-radius: 3px;
    transform: translateX(-50%);
    animation: grediant-add-song 0.7s ease-out 0s infinite ;
   }

.close-btn {
    margin: 2%;
    margin-top: -4%;
    padding: 0.4rem 0.4rem;
    position: relative;
    float: right;
    background-color: tomato;
    border-radius: 3px;
    border: none;
    box-shadow: 1 1 1 gray;
   }



@keyframes grediant-add-song {
    0% {background: linear-gradient(to right, #66ccff 0%, #cc99ff 100%)}
    12.5% {background: linear-gradient(to right bottom, #66ccff 0%, #cc99ff 100%)}
    25% {background: linear-gradient(to bottom, #66ccff 0%, #cc99ff 100%)}
    37.5% {background: linear-gradient(to bottom left, #66ccff 0%, #cc99ff 100%)}
    50% {background: linear-gradient(to left, #66ccff 0%, #cc99ff 100%)}
    62.5% {background: linear-gradient(to left top, #66ccff 0%, #cc99ff 100%)}
    75% {background: linear-gradient(to top, #66ccff 0%, #cc99ff 100%)}
    87.5% {background: linear-gradient(to top right, #66ccff 0%, #cc99ff 100%)}
    100% {background: linear-gradient(to right, #66ccff 0%, #cc99ff 100%)}
   }

这是JavaScript代码

let songs = [];

const AddSongFunction = (ev) => {
  ev.preventDefault();

   let song = { 
      name: document.getElementsByClassName("song-name-add").value, 
      artist: document.getElementsByClassName("artist-name-add").value,
      albom: document.getElementsByClassName("albom-name-add").value,
      fill: document.getElementsByClassName("mp3-file-add").value,
      img: document.getElementsByClassName("img-add").value
      };
      
  songs.push(song);
  document.querySelector("form").reset();

    console.log(songs);
    }

  document.addEventListener("DOMContentLoaded", () => {
    document.getElementById("add-song-btn").addEventListener("click", AddSongFunction )
  });

我就是想不通,如果有人能指出哪里出了问题,我将不胜感激。 P.S。这是我的第一个问题,所以我希望它是可以理解的。 谢谢大家(:

这是因为 getElementsByClassName return 是一个 HTMLCollection,“值”属性 只能在 HTMLElement 上获取。因此,您可以 select 一个元素在该集合中的位置,例如:

let song = { 
      name: document.getElementsByClassName("song-name-add")[0].value, 
      artist: document.getElementsByClassName("artist-name-add")[0].value,
      albom: document.getElementsByClassName("albom-name-add")[0].value,
      fill: document.getElementsByClassName("mp3-file-add")[0].value,
      img: document.getElementsByClassName("img-add")[0].value
      };

这 return 是一个数组:

document.getElementsByClassName("song-name-add");

这是因为 classes 应该是可重用的。如果你想要这个 return 一个特定的值尝试使用

<input type="text" id="song-name-add" placeholder="Song Name">

document.getElementById("song-name-add");

或者,如果您特别想使用 classes,您可以使用

获取具有 class 的第一个对象的值
document.getElementsByClassName("song-name-add")[0].value;

您正在使用 getElementsByClassName,其 return 值是一个数组。 如果你想访问它的值,你必须使用它的索引 document.getElementsByClassName("song-name-add")[0].value 或在 Array

上循环

您需要使用 document.querySelector() 而不是 document.getElementsByClassName()。 querySelector().valuereturns输入框的值,而getElementsByClassName()returns集合只是像一个数组。你可以在你的情况下使用 getElementsByClassName().value[0] 但更好的是只使用 querySelector().

这是更新后的歌曲对象:

   let song = {
      name: document.querySelector(".song-name-add").value,
      artist: document.querySelector(".artist-name-add").value,
      albom: document.querySelector(".albom-name-add").value,
      fill: document.querySelector(".mp3-file-add").value,
      img: document.querySelector(".img-add").value,
    };

一个快速提示: 避免在 head 中使用 script 标记,因为在所有脚本加载之前阻止 HTML 加载.

<script src="music.app.js"></script>

要么将其放在结束 </body> 标记上方,要么在 <head> 元素中使用的脚本标记中使用 async 属性。

<script async src="music.app.js"></script>

它使您的脚本无阻塞