微调器在获取后不会移除 api

The spinner does not remove after fetch api

我有这首歌的歌词应用程序,问题是 api 提取后旋转器没有移除。就像 javascript 没有检测到微调器已经存在,但它存在!当我调用删除函数时。

如果我删除条件:

if(spinnerHtml) {
   spinnerHtml.remove();
};

只留下这个:

spinnerHtml.remove();

所以我得到这个错误: TypeError:无法读取 null 的属性(读取 'remove')。

const form = document.querySelector("#formulario-buscar");
const artistInput = document.querySelector("#artista");
const songInput = document.querySelector("#cancion");
const searchBtn = document.querySelector("#buscar");
const divMessages = document.querySelector("#mensajes");
const divResult = document.querySelector("#resultado");
const headingSong = document.querySelector("#song-name");


function spinner() {
    const spinner = document.createElement("div");
    spinner.classList.add('spinner');
    spinner.setAttribute('id', 'spinner');
    spinner.innerHTML = `
    <div class="rect1"></div>
    <div class="rect2"></div>
    <div class="rect3"></div>
    <div class="rect4"></div>
    <div class="rect5"></div>
    `;
    form.insertBefore(spinner, document.querySelector(".enviar"));
}


let spinnerExist = false;

form.addEventListener("submit", searchSong);


function searchSong(e) {
    e.preventDefault();


        //show spinner
   if(spinnerExist === false) {
       spinner(); 
       spinnerExist = true;
   };

   //consult our API
  const query = new API(artistInput.value,            songInput.value)
  query.consultApi();
}

const spinnerHtml = document.getElementById('spinner');

class API {
    constructor(artist, song) {
        this.artist = artist;
        this.song = song;
    }

    async consultApi() {
        const url = `https://api.lyrics.ovh/v1/${this.artist}/${this.song}`;
        
        try {
            const response = await fetch(url);
            const result = await response.json();
          
            // //when it found the lyrics it delete the spinner
            if(spinnerHtml) {
                spinnerHtml.remove();
            };
            
            
            const {lyrics} = result;

            //here we assign the song lyrics to the DOM
            divResult.textContent = lyrics;
            headingSong.textContent = `Lyrics of ${this.song} from the artist ${this.artist}`;

        } catch (error) {

            console.log(error);
            divMessages.textContent = error;
            divMessages.classList.add("error");

            setTimeout(() => {
                divMessages.textContent = "";
                divMessages.classList.remove("error");
            }, 3000);
        }
    }
}
html{
    min-height: 100%;
    box-sizing: border-box;
}
*, *:before, *:after {
    box-sizing: inherit;
}

body {
    background-image: linear-gradient(to top, #1e3c72 0%, #1e3c72 1%, #2a5298 100%);
    font-family: 'Montserrat', sans-serif;
    min-height: 100%;
}
h1 {
    font-weight: 400;
    text-align: center;
}
h2 {
    text-align: center;
}

.contenido {
    background-color: white;
    max-width: 1100px;
    margin:  0 auto;
    height: 100%;
    padding: 20px;
}


@media (min-width:768px) {
    .contenedor {
        display: flex;
        flex-wrap: wrap;
    }
    .contenedor > div {
        flex: 1 0 50%;
    }
}
.formulario-busqueda p {
    text-align: center;
}
.formulario-busqueda span {
    color: red;
}

.input {
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
}
.input label {
    flex: 0 0 120px;
    text-align: right;
    margin-right: 1rem;
    font-weight: 700;
    text-transform: uppercase;
}
.input span {
    color: red;
}
.input input[type="text"] {
    height: 2.5rem;
    padding: 1rem;
    display: flex;
    flex: 1;
}
.enviar {
    text-align: center;
    justify-content: center;
}
.input input[type="submit"]{
    background-color: #6f86d6;
    padding: .5rem 2rem;
    color: white;
    align-self: flex-end;
    border:none;
    transition: background-color .3s ease-in-out;
} 
.input input[type="submit"]:hover {
    cursor: pointer;
    background-color: #384e9d;
}

.error {
    padding: 1rem;
    border: 1px solid red;
    background-color: rgb(249, 121, 121);
    color: white;
    text-align: center;
}


#resultado {
    white-space: pre-wrap;
    padding: 2rem;
}

.spinner {
    margin: 100px auto;
    width: 50px;
    height: 40px;
    text-align: center;
    font-size: 10px;
  }
  
  .spinner > div {
    background-color: #333;
    height: 100%;
    width: 6px;
    display: inline-block;
    
    -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
    animation: sk-stretchdelay 1.2s infinite ease-in-out;
  }
  
  .spinner .rect2 {
    -webkit-animation-delay: -1.1s;
    animation-delay: -1.1s;
  }
  
  .spinner .rect3 {
    -webkit-animation-delay: -1.0s;
    animation-delay: -1.0s;
  }
  
  .spinner .rect4 {
    -webkit-animation-delay: -0.9s;
    animation-delay: -0.9s;
  }
  
  .spinner .rect5 {
    -webkit-animation-delay: -0.8s;
    animation-delay: -0.8s;
  }
  
  @-webkit-keyframes sk-stretchdelay {
    0%, 40%, 100% { -webkit-transform: scaleY(0.4) }  
    20% { -webkit-transform: scaleY(1.0) }
  }
  
  @keyframes sk-stretchdelay {
    0%, 40%, 100% { 
      transform: scaleY(0.4);
      -webkit-transform: scaleY(0.4);
    }  20% { 
      transform: scaleY(1.0);
      -webkit-transform: scaleY(1.0);
    }
  }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Buscador de Letras - JSModerno</title>
    <link rel="stylesheet" href="https://necolas.github.io/normalize.css/8.0.0/normalize.css">
    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700,900" rel="stylesheet">
    <link rel="stylesheet" href="css/style.css">
</head>
<body>

    <main id="contenido" class="contenido">
            <h1>Letras de Canciones</h1>
            <div class="contenedor">
                    <div id="buscar" class="buscar">
                            <h2>Búsqueda</h2>
                            <p>Busca por artista y nombre:</p>
                            <p><span> * </span>Obligatorio</p>
                            <form action="#" id="formulario-buscar">
                                <div class="input">
                                    <label for="artista">Artista: <span>*</span></label>
                                    <input type="text" id="artista" placeholder="Artista">
                                </div>
                                <div class="input">
                                    <label for="cancion">Canción: <span>*</span></label>
                                    <input type="text" id="cancion" placeholder="Nombre Canción">
                                </div>

                                <div class="input enviar">
                                    <input type="submit" id= "buscar" value="Buscar">
                                </div>
                            </form>
                    </div>
                    
                    <div class="letra-resultado">
                            <h2 id="song-name"></h2>
                            <div id="resultado"></div>
                    </div>
                    <div id="mensajes"></div>
            </div>
    </main>

    
    <script src="js/app.js"></script>
</body>
</html>

我认为在 类 中使用 out-of-scope 变量是一种不好的做法。 class function consultApi 似乎无法访问变量 spinnerHtml。再次尝试使用查询选择 class function consultApi 内的元素。