问题描述
我的 html 中有几个选择标签和 div:
<div>
<select name="one" id="oneId" class="selectOne" onchange="myFunction()">
<option value="" disabled selected>choose*</option>
<option value="1">Yes</option>
<option value="2">No</option>
</select>
<div class="show" style="display:none;">
<input type="number" value="" id="other"></input>
</div>
</div>
现在我想做这样的事情:
function myFunction() {
var a = this.value; // to select this "select tag" of this function
var b = this.closest("show"); // to select closest "show div" to select tag
var c = b.children; //input // to select input in "show div"
if (a == 1) {
b.style.display = "block";
c.removeAttribute("disabled");
} else {
b.style.display = "none";
c.setAttribute('disabled','disabled');
}
}
function myFunction() {
var a = this.value; // to select this "select tag" of this function
var b = this.closest("show"); // to select closest "show div" to select tag
var c = b.children; //input // to select input in "show div"
if (a == 1) {
b.style.display = "block";
c.removeAttribute("disabled");
} else {
b.style.display = "none";
c.setAttribute('disabled','disabled');
}
}
<div>
<select name="one" id="oneId" class="selectOne" onchange="myFunction()">
<option value="" disabled selected>choose*</option>
<option value="1">Yes</option>
<option value="2">No</option>
</select>
<div class="show" style="display:none;">
<input type="number" value="" id="other"></input>
</div>
</div>
主要问题是选择合适的元素(阅读评论标签)
解决方法
引用事件目标
this
将根据侦听器功能添加到元素的方式而有所不同。
您可以使用...添加侦听器
- ……
EventTarget.addEventListener()
。this
将是它添加到的元素。 - …
HTMLElement.onevent
– 其中event
of.onevent
是实际事件名称。this
将是它添加到的元素。 - ... 内联
onevent
侦听器(例如,使用 HTML 属性onchange="myFunction()"
)。this
将是全局对象,请参阅globalThis
。
出于多种原因,通常建议使用 EventTarget.addEventListener()
。以下是您应该使用它的众多原因中的两个:
- 它允许添加多个侦听器,而不仅仅是一个。
- 使用它将使您的 HTML 远离 JavaScript,将功能与结构分开。使用 JavaScript 来添加功能,而不是 HTML。
这是一个演示添加侦听器方法的示例:
document.querySelector('button').addEventListener('click',log); // Case 1
document.querySelector('button:nth-child(2)').onclick = log; // Case 2
function log() {
console.log((this === globalThis ? "'this' is 'globalThis'" : this));
}
<button>Using addEventListener()</button>
<button>Using Element.onclick</button>
<button onclick="log()">Using onevent-listener</button> <!-- Case 3 -->
为了使其更加一致,可以使用 Event.target
。事件对象通常作为第一个参数传递。使用内联 onevent
侦听器需要您自己传递事件对象 event
。
使用 Event.target
将始终返回事件目标,无论您选择以何种方式添加侦听器。
修改后的代码如下:
document.querySelector('button').addEventListener('click',log); // Case 1
document.querySelector('button:nth-child(2)').onclick = log; // Case 2
function log(evt) {
console.log((evt.target === globalThis ? 'test' : evt.target));
}
<button>Using addEventListener()</button>
<button>Using Element.onclick</button>
<button onclick="log(event)">Using onevent-listener</button> <!-- Case 3 -->
查找与某个元素相关的其他元素
这是通过使用 Element
或 Document
的 .querySelector()
函数来查询子代,以及使用 Element.closest()
函数来查询祖先来实现的。这两个函数都需要传递一个包含 CSS selectors 的字符串。
如果您需要查找相邻的兄弟姐妹,您可以使用 Node.nextSibling
或 Node.previousSibling
查找相邻的 Node
兄弟姐妹。这还包括 TextNode
和类似的非元素节点。
要仅查找相邻元素同级,请使用 Element.nextElementSibling
或 Element.previousElementSibling
。
如果您的 <div class="show">
始终是您的 <select>
之后的以下元素,您可以简单地使用 .nextElementSibling
如下:
document.querySelector('select').addEventListener('change',selectChanged);
function selectChanged(evt) {
var divShow = evt.target.nextElementSibling;
divShow.style.display = evt.target.value;
}
<select>
<option disabled selected>Choose</option>
<option value="block">Show <div></option>
<option value="none">Hide <div></option>
</select>
<div class="show" style="display:none">
This <div> is shown.
</div>
this
指的是 onchange
函数内的 select 元素。
您正在从该函数调用 myFunction()
,因此,as per the standard rules、this
将是 window
内的 myFunction
。
如果您想传递元素,则需要显式传递(作为参数或使用 apply
或 call
)。
更好的是,不要使用内在事件属性(它有各种各样的问题),而是使用 addEventListener
。
一旦你解决了这个问题,你就会发现你使用的 closest
完全错误。
它搜索祖先而不是兄弟姐妹(所以你可能想要this.parentElement.querySelector
),并且像querySelector
一样需要一个选择器而不是一个普通的类名。