根据其他列表选择的值更新下拉列表中的选择值
Update selected value in dropdown list depending on other lists selected values
我正在尝试弄清楚如何使用 Vanilla JS 在几个下拉列表中动态选择值。我有 3 个具有相同值的下拉列表。他们每个人都应该同时选择不同的值(不允许重复)。因此,一旦用户更改了一个列表中的另一个值,另一个列表的值也应相应更新。基本上,在这种情况下我需要交换他们的号码。但是我无法完成这项任务,因为我对 JS 和整体编程都很陌生。我试过以下:
// defining initial values
var startPoint = document.querySelectorAll("select");
// function to recalculate value of each list on change
function calculateNewValues() {
var changes = new Array();
// getting updated values from lists as an array
var updatedValues = document.querySelectorAll("select");
// looping through array
for (let i = 0; i < updatedValues.length; i++) {
// if in updated array value of current index isn't equal to value
// of index in initial array
if (updatedValues[i].value != startPoint[i].value) {
// creating variable changes for tracking
changes[i] = updatedValues[i].value;
}
// if var changes has been defined (i.e. value of any list was updated)
if (changes.length > 0) {
// finding index of initial array with same value
var key = startPoint.findIndex(changes[i]);
// setting value of found index to previously stored value in updated list
updatedValues[key].value = startPoint[i].value;
}
}
updatedValues.forEach(element => {
console.log(element.value);
});
}
// event listeners for change of every dropdown list
const lists = document.querySelectorAll("select");
for (k = 0; k < lists.length; k++) {
lists[k].addEventListener("change", calculateNewValues, false);
}
<p>
<select name="list1" id="list1">
<option value="1" id="list1option1" selected>1</option>
<option value="2" id="list1option2">2</option>
<option value="3" id="list1option3">3</option>
</select>
</p>
<p>
<select name="list2" id="list2">
<option value="1" id="list2option1">1</option>
<option value="2" id="list2option2" selected>2</option>
<option value="3" id="list2option3">3</option>
</select>
</p>
<p>
<select name="list3" id="list3">
<option value="1" id="list3option1">1</option>
<option value="2" id="list3option2">2</option>
<option value="3" id="list3option3" selected>3</option>
</select>
</p>
关于 if (changes.length > 0) {
我可能犯了一些错误
但我不明白如何让这部分变得更好。
非常感谢。
您已将 startPoint
分配给 querySelectorAll。每当您编写相同的 querySelectorAll 时,它将保存完全相同的对象。因此,在您的情况下,startPoint
和 updatedValues
将始终相同。
- 我已将
startPoint
定义为值数组并将其值设置在 setStartingPointValues()
中。
- 已添加
target
作为正在更新的当前列表。
- 更新了
if (target.id == updatedValues[i].id && updatedValues[i].value != startPoint[i])
并检索了 target
的旧值。
var key = startPoint.findIndex(x => x == target.value);
会发现 select 的值与新值相似。如果我们找到 key != -1,则将 select 更新为 oldValue.
- 在更改事件结束时调用
setStartingPointValues()
。
// defining initial values
var startPoint = [];
// store values for all select.
function setStartingPointValues() {
startPoint = [];
document.querySelectorAll("select").forEach(x => startPoint.push(x.value));
}
setStartingPointValues();
// function to recalculate value of each list on change
function calculateNewValues() {
let target = this;
let oldValue = 0;
// getting updated values from lists as an array
var updatedValues = document.querySelectorAll("select");
// looping through array
for (let i = 0; i < updatedValues.length; i++) {
// if in updated array value of current index isn't equal to value
// of index in initial array
if (target.id == updatedValues[i].id && updatedValues[i].value != startPoint[i]) {
// creating variable changes for tracking
// changes[i] = updatedValues[i].value;
oldValue = startPoint[i];
}
// if var changes has been defined (i.e. value of any list was updated)
// finding index of initial array with same value
var key = startPoint.findIndex(x => x == target.value);
// setting value of found index to previously stored value in updated list
if (key !== -1)
updatedValues[key].value = oldValue;
}
setStartingPointValues();
}
// event listeners for change of every dropdown list
const lists = document.querySelectorAll("select");
for (k = 0; k < lists.length; k++) {
lists[k].addEventListener("change", calculateNewValues, false);
}
<p>
<select name="list1" id="list1">
<option value="1" id="list1option1" selected>1</option>
<option value="2" id="list1option2">2</option>
<option value="3" id="list1option3">3</option>
</select>
</p>
<p>
<select name="list2" id="list2">
<option value="1" id="list2option1">1</option>
<option value="2" id="list2option2" selected>2</option>
<option value="3" id="list2option3">3</option>
</select>
</p>
<p>
<select name="list3" id="list3">
<option value="1" id="list3option1">1</option>
<option value="2" id="list3option2">2</option>
<option value="3" id="list3option3" selected>3</option>
</select>
</p>
定义良好的结构(在某处存储选定的值),其余的应该很容易
const lists = Array.from(document.querySelectorAll("#list")).map(element => {
const options = Array.from(element.children);
const selected = options.findIndex(child => child.selected) + 1;
return {
element,
options,
selected
}
});
const calculateNewValues = ({target}) => {
const value = Number(target.value);
const currentList = lists.find(pr => pr.element === target);
const list = lists.find(pr => pr.selected === value)
const oldValue = currentList.selected;
currentList.selected = value;
list.options[value - 1].selected = false;
list.options[oldValue - 1].selected = true;
list.selected = oldValue;
}
for(let {element} of lists) {
element.addEventListener("change", calculateNewValues, false);
}
<p>
<select name="list1" id="list">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</p>
<p>
<select name="list2" id="list">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>
</p>
<p>
<select name="list3" id="list">
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected>3</option>
</select>
</p>
我正在尝试弄清楚如何使用 Vanilla JS 在几个下拉列表中动态选择值。我有 3 个具有相同值的下拉列表。他们每个人都应该同时选择不同的值(不允许重复)。因此,一旦用户更改了一个列表中的另一个值,另一个列表的值也应相应更新。基本上,在这种情况下我需要交换他们的号码。但是我无法完成这项任务,因为我对 JS 和整体编程都很陌生。我试过以下:
// defining initial values
var startPoint = document.querySelectorAll("select");
// function to recalculate value of each list on change
function calculateNewValues() {
var changes = new Array();
// getting updated values from lists as an array
var updatedValues = document.querySelectorAll("select");
// looping through array
for (let i = 0; i < updatedValues.length; i++) {
// if in updated array value of current index isn't equal to value
// of index in initial array
if (updatedValues[i].value != startPoint[i].value) {
// creating variable changes for tracking
changes[i] = updatedValues[i].value;
}
// if var changes has been defined (i.e. value of any list was updated)
if (changes.length > 0) {
// finding index of initial array with same value
var key = startPoint.findIndex(changes[i]);
// setting value of found index to previously stored value in updated list
updatedValues[key].value = startPoint[i].value;
}
}
updatedValues.forEach(element => {
console.log(element.value);
});
}
// event listeners for change of every dropdown list
const lists = document.querySelectorAll("select");
for (k = 0; k < lists.length; k++) {
lists[k].addEventListener("change", calculateNewValues, false);
}
<p>
<select name="list1" id="list1">
<option value="1" id="list1option1" selected>1</option>
<option value="2" id="list1option2">2</option>
<option value="3" id="list1option3">3</option>
</select>
</p>
<p>
<select name="list2" id="list2">
<option value="1" id="list2option1">1</option>
<option value="2" id="list2option2" selected>2</option>
<option value="3" id="list2option3">3</option>
</select>
</p>
<p>
<select name="list3" id="list3">
<option value="1" id="list3option1">1</option>
<option value="2" id="list3option2">2</option>
<option value="3" id="list3option3" selected>3</option>
</select>
</p>
关于 if (changes.length > 0) {
我可能犯了一些错误
但我不明白如何让这部分变得更好。
非常感谢。
您已将 startPoint
分配给 querySelectorAll。每当您编写相同的 querySelectorAll 时,它将保存完全相同的对象。因此,在您的情况下,startPoint
和 updatedValues
将始终相同。
- 我已将
startPoint
定义为值数组并将其值设置在setStartingPointValues()
中。 - 已添加
target
作为正在更新的当前列表。 - 更新了
if (target.id == updatedValues[i].id && updatedValues[i].value != startPoint[i])
并检索了target
的旧值。 var key = startPoint.findIndex(x => x == target.value);
会发现 select 的值与新值相似。如果我们找到 key != -1,则将 select 更新为 oldValue.- 在更改事件结束时调用
setStartingPointValues()
。
// defining initial values
var startPoint = [];
// store values for all select.
function setStartingPointValues() {
startPoint = [];
document.querySelectorAll("select").forEach(x => startPoint.push(x.value));
}
setStartingPointValues();
// function to recalculate value of each list on change
function calculateNewValues() {
let target = this;
let oldValue = 0;
// getting updated values from lists as an array
var updatedValues = document.querySelectorAll("select");
// looping through array
for (let i = 0; i < updatedValues.length; i++) {
// if in updated array value of current index isn't equal to value
// of index in initial array
if (target.id == updatedValues[i].id && updatedValues[i].value != startPoint[i]) {
// creating variable changes for tracking
// changes[i] = updatedValues[i].value;
oldValue = startPoint[i];
}
// if var changes has been defined (i.e. value of any list was updated)
// finding index of initial array with same value
var key = startPoint.findIndex(x => x == target.value);
// setting value of found index to previously stored value in updated list
if (key !== -1)
updatedValues[key].value = oldValue;
}
setStartingPointValues();
}
// event listeners for change of every dropdown list
const lists = document.querySelectorAll("select");
for (k = 0; k < lists.length; k++) {
lists[k].addEventListener("change", calculateNewValues, false);
}
<p>
<select name="list1" id="list1">
<option value="1" id="list1option1" selected>1</option>
<option value="2" id="list1option2">2</option>
<option value="3" id="list1option3">3</option>
</select>
</p>
<p>
<select name="list2" id="list2">
<option value="1" id="list2option1">1</option>
<option value="2" id="list2option2" selected>2</option>
<option value="3" id="list2option3">3</option>
</select>
</p>
<p>
<select name="list3" id="list3">
<option value="1" id="list3option1">1</option>
<option value="2" id="list3option2">2</option>
<option value="3" id="list3option3" selected>3</option>
</select>
</p>
定义良好的结构(在某处存储选定的值),其余的应该很容易
const lists = Array.from(document.querySelectorAll("#list")).map(element => {
const options = Array.from(element.children);
const selected = options.findIndex(child => child.selected) + 1;
return {
element,
options,
selected
}
});
const calculateNewValues = ({target}) => {
const value = Number(target.value);
const currentList = lists.find(pr => pr.element === target);
const list = lists.find(pr => pr.selected === value)
const oldValue = currentList.selected;
currentList.selected = value;
list.options[value - 1].selected = false;
list.options[oldValue - 1].selected = true;
list.selected = oldValue;
}
for(let {element} of lists) {
element.addEventListener("change", calculateNewValues, false);
}
<p>
<select name="list1" id="list">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</p>
<p>
<select name="list2" id="list">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>
</p>
<p>
<select name="list3" id="list">
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected>3</option>
</select>
</p>