如何使我的排序函数一起工作?

huangapple go评论57阅读模式
英文:

How to make my sorting functions work together?

问题

我有一个包含三个排序和过滤选项的下拉菜单的网站:“按价格排序”,“按位置排序”和“按月份排序”。这些功能的代码在单独使用时似乎工作正常,但是当尝试同时使用多个选项时出现问题。只有页面顶部的代码起作用,而其他代码则无法产生预期的结果。

以下是当前代码的摘要:

按价格排序:当用户点击“从低到高”、“从高到低”或“默认”按钮时,网站成功地按照data-price属性对“hero” div进行排序。

按月份过滤:根据下拉菜单中选择的月份,网站正确地对“hero” div进行过滤。它显示与所选月份匹配的div,并隐藏其他div。

按位置过滤:网站还根据下拉菜单中选择的位置对“hero” div进行过滤。它显示与所选位置匹配的div,并隐藏其他div。

然而,问题在于当我尝试同时使用多个选项时,只有我首先选择的选项似乎起作用。例如,如果我首先按价格排序,然后尝试按月份或位置进行过滤,排序就停止工作,只有过滤起作用。

// 排序函数

document.addEventListener("DOMContentLoaded", function () {
    // 按data-price属性对“hero” div进行排序的函数
    function sortHeroByPrice(order) {
      const container = document.querySelector("#hero-container");
      const heroElements = document.querySelectorAll("#hero");

      // 将NodeList转换为数组以便更容易操作
      const heroArray = Array.from(heroElements);

      heroArray.sort(function (a, b) {
        const priceA = parseInt(a.getAttribute("data-price"));
        const priceB = parseInt(b.getAttribute("data-price"));
        const dateA = new Date(a.getAttribute('data-date'));
        const dateB = new Date(b.getAttribute('data-date'));


        if (order === "lowToHigh") {
          return priceA - priceB;
        } else if (order === "highToLow") {
          return priceB - priceA;
        }
        else if (order === "defaultBtn") {
            return dateA - dateB;
            } 
      });

      // 将排序后的元素添加到容器中
      heroArray.forEach(function (hero) {
        container.appendChild(hero);
      });
    }
             
    // 初始排序(可以选择“lowToHigh”或“highToLow”)
    sortHeroByPrice('defaultBtn');
    
    // 按钮点击处理程序
    document.getElementById("lowToHigh").addEventListener("click", function () {
      sortHeroByPrice('lowToHigh');
    });

    document.getElementById("highToLow").addEventListener("click", function () {
      sortHeroByPrice('highToLow');
    });

    document.getElementById("defaultBtn").addEventListener("click", function () {
        sortHeroByPrice('defaultBtn');
        });

    document.getElementById("moblh").addEventListener("click", function () {
        sortHeroByPrice('lowToHigh');
      });
      document.getElementById("mobhl").addEventListener("click", function () {
        sortHeroByPrice('highToLow');
      });
        document.getElementById("mobdef").addEventListener("click", function () {
            sortHeroByPrice('defaultBtn');
        });   

    });
// 按月份过滤

// 根据选择的月份过滤“hero” div的函数
function filterHeroByMonth(selectedMonth) {
  const heroElements = document.querySelectorAll('.hero');
  heroElements.forEach(function (hero) {
    const month = hero.dataset.month;

    if (selectedMonth === 'All' || selectedMonth === month) {
        
        hero.classList.remove('monthf');
    }
    else if (selectedMonth !== month){
    
   
    hero.classList.add('monthf');
    hero.style.display = 'none';
    }
  });
}

// 下拉菜单点击处理程序
const dropdownItems = document.querySelectorAll('.dropdown-item');
dropdownItems.forEach(function (item) {
  item.addEventListener('click', function (e) {
    e.preventDefault();
    const selectedMonth = item.dataset.month;

    const heroElements = document.querySelectorAll('.hero');
    heroElements.forEach(function (hero) {
        hero.classList.remove('monthf');
        hero.style.display = 'flex';

    });
    filterHeroByMonth(selectedMonth);
  });
  
});

// 按位置过滤的函数

function filterHeroByLocation(selectedLocation) {
  const heroElements = document.querySelectorAll('.hero');
  heroElements.forEach(function (hero) {
    const location = hero.dataset.location;

    if (selectedLocation === 'All' || selectedLocation === location) {
        
        hero.classList.remove('monthf');
    }
    else {
    hero.classList.add('monthf');
    hero.style.display = 'none';
    }
  });
}

// 下拉菜单点击处理程序
 dropdownItems = document.querySelectorAll('.dropdown-item');
dropdownItems.forEach(function (item) {
  item.addEventListener('click', function (e) {
    e.preventDefault();
    const selectedLocation = item.dataset.location;

    const heroElements = document.querySelectorAll('.hero');
    heroElements.forEach(function (hero) {
        hero.classList.remove('monthf');
        hero.style.display = 'flex';

    });
    filterHeroByLocation(selectedLocation);
  });
  
});
});
英文:

I have a website with a dropdown that contains three sorting and filtering options: "Sort by Price," "Sort by Location," and "Sort by Month." The code for these functionalities seems to work fine individually, but the issue arises when attempting to use more than one option simultaneously. Only the code at the top of the page works, while the others do not produce the expected results.

Here's a summary of the current code:

Sorting by Price: The website successfully sorts the 'hero' divs by the data-price attribute when the user clicks the "Low to High," "High to Low," or "Default" buttons.

Filtering by Month: The website correctly filters the 'hero' divs based on the selected month from the dropdown. It displays the divs that match the selected month and hides the others.

