如何将事件作为参数传递给 JavaScript 中的内联事件处理程序?

IT技术 javascript events event-handling parameter-passing inline
2021-01-27 21:53:44
// this e works
document.getElementById("p").oncontextmenu = function(e) {
    e = e || window.event;
    var target = e.target || e.srcElement;
    console.log(target);
};

// this e is undefined
function doSomething(e) {
    e = e || window.event;
    var target = e.target || e.srcElement;
    console.log(target);
}
<p id="p" onclick="doSomething(e)">
    <a href="#">foo</a>
    <span>bar</span>
</p>

有人问过一些类似的问题。

但是在我的代码中,我试图获取被单击的子元素,例如aspan

那么event作为参数传递给事件处理程序的正确方法是什么,或者如何在不传递参数的情况下在处理程序中获取事件?

编辑

我知道addEventListener并且jQuery,请提供将事件传递给inline事件处理程序的解决方案

4个回答

传递event对象:

<p id="p" onclick="doSomething(event)">

获取点击的孩子element(应该与event参数一起使用

function doSomething(e) {
    e = e || window.event;
    var target = e.target || e.srcElement;
    console.log(target);
}

传递element自身(DOMElement):

<p id="p" onclick="doThing(this)">

请参阅jsFiddle上的实时示例

您可以指定上述名称event,但您的处理程序也可以event此处所述访问参数:“当事件处理程序被指定为 HTML 属性时,指定的代码将被包装到具有以下参数的函数中”。链接上还有更多其他文档。

Wadih M. 的回答比这要好得多。这个是误导性的(和其他类似的一样),使人们认为应该将“(事件)”参数放入函数调用中,而实际上,JavaScript 已经在被调用的函数中具有“事件”参数并且随时可用,所以没有必要声明它(我花了几天时间才意识到改变变量名没有区别,因为它并没有真正被传递)。此外,那里给出的解释消除了对 JS 为何如此工作的任何疑问(也许不应该,但这不是我可以判断的......)
2021-03-17 21:53:44
如果支持,传递“事件”是我所知道的唯一方法。在这种情况下解析“this”是没有用的
2021-03-20 21:53:44
developer.mozilla.org/en-US/docs/Web/Guide/Events/... 中解释了“事件”对象可以用作 HTML 内联事件处理程序的参数的原因
2021-03-20 21:53:44
(对于任何想知道的人:是的,这确实适用于 Chrome、Firefox 等,即使某些 [Firefox,例如] 没有全局event对象。这是因为调用 DOM0 处理程序的上下文有一个event对象,即使 [在某些浏览器上] 它不是全局的。)
2021-03-21 21:53:44
@user1643156 这非常重要。参数必须完全命名为“事件”
2021-04-12 21:53:44

由于内联事件作为函数执行,您可以简单地使用参数

<p id="p" onclick="doSomething.apply(this, arguments)">

function doSomething(e) {
  if (!e) e = window.event;
  // 'e' is the event.
  // 'this' is the P element
}

接受的答案中提到的“事件”实际上是传递给函数的参数的名称。它与全球事件无关。

好提示。当人们开始采用 Web 组件call()apply()证明在模拟主流 js 框架中可用的数据绑定功能方面至关重要。一个额外的技巧是Object.assign(this.querySelector('my-btn'), this)在 web 组件内部做一些类似的事情,瞧,数据绑定。您可以从内联事件访问父 Web 组件类的任何方法onclick="toggleBtnActive.call(this, true)"
2021-03-24 21:53:44

您不需要 pass thisevent默认情况下已经有对象自动传递,其中包含event.target它来自的对象。您可以简化语法:

这:

<p onclick="doSomething()">

将与此一起使用:

function doSomething(){
  console.log(event);
  console.log(event.target);
}

您不需要实例化event对象,它已经存在。试试看。并且event.target将包含调用它的整个对象,您之前将其称为“this”。

现在,如果您从代码中的某处动态触发 doSomething(),您会注意到它event是未定义的。这是因为它不是由点击事件触发的。因此,如果您仍然想人为地触发事件,只需使用dispatchEvent

document.getElementById('element').dispatchEvent(new CustomEvent("click", {'bubbles': true}));

然后doSomething()会看到eventevent.target往常一样的!

无需this到处传递,您可以使您的函数签名不受接线信息的影响并简化事情。

至少在 IE11 上,这不是真的,没有默认参数。
2021-03-16 21:53:44
@cskwg 它也适用于 IE11。它适用于所有主要浏览器,因为这是向后兼容所必需的。正如我在答案中提到的,只有当 javascript 函数从一个事件中被触发时,这是存在事件的唯一场景,才会有一个已经称为“事件”的对象,您可以在您的函数中轻松访问它而不必将额外的接线传递给您的函数原型。我刚刚在我的机器上用 IE11 对 onclick 事件进行了测试,并且“事件”变量包含一个“PointerEvent 对象”。
2021-03-22 21:53:44
我无法模拟单击单选按钮,我错过了什么吗?document.getElementById("radioOption1").click() 有效,但这没有: document.getElementById("radioOption1").dispatchEvent(new CustomEvent("click", {'bubbles': true}))
2021-03-31 21:53:44

以下是我将如何防止用户将无效字符复制并粘贴到输入文本字段中:

function validatePaste(el, e) {
  var regex = /^[a-z .'-]+$/gi;
  var key = e.clipboardData.getData('text')
  if (!regex.test(key)) {
    e.preventDefault();
    return false;
  }
}

此函数位于<script>标签内,其调用方式如下:

<input type="text" onpaste="validatePaste(event)">