如何使用下拉菜单和HTML5数据属性动态更改HTML元素的分组

How to dynamically change the grouping of HTML elements using a dropdown and HTML5 data attributes?

本文关键字:HTML 元素 动态 下拉菜单 何使用 HTML5 数据属性      更新时间:2023-09-26

给定下拉列表:

<select>
  <option value="group1">Name</option>
  <option value="group2" data-group-order="[Odds|Evens]">Odds First then Even</option>
  <option value="group3" data-group-order="[Most Favorites|Somewhat Favorites|Least Favorites]">Most to least favorite</option>
</select>

和这个HTML:

<div id="Item1" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="5" data-group3-name="Least Favorites" data-group3-order="10">Item 1</div>
<div id="Item2" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="1">Item 2</div>
<div id="Item3" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="4" data-group3-name="Least Favorites" data-group3-order="1">Item 3</div>
<div id="Item4" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="5">Item 4</div>
<div id="Item5" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="3" data-group3-name="Least Favorites" data-group3-order="5">Item 5</div>
<div id="Item6" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="10">Item 6</div>
<div id="Item7" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="2" data-group3-name="Somewhat Favorites" data-group3-order="2">Item 7</div>
<div id="Item8" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="3">Item 8</div>
<div id="Item9" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="1">Item 9</div>
<div id="Item10" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Somewhat Favorites" data-group3-order="5">Item 10</div>

当从下拉菜单中选择一个选项时,我是否可以动态更新HTML,以便用户看到的是基于选项元素"data-group-order"值的div分组,该组中的每个div都按照其"data-groupX-order"属性的值进行排序?

例如,如果我选择了"Name"选项(value=group1),我希望:

<div>Name</div>
<div id="Item1" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="5" data-group3-name="Least Favorites" data-group3-order="10">Item 1</div>
<div id="Item2" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="1">Item 2</div>
<div id="Item3" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="4" data-group3-name="Least Favorites" data-group3-order="1">Item 3</div>
<div id="Item4" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="5">Item 4</div>
<div id="Item5" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="3" data-group3-name="Least Favorites" data-group3-order="5">Item 5</div>
<div id="Item6" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="10">Item 6</div>
<div id="Item7" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="2" data-group3-name="Somewhat Favorites" data-group3-order="2">Item 7</div>
<div id="Item8" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="3">Item 8</div>
<div id="Item9" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="1">Item 9</div>
<div id="Item10" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Somewhat Favorites" data-group3-order="5">Item 10</div>

如果我选择了"赔率优先然后偶数"选项(value=group1, data-group-order="[赔率|偶数]"),我将期望:

<div>Odds</div>
<div id="Item9" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="1">Item 9</div>
<div id="Item7" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="2" data-group3-name="Somewhat Favorites" data-group3-order="2">Item 7</div>
<div id="Item5" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="3" data-group3-name="Least Favorites" data-group3-order="5">Item 5</div>
<div id="Item3" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="4" data-group3-name="Least Favorites" data-group3-order="1">Item 3</div>
<div id="Item1" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="5" data-group3-name="Least Favorites" data-group3-order="10">Item 1</div>
<div>Evens</div>
<div id="Item2" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="1">Item 2</div>
<div id="Item4" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="5">Item 4</div>
<div id="Item6" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="10">Item 6</div>
<div id="Item8" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="3">Item 8</div>
<div id="Item10" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Somewhat Favorites" data-group3-order="5">Item 10</div>

如果我选择了"Most to least favorite"选项(value=group3 data-group-order="[Most Favorites|Somewhat Favorites| least Favorites]"),我将期望:

<div>Most Favorites</div>
<div id="Item9" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="1">Item 9</div>
<div id="Item4" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="5">Item 4</div>
<div id="Item6" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="10">Item 6</div>
<div>Somewhat Favorites</div>
<div id="Item7" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="2" data-group3-name="Somewhat Favorites" data-group3-order="2">Item 7</div>
<div id="Item10" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Somewhat Favorites" data-group3-order="5">Item 10</div>
<div>Least Favorites</div>
<div id="Item2" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="1">Item 2</div>
<div id="Item3" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="4" data-group3-name="Least Favorites" data-group3-order="1">Item 3</div>
<div id="Item8" data-group1-name="Name" data-group1-order="1" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="3">Item 8</div>
<div id="Item5" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="3" data-group3-name="Least Favorites" data-group3-order="5">Item 5</div>
<div id="Item1" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="5" data-group3-name="Least Favorites" data-group3-order="10">Item 1</div>

