javascript - 按键值对对象数组进行排序并将它们显示在 HTML 元素上

标签 javascript html sorting

我正在制作一个电影排序列表,您输入标题,然后输入评分,它会按评分顺序显示电影。我有一个对象数组,我设法按评级对数组进行排序,但我找不到在 HTML DOM 上实际按顺序显示数组的方法。

我试过 for 循环和 forEach,但它们无法按我想要的方式工作。

const movieTitle = document.querySelector(".movie-title");
const movieRating = document.querySelector(".movie-rating");
const movieList = document.querySelector(".movie-list");
const sortBtn = document.querySelector(".btn");

let movieStorage = [];

function sendMovie() {
    if(event.keyCode == 13) {
        if(movieTitle.value != "" && movieRating.value != "") {
            title = movieTitle.value;
            rating = parseInt(movieRating.value);

            movieStorage.push({
                title: title,
                rating: rating
            });

            // If rating of a is bigger than rating of b return 1, if not return -1
            movieStorage.sort((a, b) => (a.rating > b.rating) ? -1 : 1);
            console.log(movieStorage);

            addMovieToList(title, rating);

            movieTitle.value = "";
            movieRating.value = "";
        } else {
            console.log("Fields missing");
        }
    }
}

function addMovieToList(title, rating) {

    const div = document.createElement("div");
    div.className = "list-items";

    div.innerHTML = `
    <div class="item-title">
        <p>${title}</p>
    </div>

    <div class="item-rating">
        <p>${rating}</p>
    </div>

    <div class="item-delete">
        <i class="fa fa-trash trash-icon delete"></i>
    </div>
    `;

    movieList.appendChild(div);
}

function sortByRating(element) {
    for(let i = 0; i < movieStorage.length; i++) {
        element.innerHTML = `
        <div class="item-title">
            <p>${movieStorage[i].title}</p>
        </div>

        <div class="item-rating">
            <p>${movieStorage[i].rating}</p>
        </div>

        <div class="item-delete">
            <i class="fa fa-trash trash-icon delete"></i>
        </div>
        `;
    }
}

document.addEventListener("click", (e) => {
    const deleteIcon = e.target;

    const item = document.querySelector(".list-items");

    if(deleteIcon.classList.contains("delete")) {
        deleteIcon.parentElement.parentElement.remove(item);
    }
})

最佳答案

tldr demo

排序数组后,您需要一种引用电影 div 的方法来对它们进行排序。有很多种方法,我选择的是使用id .当您创建电影时 <div> , 为每个电影名称赋予一个唯一的 ID:

// Simple function to generate hash number for each string
function hashStr(stringValue) {
  var hash = 0, i, chr;
  if (stringValue.length === 0) return hash;
  for (i = 0; i < stringValue.length; i++) {
    chr   = stringValue.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
}

const MOVIES = [
   {name: "a", rating: 3},
   {name: "b", rating: 6},
   {name: "c", rating: 3},
   {name: "d", rating: 2},
   {name: "e", rating: 1},
];

function showMovies() {
    const moviesDiv = document.querySelector("#movies");
    for(const movie of MOVIES) 
    {
        const id = "movie-"+hashStr(movie.name);
        // If there's no element with the ID, we need to create the DIV for the movie
        if(!document.querySelector("#"+id)) {
            const elm = document.createElement("div");
            elm.appendChild(new Text(movie.name + " ("+movie.rating+"/10)"));
            elm.id = id;
            elm.classList.add("movie");
            moviesDiv.appendChild(elm);
        }
    }
}

然后排序的时候,可以通过ID来引用每部电影:

// Sort movies using given property (eg. "name")
// The second param determines sort direction
function sortBy(property, ascending=true) {
    MOVIES.sort((a,b) =>{
        return cmp(a[property], b[property], ascending);    
    });
    // Now after sorting the array, we can sort the HTML elements
    const moviesDiv = document.querySelector("#movies");
    let lastMovie = null;
    for(const movie of MOVIES) 
    {
        const id = "#movie-"+hashStr(movie.name);
        const movieDiv = document.querySelector(id);
        console.log(id, movieDiv);
        // If created
        if(movieDiv) {
            // remove and append after last processed movie (for the first movie, this will append to top)
            moviesDiv.insertBefore(movieDiv, lastMovie);
        }
    }
}
// Compare string and number, makes no sense for other types
function cmp(a,b, ascending=true) {
    if(typeof a=='number' && typeof b == "number") {
        return ascending ? a-b : b-a;
    }
    else if(typeof a=='string' && typeof b == "string"){
        return (ascending ? 1 : -1) * a.localeCompare(b);
    }
    else {
        return 0;
    }
}

添加电影时,只需再次调用 sort 即可。您需要记住最后的排序参数。

关于javascript - 按键值对对象数组进行排序并将它们显示在 HTML 元素上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57625553/

相关文章:

javascript - 如何解决对象没有方法 'appendChild'

html - 如何制作具有自动宽度的语义html水平定义列表?

java - 选择排序比较和交换已经排序的列表

algorithm - 如何通过反转子序列对排列进行排序(取自 Skiena 第 3 版)

javascript - JQuery 表单更新监听器

javascript - 使用 Redux-Observable 的通用 Epic

javascript - 使用 JavaScript 调用事件 click

javascript - 尝试从 JavaScript 函数调用单击隐藏按钮的函数

html - 令人困惑的 CSS 定位

具有延迟加载、过滤和排序功能的 jsf 数据表