简体   繁体   English

我如何遍历所有ID?

[英]How do I iterate through all the id's?

Check out the api --> https://api.icndb.com/jokes/random/10 查看api-> https://api.icndb.com/jokes/random/10

Everytime when the user clicks on a specific joke, it will be added to the favorite list. 每当用户单击特定的笑话时,它将被添加到收藏夹列表中。

To keep the code concise I will only show the function itself: 为了使代码简洁,我将仅显示函数本身:

  (function() { "use strict"; const getJokesButton = document.getElementById('getData'); getJokesButton.addEventListener('click', getData); loadLocalStorage(); function loadLocalStorage() { let storage = JSON.parse(localStorage.getItem('favoList')) || []; let listOfFavorites = document.getElementById("favorites"); let emptyArray = ''; if(storage.length > 0) { for(let i = 0; i < storage.length; i++) { let idNumberJoke = storage[i].id; emptyArray += `<li><input type="checkbox" id='${idNumberJoke}'/> User title: ${storage[i].joke}</li>`; listOfFavorites.innerHTML = emptyArray; } } else { return false; } } // fetch data from api function getData() { let listOfJokes = document.getElementById("list-of-jokes"); fetch('https://api.icndb.com/jokes/random/10') .then(function(res) { return res.json(); }).then(function(data) { // variable is undefined because it is not initialized. Therefore at some empty single quotes let result = ''; console.log(data.value); data.value.forEach((joke) => { result += `<li><input type="checkbox" class='inputCheckbox' id='${joke.id}'/> User title : ${joke.joke}</li>`; listOfJokes.innerHTML = result; }); bindCheckbox(); }).catch(function(err) { console.log(err); }); } function clickedButton() { getJokesButton.setAttribute('disabled', 'disabled'); getJokesButton.classList.add('opacity'); } function bindCheckbox() { let inputCheckbox = document.querySelectorAll('input[type=checkbox]'); let elems = document.getElementById('list-of-jokes').childNodes; let favoriteList = document.getElementById('favorites'); let fav = JSON.parse(localStorage.getItem('favoList'))|| []; if(elems.length > 0) { inputCheckbox.forEach(function(element, index) { inputCheckbox[index].addEventListener('change', function() { let joke = this; if(joke.checked && joke.parentNode.parentNode.id === 'list-of-jokes') { joke.checked = false; favoriteList.appendChild(joke.parentNode); addFavorite(joke.id, joke.parentNode.innerText, fav); } if(joke.checked && joke.parentNode.parentNode.id === 'favorites') { joke.checked = false; removeFavorite(joke, index); } }); }); } clickedButton(); } function removeFavorite(favorite, index) { let favoriteCheckBox = favorite; let i = index; // convert iterable object to an array, otherwise splice method would give an error. let favoriteListItem = Array.from(favoriteCheckBox.parentNode); favoriteListItem.splice(i, 1); document.getElementById('list-of-jokes').appendChild(favorite.parentNode); localStorage.setItem('favoList', JSON.stringify(favoriteListItem)); } // store favorites in localStorage function addFavorite(jokeId, jokeText, fav) { let norrisJoke = { id: jokeId, joke: jokeText }; let favorites = fav; for (let i = 0; i < favorites.length; i++) { if(favorites[i].id !== norrisJoke.id) { favorites.push(norrisJoke); } } // favorites[i].id !== norrisJoke.id // always get the object before the push method and pass it into stringify localStorage.setItem('favoList', JSON.stringify(favorites)); } // function which will randomly add one joke to favorite list every 5 seconds // function need a button which allows you to turn on and off this auto add function })(); 
 <div class="inner-body"> <button id="getData">GET Jokes</button> <div class='inner-block'> <h2>Chuck Norris Jokes</h2> <ul class='unordered-list' id="list-of-jokes"> </ul> </div> <div class='inner-block'> <h2>Favorites</h2> <ul class='unordered-list' id="favorites"> </ul> </div> </div> 

The keys and values would not be pushed into localStorage, the only thing I see is an empty [] in localStorage. 键和值不会被推入localStorage,我唯一看到的是localStorage中的空[]。 The norrisJoke object literal will be dynamically changed. norrisJoke对象文字将被动态更改。 So how could I make this function works? 那么如何使此功能起作用?

Too complex, but click on the link below and scroll down to the bottom: 太复杂了,但是请点击下面的链接并向下滚动到底部:

https://codepen.io/chichichi/pen/Gyzzvb https://codepen.io/chichichi/pen/Gyzzvb

let favorites = JSON.parse(localStorage.getItem('favoList'))|| {};

favorites[norrisJoke.id] =norrisJoke.joke 

Why don't you use a map in place of an array? 为什么不使用映射代替数组?

Also as @fl9 points out your for loop will never start off! 就像@ fl9指出的那样,您的for循环将永远不会开始! because favorites.length is 0 to begin with 因为favorites.length为0开头

But I want to check duplicates before the joke will be pushed into favorite list 但是我想在笑话被推入收藏夹之前检查重复项

By definition a hash will not allow duplicate entries, so no need to worry about duplications 根据定义,哈希将不允许重复的条目,因此无需担心重复

Run localStorage.getItem('favoList') in the console of this fiddle : 小提琴的控制台中运行localStorage.getItem('favoList')

(function() {
    "use strict";

    const getJokesButton = document.getElementById('getData');
    getJokesButton.addEventListener('click', getData);

    loadLocalStorage();

    function loadLocalStorage() {
        let storage = JSON.parse(localStorage.getItem('favoList')) || [];
        let listOfFavorites = document.getElementById("favorites");
        let emptyArray = '';
        if(storage.length > 0) {
            for(let i = 0; i < storage.length; i++) {
                let idNumberJoke = storage[i].id;
                emptyArray += 
                `<li><input type="checkbox" id='${idNumberJoke}'/> User title: ${storage[i].joke}</li>`;
                listOfFavorites.innerHTML = emptyArray;
            }
        } else {
            return false;
        }
    }

    // fetch data from api
    function getData() {
        let listOfJokes = document.getElementById("list-of-jokes"); 

        fetch('https://api.icndb.com/jokes/random/10')
        .then(function(res) {
            return res.json();
        }).then(function(data) { 
            // variable is undefined because it is not initialized. Therefore at some empty single quotes
            let result = '';
            console.log(data.value);
            data.value.forEach((joke) => {
                result +=
                `<li><input type="checkbox" class='inputCheckbox' id='${joke.id}'/> User title :  ${joke.joke}</li>`;
                listOfJokes.innerHTML = result;
            });
            bindCheckbox();
        }).catch(function(err) {
            console.log(err);
        });
    }

    function clickedButton() {
        getJokesButton.setAttribute('disabled', 'disabled');
        getJokesButton.classList.add('opacity');
    }

    function bindCheckbox() {
        let inputCheckbox = document.querySelectorAll('input[type=checkbox]');
        let elems = document.getElementById('list-of-jokes').childNodes;
        let favoriteList = document.getElementById('favorites');
        let fav = JSON.parse(localStorage.getItem('favoList'))|| [];

        if(elems.length > 0) {  
            inputCheckbox.forEach(function(element, index) {
                inputCheckbox[index].addEventListener('change', function() {
                    let joke = this;
                    if(joke.checked && joke.parentNode.parentNode.id === 'list-of-jokes') { 
                       joke.checked = false;
                       favoriteList.appendChild(joke.parentNode);
                       addFavorite(joke.id, joke.parentNode.innerText, fav);
                    } 
                    if(joke.checked && joke.parentNode.parentNode.id === 'favorites') {
                       joke.checked = false;
                       removeFavorite(joke, index);
                    }
                });
            });
        }
        clickedButton();
    }

    function removeFavorite(favorite, index) {
        let favoriteCheckBox = favorite;
        let i = index;

        // convert iterable object to an array, otherwise splice method would give an error.
        let favoriteListItem = Array.from(favoriteCheckBox.parentNode); 
        favoriteListItem.splice(i, 1);
        document.getElementById('list-of-jokes').appendChild(favorite.parentNode);
        localStorage.setItem('favoList', JSON.stringify(favoriteListItem));
    }

    // store favorites in localStorage
    function addFavorite(jokeId, jokeText, fav) {
        let norrisJoke = {
            id: jokeId,
            joke: jokeText
        };
        let favorites = fav;

        for (let i = 0; i < favorites.length; i++) {
            if(favorites[i].id !== norrisJoke.id) {
                favorites.push(norrisJoke);
            }
        }
        // favorites[i].id !== norrisJoke.id

        // always get the object before the push method and pass it into stringify
        localStorage.setItem('favoList', JSON.stringify(favorites));
    }   

   // function which will randomly add one joke to favorite list every 5 seconds
   // function need a button which allows you to turn on and off this auto add function
})();

The problem is the for loop, the first time it's executed favorites will be an empty array so it's length will be 0, so it will never enter the loop 问题是for循环,第一次执行收藏夹时,它将是一个空数组,因此其长度将为0,因此它将永远不会进入循环

Something like this should work: 这样的事情应该起作用:

favorites = favorites.filter(joke => joke.id !== norrisJoke.id).concat(norrisJoke);

You are trying to run through an empty list here 您正在尝试在此处填写一个空列表

for (let i = 0; i < favorites.length; i++) {
    if(favorites[i].id !== norrisJoke.id) {
        favorites.push(norrisJoke);
    }
}

This means that nothing will ever be pushed. 这意味着什么都不会被推。 You can reduce your list to an array of id , then check if the joke exists in the list. 您可以将列表简化为id数组,然后检查列表中是否存在该笑话。

const favIds = favorites.reduce((sum, element) => { 
        return sum.concat(element.id); 
    }, 
[]);

Now you can check if the joke doesn't exists in favorites 现在您可以检查收藏夹中是否不存在该笑话

if(!favIds.includes(jokeId)){
    favorites.push(norrisJoke);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM