Я хочу получить значения во входных данных формы и создать новый объект песни внутри массива «песни». Я пытаюсь сделать музыкальное приложение просто для удовольствия, но я застрял. Вот мой 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.info(songs);
}
document.addEventListener("DOMContentLoaded", () => {
document.getElementById("add-song-btn").addEventListener("click", AddSongFunction )
});
Я просто не могу понять это, если кто-то может показать, что пошло не так, я буду благодарен. P.S. это мой первый вопрос, поэтому я надеюсь, что это понятно. Спасибо вам всем (:
Это связано с тем, что getElementsByClassName возвращает HTMLCollection, свойство «значение» может быть получено только для HTMLElement. Таким образом, вы можете выбрать элемент по его положению в этой коллекции, например:
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
};
Это возвращает массив:
document.getElementsByClassName("song-name-add");
Это связано с тем, что классы должны быть повторно используемыми. Если вы хотите, чтобы это возвращало определенное значение, попробуйте использовать
<input type = "text" id = "song-name-add" placeholder = "Song Name">
И
document.getElementById("song-name-add");
Или, если вы специально хотите использовать классы, вы можете получить значение первого объекта с этим классом, используя
document.getElementsByClassName("song-name-add")[0].value;
Вы используете getElementsByClassName, его возвращаемое значение представляет собой массив. Если вы хотите получить доступ к его значению, вам нужно использовать его индекс document.getElementsByClassName("song-name-add")[0].value или цикл в массиве.
Вам нужно использовать document.querySelector() вместо document.getElementsByClassName(). querySelector().value возвращает значение поля ввода, а getElementsByClassName() возвращает коллекцию, как массив. В вашем случае вы можете использовать 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,
};
Один быстрый совет: избегайте использования тега script в head, потому что он блокирует загрузку HTML до тех пор, пока не загрузится весь скрипт.
<script src = "music.app.js"></script>
Либо поместите его над закрывающим тегом </body>, либо используйте свойство async в теге script, используемом в элементе <head>.
<script async src = "music.app.js"></script>
Это делает ваш скрипт неблокирующим
Спасибо за подсказку, я думаю, что это поможет мне в будущем
Не за что ! Проголосуйте и примите ответ, если вы нашли его полезным для других разработчиков.
Если имеется только один из них, используйте идентификатор, а не имя класса, и document.getElementById, а не getElementsByClassName. Имя класса вернет коллекцию и не будет иметь .value — вам нужно будет сослаться на одно из них, возможно, с [0] — например, document.getElementsByClassName("song-name-add")[0].value