为什么这个事件处理程序设置不起作用?

Tim*_*Tim -1 html javascript javascript-events node.js

这是我的html文件 /tmp/test/test.html

<!DOCTYPE html>
<html>

  <head>
    <script src="../js/my.js" defer>
    </script>
  </head>

  <body>

    <p>This example uses the HTML DOM to assign an "onchange" event to an input element.</p>   

    Enter your name: <input type="text" id="fname">
    <p>When you leave the input field, a function is triggered which transforms the input text to upper case.</p>


  </body>
  </html>
Run Code Online (Sandbox Code Playgroud)

这是我的javascript文件/tmp/js/my.js,但事件处理程序的设置不起作用.为什么它不起作用,我该怎么做才能使它工作?

function myFunction1(input) {
    input.value = input.value.toUpperCase();
}

document.getElementById("fname").onchange =  myFunction1;
Run Code Online (Sandbox Code Playgroud)

如果我用我的javascript文件替换

function myFunction2() {
    var x = document.getElementById("fname");
    x.value = x.value.toUpperCase();
}

document.getElementById("fname").onchange =  myFunction2;
Run Code Online (Sandbox Code Playgroud)

事件处理程序工作.我想知道为什么两种方法之间存在这样的差异?

在外部javascript文件或html文件中,首选哪种方式指定事件处理程序的设置?

谢谢.

Sco*_*cus 5

它不起作用的原因与外部文件中的脚本无关.这是因为您假设对DOM对象的引用作为参数(input)传递给函数,而不是.input实际上是对事件的引用.使用对象属性(onchange等)或通过更现代和基于标准的方式设置的事件处理程序.addEventListener()会自动传递对作为回调函数的第一个参数调用的事件的引用.

您的第二个版本有效,因为您不依赖于参数来引用DOM对象,而是正确获取对DOM对象的引用document.getElementById("fname").但是,实际上,您不需要做任何特殊操作来获取对触发事件的DOM对象的引用,因为该对象将绑定到this回调函数中的关键字.

除此之外,您应该放弃通过事件属性等设置事件onchange,因为这种方法限制您每个事件只设置一个事件处理函数.而是使用现代标准element.addEventListener()

最后,要将文本内容更改为全部大写,您甚至不需要JavaScript,因为只能使用CSS.

请参阅下面的示例,其中显示了所有这些:

// Get your reference to DOM objects that you'll need just once, when the DOM is available
// And, set up events following modern standards:
document.getElementById("fname").addEventListener("change", myFunction);

// Event handlers are automatically passed a reference 
// to the event as the handler's first argument.
function myFunction(evt) {
  // Inside of an event handler for a DOM object, you can always
  // reference the DOM object that triggered the event via the target property
  // of the event (evt.target in this case) or, even simpler via the "this" keyword.
  console.log("Event: " + evt.type.toUpperCase()  + " was triggered by: " + this.nodeName + " " + this.id + " " + evt.target);
  this.value = evt.type;
}
Run Code Online (Sandbox Code Playgroud)
/* You don't need JavaScript to convert content to upper case */
#fname { text-transform:uppercase; }
Run Code Online (Sandbox Code Playgroud)
<p>This example uses the HTML DOM to assign an "onchange" event to an input element.</p>   

Enter your name: <input type="text" id="fname">
<p>When you leave the input field (just hit TAB after inputting some data), the CHANGE event callback function is triggered.</p>
Run Code Online (Sandbox Code Playgroud)