[英]How do I assign a “ selected='selected' ” attribute to a specific <option> in a <select> list. VanillaJS only please
Click the about menu button to see the "About" display in the select list. 单击“关于”菜单按钮以在选择列表中看到“关于”显示。 I'd like each option match the clicked button.
我希望每个选项都与单击的按钮匹配。
<select name="selectList" id="mySelect">
<option value="one">Home</option>
<option value="two">About</option>
<option value="three">Hobbies</option>
<option value="four">Blog</option>
<option value="five">Contact</option>
</select>
<nav>
<ul id="nav">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Hobbies</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
var nav = document.getElementById("nav");
var mySelect = document.getElementById("mySelect");
for (i = 0; i < nav.children.length;i++) {
nav.children[i].addEventListener("click", function() {
mySelect[1].selected='selected';
})
};
When you add the event listener, on the function add a parameter. 添加事件侦听器时,在函数上添加一个参数。 This will contain the event.
这将包含事件。
The event.target
contains the element that has fired the event, so you can do event.target.setAttribute("selected", "selected")
event.target
包含触发事件的元素,因此您可以执行event.target.setAttribute("selected", "selected")
For example: 例如:
nav.children[i].addEeventListener("click", function(event){
event.target.setAttribute("selected", "selected");
});
PD: Don't forget to removeAttribute
from the other items PD:不要忘了从其他项目中
removeAttribute
THe problem is within the way you register your event listeners. 问题出在注册事件侦听器的方式之内。 You do it inside a loop.
您可以在一个循环中进行操作。 This is wrong .
这是错的 。 Event listening is asynchronous, which means that the listeners are really going to work after the current loop is over.
事件侦听是异步的,这意味着侦听器在当前循环结束后才真正起作用。 (Same goes for any async activity, including
setTimeout
. Just try using a setTimeout
inside a loop and you will see how it behaves - it won't be the way you expected!) And when the loop is over, the value of i
is going to be 5, and there is no option with index 5. Here is another way of registering listeners, if you are okay with writing in in the html. (对于任何异步活动,包括
setTimeout
。只需尝试在循环内使用setTimeout
,您将看到它的行为-不会像您期望的那样!)当循环结束时, i
值为将会是5,并且索引5没有选项。这是注册侦听器的另一种方法,如果可以用html编写的话。
var nav = document.getElementById("nav"); var mySelect = document.getElementById("mySelect"); function onNavClick(index) { mySelect.children[index].selected = 'selected'; }
<select name="selectList" id="mySelect"> <option value="one">Home</option> <option value="two">About</option> <option value="three">Hobbies</option> <option value="four">Blog</option> <option value="five">Contact</option> </select> <nav> <ul id="nav"> <li><a href="#" onclick="onNavClick(0)">Home</a></li> <li><a href="#" onclick="onNavClick(1)">About</a></li> <li><a href="#" onclick="onNavClick(2)">Hobbies</a></li> <li><a href="#" onclick="onNavClick(3)">Blog</a></li> <li><a href="#" onclick="onNavClick(4)">Contact</a></li> </ul> </nav>
You could check the textContent
of the target
element of the event to check if the values match the options and select the one you want. 您可以检查事件
target
元素的textContent
,以检查值是否与选项匹配,然后选择所需的选项。 Here is a snippet: 这是一个片段:
var nav = document.getElementById("nav"); var mySelect = document.getElementById("mySelect"); for (var i = 0; i < nav.children.length; i++) { nav.children[i].addEventListener("click", function (e) { var text = e.target.textContent; var options = mySelect.getElementsByTagName('option'); for (var j = 0; j < options.length; j++) { var option = options[j]; if (option.text === text) { option.selected = 'selected'; } else { option.selected = null; } } }); }
<select name="selectList" id="mySelect"> <option value="one">Home</option> <option value="two">About</option> <option value="three">Hobbies</option> <option value="four">Blog</option> <option value="five">Contact</option> </select> <nav> <ul id="nav"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Hobbies</a></li> <li><a href="#">Blog</a></li> <li><a href="#">Contact</a></li> </ul> </nav>
By the time a click event fires, the loop has already run its course. 当click事件触发时,循环已经运行了。
Since the variable i
is in global scope, the value referenced from each handler will be the same. 由于变量
i
在全局范围内,因此从每个处理程序引用的值将相同。
In the example below, notice that each handler references last value in the loop (5): 在下面的示例中,请注意,每个处理程序都在循环(5)中引用最后一个值:
var mySelect = document.getElementById("mySelect"); for (i = 0; i < nav.children.length; i++) { nav.children[i].addEventListener("click", function() { console.log(i); }) };
<ul id="nav"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Hobbies</a></li> <li><a href="#">Blog</a></li> <li><a href="#">Contact</a></li> </ul>
One technique is to use a closure . 一种技术是使用闭包 。
For reference, also see Creating Closures in Loops - A Common Mistake . 作为参考,另请参阅“ 在循环中创建闭包-常见错误” 。
var nav = document.getElementById("nav"); var mySelect = document.getElementById("mySelect"); var selectOption = function(index) { return function() { mySelect.children[index].selected = 'selected'; } } for (i = 0; i < nav.children.length; i++) { nav.children[i].addEventListener("click", selectOption(i)); };
<select name="selectList" id="mySelect"> <option value="one">Home</option> <option value="two">About</option> <option value="three">Hobbies</option> <option value="four">Blog</option> <option value="five">Contact</option> </select> <nav> <ul id="nav"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Hobbies</a></li> <li><a href="#">Blog</a></li> <li><a href="#">Contact</a></li> </ul> </nav>
Another technique is to use the let
keyword : 另一种技术是使用
let
关键字 :
let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used.
let允许您声明范围仅限于使用它的块,语句或表达式的变量。 This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.
这与var关键字不同,该关键字在全局范围内或在整个函数本地定义变量,而不管块范围如何。
var nav = document.getElementById("nav"); var mySelect = document.getElementById("mySelect"); for (i = 0; i < nav.children.length; i++) { let option = mySelect[i]; nav.children[i].addEventListener("click", function() { option.selected = 'selected'; }); };
<select name="selectList" id="mySelect"> <option value="one">Home</option> <option value="two">About</option> <option value="three">Hobbies</option> <option value="four">Blog</option> <option value="five">Contact</option> </select> <nav> <ul id="nav"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Hobbies</a></li> <li><a href="#">Blog</a></li> <li><a href="#">Contact</a></li> </ul> </nav>
This uses a closure to preserve the intended value of i
for each of the event listeners; 这使用闭包为每个事件侦听器保留
i
的预期值; and selectedIndex
to set the select box option (which in this case is somewhat more convenient than setting the selected attribute on one of the <option>
s.) It's otherwise identical to your code. 和
selectedIndex
设置选择框选项(在这种情况下,它比在<option>
之一上设置selected属性要方便一些。)它与代码相同。
var nav = document.getElementById("nav"); var mySelect = document.getElementById("mySelect"); for (i = 0; i < nav.children.length; i++) { (function(i) { // begin closure nav.children[i].addEventListener("click", function() { mySelect.selectedIndex = i; // easier way to set the selected option }); })(i); // end of the closure };
<select name="selectList" id="mySelect"> <option value="one">Home</option> <option value="two">About</option> <option value="three">Hobbies</option> <option value="four">Blog</option> <option value="five">Contact</option> </select> <nav> <ul id="nav"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Hobbies</a></li> <li><a href="#">Blog</a></li> <li><a href="#">Contact</a></li> </ul> </nav>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.