Filtering by Location: The website also filters the 'hero' divs based on the selected location from the dropdown. It shows the divs that match the selected location and hides the others.

However, the problem is that when I try to use more than one option together, only the first one I selected seems to work. For example, if I sort by price first, and then try to filter by month or location, the sorting stops working, and only the filtering works.

// sorting functions
document.addEventListener("DOMContentLoaded", function () {
// Function to sort 'hero' divs by data-price attribute
function sortHeroByPrice(order) {
const container = document.querySelector("#hero-container");
const heroElements = document.querySelectorAll("#hero");
// Convert NodeList to an array for easier manipulation
const heroArray = Array.from(heroElements);
heroArray.sort(function (a, b) {
const priceA = parseInt(a.getAttribute("data-price"));
const priceB = parseInt(b.getAttribute("data-price"));
const dateA = new Date(a.getAttribute('data-date'));
const dateB = new Date(b.getAttribute('data-date'));
if (order === "lowToHigh") {
return priceA - priceB;
} else if (order === "highToLow") {
return priceB - priceA;
}
else if (order === "defaultBtn") {
return dateA - dateB;
} 
});
// Append sorted elements to the container
heroArray.forEach(function (hero) {
container.appendChild(hero);
});
}
// Sort initially (you can choose 'lowToHigh' or 'highToLow')
sortHeroByPrice('defaultBtn');
// Button click handlers
document.getElementById("lowToHigh").addEventListener("click", function () {
sortHeroByPrice('lowToHigh');
});
document.getElementById("highToLow").addEventListener("click", function () {
sortHeroByPrice('highToLow');
});
document.getElementById("defaultBtn").addEventListener("click", function () {
sortHeroByPrice('defaultBtn');
});
document.getElementById("moblh").addEventListener("click", function () {
sortHeroByPrice('lowToHigh');
});
document.getElementById("mobhl").addEventListener("click", function () {
sortHeroByPrice('highToLow');
});
document.getElementById("mobdef").addEventListener("click", function () {
sortHeroByPrice('defaultBtn');
});   
});
// filter by month
//     Function to filter hero divs by selected month
function filterHeroByMonth(selectedMonth) {
const heroElements = document.querySelectorAll('.hero');
heroElements.forEach(function (hero) {
const month = hero.dataset.month;
if (selectedMonth === 'All' || selectedMonth === month) {
hero.classList.remove('monthf');
}
else if (selectedMonth !== month){
hero.classList.add('monthf');
hero.style.display = 'none';
}
});
}
// Dropdown click handler
const dropdownItems = document.querySelectorAll('.dropdown-item');
dropdownItems.forEach(function (item) {
item.addEventListener('click', function (e) {
e.preventDefault();
const selectedMonth = item.dataset.month;
const heroElements = document.querySelectorAll('.hero');
heroElements.forEach(function (hero) {
hero.classList.remove('monthf');
hero.style.display = 'flex';
});
filterHeroByMonth(selectedMonth);
});
});
// function to filter by location
function filterHeroByLocation(selectedLocation) {
const heroElements = document.querySelectorAll('.hero');
heroElements.forEach(function (hero) {
const location = hero.dataset.location;
if (selectedLocation === 'All' || selectedLocation === location) {
hero.classList.remove('monthf');
}
else {
hero.classList.add('monthf');
hero.style.display = 'none';
}
});
}
// Dropdown click handler
dropdownItems = document.querySelectorAll('.dropdown-item');
dropdownItems.forEach(function (item) {
item.addEventListener('click', function (e) {
e.preventDefault();
const selectedLocation = item.dataset.location;
const heroElements = document.querySelectorAll('.hero');
heroElements.forEach(function (hero) {
hero.classList.remove('monthf');
hero.style.display = 'flex';
});
filterHeroByLocation(selectedLocation);
});
});
});

答案1

得分: 2

你的代码有很多可以改进的地方。其中一些是:

  • 为了获取下拉菜单的值,使用select标签的onchange监听器,而不是为每个选项添加事件监听器。

     <select onchange="monthFilterChanged(event)">
    

然后获取选中的值:

 function monthFilterChanged(e) {
const selectedMonth = e.target.value;
....
}
  • 将当前排序值保存在一个JavaScript变量中:

     let sortingOrder = "defaultBtn"
    

每次更改排序时,更新该值:

sortingOrder = "NEW_VALUE"

更改值后,再次调用排序函数,不需要将排序顺序作为参数传递,使用新变量即可。

const currentOrder = sortingOrder

这里有一个CodePen示例,我在其中实现了按月份和价格排序,它们可以同时工作,添加位置过滤器也应该可以工作。

https://codepen.io/nicofetter/pen/zYMmjpm

英文:

Lots of stuff could be improved in your code. Some of them are:

  • To get the value of the dropdown use onchange listener of the select tag, instead of adding an event listener to each option.

     &lt;select onchange=&quot;monthFilterChanged(event)&quot;&gt;
    

And then to get the selected value:

 function monthFilterChanged(e) {
const selectedMonth = e.target.value;
....
}
  • Keep the current sorting value in a javascript variable:

     let sortingOrder = &quot;defaultBtn&quot;
    

Every time sorting is changed update the value like so:

sortingOrder = &quot;NEW_VALUE&quot;

After changing the value call the sorting function again without passing the sorting order as param, use the new variable.

const currentOrder = sortingOrder

Here you have a codepen where I did month and price, both of them work together, adding location filter should work as well.

https://codepen.io/nicofetter/pen/zYMmjpm

huangapple
  • 本文由 发表于 2023年7月27日 15:56:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76777612.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定