首页 > 解决方案 > 将数据循环到 DOM 后如何从 api 捕获数据

问题描述

我创建了一个名为的全局变量movieID,并且我有一个调用函数,该函数generateSearch 从 API 获取数据,然后该displayResults函数循环遍历结果并在 DOM 上显示数据。

我的目标是插入一个事件侦听器,当您点击电影的特定标题 ( #more-details) 时,该movieID变量将获取点击电影的 ID!

//GLOBAL VARIABLES
let resultArr = [];
let movieID;

//EVENT LISTENER
submitBtn.addEventListener('click', generateSearch)

//GENERATE SEARCH DATA
async function generateSearch() {
    resultArr = []

    const result = await fetch(`${baseURL}${search}${userInput.value}${apiKey}`)
    const data = await result.json();

    //push data in array
    data.Search.forEach(element => {
        resultArr.push(element)
    })
    console.log(resultArr)

    displayResults()
}

//DISPLAY ON UI
function displayResults() {
    clearUI()
    resultArr.forEach(movie => {
        const markup = `
       
        <div class="results">
            <img src="${movie.Poster}" alt="Movie Poster">
            <ul>
                <a href="#" id="more-details"><li>${movie.Title}</li></a>
                <li>${capitalizeFirstLetter(movie.Type)}</li>
                <li>${movie.Year}</li>
                <li>${movie.imdbID}</li>
            </ul>
            </div>
            
    `
        resultUI.insertAdjacentHTML('afterbegin', markup)

    })
    moviePage()
}

标签: javascriptarraysapiloopsdom

解决方案


您应该尽量避免使用全局变量。这里有一个在评论中有解释的解决方案:

//EVENT LISTENER
submitBtn.addEventListener('click', event => generateSearch(event.target.value))
document.body.addEventListener('click', event => { // For every click...
    const clickedElement = event.target // Get the clicked element
    const movieId = clickedElement.dataset.movieId
    if (movieId) {
        // Do something with the movieId
        // ...
    }
})


//GENERATE SEARCH DATA
async function generateSearch(query) {
    const result = await fetch(`${baseURL}${search}${query}${apiKey}`)
    const data = await result.json();

    const nodes = getResultsAsArrayOfNodes(data.Search)

    //DISPLAY ON UI
    // searchResultElement should be a DOM node in which all the results will be appended
    searchResultElement.append(...nodes) // Append all the nodes (https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append)
}

function getResultsAsArrayOfNodes(movies) {
    return movies.map(movie => { // For each movie...
        const node = document.createElement('div') // ...create a node..
        node.className = 'results'
        const markup = `
            <img src="${movie.Poster}" alt="Movie Poster">
            <ul>
                <!-- Create here an element with an id that contains the IMDB movie id -->
                <li><a href="#" data-movie-id="${movie.imdbID}">${movie.Title}</a></li>
                <li>${capitalizeFirstLetter(movie.Type)}</li>
                <li>${movie.Year}</li>
                <li>${movie.imdbID}</li>
            </ul>
        `
        node.innerHTML = markup // ...put the markup in the div.results node
        return node // return the node
    }) // Return the array of nodes
}

推荐阅读