注意当使用"data-groupX-order"在组内排序时,顺序基于该值,如果多个元素共享相同的值,则顺序基于字母数字。

一种可能的方法。注意,我避免在一起使用顺序。我以data-group2-name为基础进行排序,但有一个dict变量来跟踪我希望这些不同名称值出现的顺序。这样做的原因是,必须手动维护订单值,很可能会忘记更新一个项目。

对具有相同值的元素按字母顺序进行编号,首先对名称进行排序,然后应用组顺序(注意,按字母顺序,'Item 10'在'Item 2'之前)。

function handleSelectChange(event) {
	var selectEl = event.target;
	var gp = selectEl.value;
	var dict = selectEl.options[selectEl.selectedIndex].dataset.groupOrder;
	dict = (dict || '').replace(/'[(.*?)']/, "$1").split('|');
	groupChildren(
	    document.getElementById('orderedThroughSelect'),
	    gp, 
	    dict
	);
}
function groupChildren(el, gp, dict) {
	// --- getting the list of nodes to sort
	var nodes = Array.prototype.slice.call(el.children);
	// --- ordering
	// start by ordering options in alphabetical order
	var nodeText = function(node) { return node.innerText; };
	var alphabeticAsc = function(a, b) { return (a < b) ? -1 : (a > b) ? 1 : 0; };
	nodes.sort(function(a, b) { return alphabeticAsc(nodeText(a), nodeText(b)); });
	// now order by group
	if(dict) { 
	    var nodeGroupIndex = function(node) { return  dict.indexOf(node.dataset[gp+'Name']);  };
	    var numericAsc = function(a, b) { return a - b; };
	    nodes.sort(function(a, b) { return numericAsc(nodeGroupIndex(a), nodeGroupIndex(b)); });
	}
	// --- reseting content
	var div = document.createElement('div');
	nodes.forEach(function(el) { div.appendChild(el); });
	el.innerHTML = div.innerHTML;
}
<select onchange='handleSelectChange(event)'>
  <option value="group1">Name</option>
  <option value="group2" data-group-order="[Odds|Evens]">Odds First then Even</option>
  <option value="group3" data-group-order="[Most Favorites|Somewhat Favorites|Least Favorites]">Most to least favorite</option>
</select>
<div id='orderedThroughSelect'>
	<div id="Item1" data-group1-name="Name" data-group1-order="1" data-group2-name="Odds" data-group2-order="5" data-group3-name="Least Favorites" data-group3-order="10">Item 1</div>
	<div id="Item2" data-group1-name="Name" data-group1-order="2" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="1">Item 2</div>
	<div id="Item3" data-group1-name="Name" data-group1-order="3" data-group2-name="Odds" data-group2-order="4" data-group3-name="Least Favorites" data-group3-order="1">Item 3</div>
	<div id="Item4" data-group1-name="Name" data-group1-order="4" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="5">Item 4</div>
	<div id="Item5" data-group1-name="Name" data-group1-order="5" data-group2-name="Odds" data-group2-order="3" data-group3-name="Least Favorites" data-group3-order="5">Item 5</div>
	<div id="Item6" data-group1-name="Name" data-group1-order="6" data-group2-name="Evens" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="10">Item 6</div>
	<div id="Item7" data-group1-name="Name" data-group1-order="7" data-group2-name="Odds" data-group2-order="2" data-group3-name="Somewhat Favorites" data-group3-order="2">Item 7</div>
	<div id="Item8" data-group1-name="Name" data-group1-order="8" data-group2-name="Evens" data-group2-order="1" data-group3-name="Least Favorites" data-group3-order="3">Item 8</div>
	<div id="Item9" data-group1-name="Name" data-group1-order="9" data-group2-name="Odds" data-group2-order="1" data-group3-name="Most Favorites" data-group3-order="1">Item 9</div>
	<div id="Item10" data-group1-name="Name" data-group1-order="10" data-group2-name="Evens" data-group2-order="1" data-group3-name="Somewhat Favorites" data-group3-order="5">Item 10</div>
</div>