简体   繁体   English

JavaScript 如何在 onchange 事件和 select 元素中使用“this”

[英]JavaScript How to use “this” with onchange event and select element

I have got several select tags and divs in my html:我的 html 中有几个 select 标签和 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>

Now I would like to do semething like this:现在我想做这样的事情:

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>

The main problem is with selecting proper elements (read the comment tags)主要问题是选择适当的元素(阅读评论标签)

Referencing the event target引用事件目标

this will differ depending on how the listener-function is added to an element. this将根据侦听器功能添加到元素的方式而有所不同。

You can add a listener using …您可以使用...添加侦听器

  1. EventTarget.addEventListener() . EventTarget.addEventListener() this will be the element it is added to. this将是它被添加到的元素。
  2. HTMLElement.onevent – where event of .onevent is an actual event name. HTMLElement.onevent.oneventevent是实际事件名称。 this will be the element it is added to. this将是它被添加到的元素。
  3. … inline onevent listeners (eg using the HTML-attribute onchange="myFunction()" ). … 内联onevent监听器(例如使用 HTML 属性onchange="myFunction()" )。 this will be the global object, see globalThis . this将是全局 object,请参见globalThis

It is generally recommended to use EventTarget.addEventListener() for multiple reasons.出于多种原因,通常建议使用EventTarget.addEventListener() Here are two of many reasons why you should use it:以下是您应该使用它的众多原因中的两个:

  1. It allows for multiple listeners to be added instead of just one.它允许添加多个侦听器,而不仅仅是一个。
  2. Using it will keep your HTML clear of JavaScript, separating functionality from structure.使用它将使您的 HTML 远离 JavaScript,从而将功能与结构分开。 Use JavaScript to add functionality, not HTML.使用 JavaScript 添加功能,而不是 HTML。

Here is an example demonstrating the ways of adding listeners:这是一个演示添加侦听器方法的示例:

 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 -->

To make it more consistent, one can use Event.target .为了使其更加一致,可以使用Event.target The event-object is usually passed as the first argument.事件对象通常作为第一个参数传递。 Using inline onevent listener would require you to pass the event-object event yourself.使用内联onevent侦听器需要您自己传递事件对象event

Using Event.target will always return the event-target, regardless of what way you choose to add the listener.使用Event.target将始终返回事件目标,无论您选择哪种方式添加侦听器。

The modified code would look like this:修改后的代码如下所示:

 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 -->

Finding other elements relative to an element查找与某个元素相关的其他元素

This is accomplished by using the .querySelector() function of Element or Document to query for children, and the Element.closest() function to query for ancestors.这是通过使用ElementDocument.querySelector() function 来查询子级,并使用Element.closest() function 来查询祖先来完成的。 Both functions require a String containing CSS selectors to be passed.这两个函数都需要传递一个包含CSS 选择器的字符串。

In case you need to find a neighboring sibling, you can use Node.nextSibling or Node.previousSibling to find neighboring Node siblings.如果需要查找相邻的兄弟节点,可以使用Node.nextSiblingNode.previousSibling来查找相邻的Node兄弟节点。 This also includes TextNode s and similar non-element Nodes.这也包括TextNode和类似的非元素节点。
To only find neighboring element siblings, use Element.nextElementSibling or Element.previousElementSibling .要仅查找相邻元素兄弟,请使用Element.nextElementSiblingElement.previousElementSibling

If your <div class="show"> will always be the following element after your <select> , you can simply use .nextElementSibling like this:如果您的<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 &lt;div&gt;</option> <option value="none">Hide &lt;div&gt;</option> </select> <div class="show" style="display:none"> This &lt;div&gt; is shown. </div>

this refers to the select element inside the onchange function. this是指onchange function 内的 select 元素。

You are calling myFunction() from that function so, as per the standard rules , this is going to be window inside myFunction .您正在从该 function 调用myFunction()因此, 根据标准规则this将是myFunction中的window

If you want to pass the element along then you'll need to do so explicitly (either as an argument or with apply or call ).如果您想传递元素,那么您需要明确地这样做(作为参数或使用applycall )。


Better yet, don't use intrinsic event attributes (which have all sorts of issues), and use addEventListener instead.更好的是,不要使用内部事件属性(有各种问题),而是使用addEventListener


Once you've sorted that problem, you'll find that you are using closest completely wrong.一旦你解决了这个问题,你会发现你使用closest完全错误。

It searches ancestors not siblings (so possibly you'd want this.parentElement.querySelector instead) and, like querySelector expects a selector and not a plain class name.它搜索祖先而不是兄弟姐妹(因此您可能需要this.parentElement.querySelector代替),并且像querySelector需要一个选择器而不是普通的 class 名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM