Javascript 如何获取javaScript事件源元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10428562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:15:42  来源:igfitidea点击:

how to get javaScript event source element?

javascriptjqueryhtml

提问by ilyes kooli

Is there a way to retrieve the element source of an inline javaScript call?

有没有办法检索内联 javaScript 调用的元素源?

I have a button like this:

我有一个这样的按钮:

<button onclick="doSomething('param')" id="id_button">action</button>

Note:

笔记:

  • the button is generated from server
  • I cannot modify the generation process
  • several buttons are generated on the page, I have control only on client side.
  • 该按钮是从服务器生成的
  • 我无法修改生成过程
  • 页面上生成了几个按钮,我只能在客户端进行控制。

What I have tried:

我尝试过的:

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

On firebug I get event is not defined

在萤火虫上我没有定义事件

Edit: After some answers, an override of the event handling using jQuery is very acceptable. My issue is how to call the original onClick function with it's original prameters, and without knowing the function name.

编辑:经过一些回答后,使用 jQuery 覆盖事件处理是非常可以接受的。我的问题是如何在不知道函数名称的情况下使用原始参数调用原始 onClick 函数。

code:

代码:

<button onclick="doSomething('param')" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button1">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>
.
.
and so on..

So the override would be:

所以覆盖将是:

$(document).on('click', 'button', function(e) {
  e.preventDefault();
  var action = $(this).attr('onclick');
  /**
   * What to do here to call
   * - doSomething(this, 'param'); if button1 is clicked
   * - doAnotherSomething(this, 'param1', 'param2'); if button2 is clicked
   * - doDifferentThing(this); if button3 is clicked
   * there are many buttons with many functions..
   */
});

采纳答案by adeneo

You should change the generated HTML to not use inline javascript, and use addEventListenerinstead.

您应该将生成的 HTML 更改为不使用内联 javascript,addEventListener而是使用。

If you can notin any way change the HTML, you could get the onclickattributes, the functions and arguments used, and "convert" it to unobtrusive javascript instead by removing the onclickhandlers, and using event listeners.

如果您无法以任何方式更改 HTML,您可以获取所使用的onclick属性、函数和参数,并通过删除onclick处理程序和使用事件侦听器将其“转换”为不显眼的 javascript 。

We'd start by getting the values from the attributes

我们首先从属性中获取值

$('button').each(function(i, el) {
    var funcs = [];

 $(el).attr('onclick').split(';').map(function(item) {
     var fn     = item.split('(').shift(),
         params = item.match(/\(([^)]+)\)/), 
            args;
            
        if (params && params.length) {
         args = params[1].split(',');
            if (args && args.length) {
                args = args.map(function(par) {
              return par.trim().replace(/('")/g,"");
             });
            }
        }
        funcs.push([fn, args||[]]);
    });
  
    $(el).data('args', funcs); // store in jQuery's $.data
  
    console.log( $(el).data('args') );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="doSomething('param')" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button1">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>

That gives us an array of all and any global methods called by the onclickattribute, and the arguments passed, so we can replicate it.

这为我们提供了一个由onclick属性调用的所有和任何全局方法以及传递的参数的数组,因此我们可以复制它。

Then we'd just remove all the inline javascript handlers

然后我们只需删除所有内联 javascript 处理程序

$('button').removeAttr('onclick')

and attach our own handlers

并附加我们自己的处理程序

$('button').on('click', function() {...}

Inside those handlers we'd get the stored original function calls and their arguments, and call them.
As we know any function called by inline javascript are global, we can call them with window[functionName].apply(this-value, argumentsArray), so

在这些处理程序中,我们将获取存储的原始函数调用及其参数,并调用它们。
我们知道内联 javascript 调用的任何函数都是全局的,我们可以用 调用它们window[functionName].apply(this-value, argumentsArray),所以

$('button').on('click', function() {
    var element = this;
    $.each(($(this).data('args') || []), function(_,fn) {
        if (fn[0] in window) window[fn[0]].apply(element, fn[1]);
    });
});

And inside that click handler we can add anything we want before or after the original functions are called.

在点击处理程序中,我们可以在调用原始函数之前或之后添加我们想要的任何内容。

A working example

一个工作示例

$('button').each(function(i, el) {
    var funcs = [];

 $(el).attr('onclick').split(';').map(function(item) {
     var fn     = item.split('(').shift(),
         params = item.match(/\(([^)]+)\)/), 
            args;
            
        if (params && params.length) {
         args = params[1].split(',');
            if (args && args.length) {
                args = args.map(function(par) {
              return par.trim().replace(/('")/g,"");
             });
            }
        }
        funcs.push([fn, args||[]]);
    });
    $(el).data('args', funcs);
}).removeAttr('onclick').on('click', function() {
 console.log('click handler for : ' + this.id);
  
 var element = this;
 $.each(($(this).data('args') || []), function(_,fn) {
     if (fn[0] in window) window[fn[0]].apply(element, fn[1]);
    });
  
    console.log('after function call --------');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button onclick="doSomething('param');" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button2">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>

<script>
 function doSomething(arg) { console.log('doSomething', arg) }
    function doAnotherSomething(arg1, arg2) { console.log('doAnotherSomething', arg1, arg2) }
    function doDifferentThing() { console.log('doDifferentThing','no arguments') }
</script>

回答by slipset

Your html should be like this:

你的 html 应该是这样的:

<button onclick="doSomething" id="id_button">action</button>

And renaming your input-paramter to event like this

并将您的输入参数重命名为这样的事件

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

would solve your problem.

会解决你的问题。

As a side note, I'd suggest taking a look at jQuery and unobtrusive javascript

作为旁注,我建议看看 jQuery 和 unobtrusive javascript

回答by srini

Try something like this:

尝试这样的事情:

<html>
  <body>

    <script type="text/javascript">
        function doSomething(event) {
          var source = event.target || event.srcElement;
          console.log(source);
          alert('test');
          if(window.event) {
            // IE8 and earlier
            // doSomething
           } else if(e.which) {
            // IE9/Firefox/Chrome/Opera/Safari
            // doSomething
           }
        }
     </script>

    <button onclick="doSomething('param')" id="id_button">
      action
    </button>

  </body>      
</html>

回答by DavidTaubmann

I believe the solution by @slipset was correct, but wasn't cross-browser ready.

我相信@slipset 的解决方案是正确的,但还没有准备好跨浏览器。

According to Javascript.info, events (when referenced outside markup events) are cross-browser ready once you assure it's defined with this simple line: event = event || window.event.

Javascript.info,事件(引用外标记事件时)是跨浏览器准备好,一旦你保证它与这个简单的行定义的:event = event || window.event

So the complete cross-browser ready function would look like this:

所以完整的跨浏览器就绪函数如下所示:

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

回答by Sethunath

You can pass thiswhen you call the function

this调用函数时可以通过

<button onclick="doSomething('param',this)" id="id_button">action</button>

<script>
    function doSomething(param,me){

    var source = me
    console.log(source);
}
</script>

回答by Pranav

USE .live()

使用 .live()

 $(selector).live(events, data, handler); 

As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers.

从 jQuery 1.7 开始,不推荐使用 .live() 方法。使用 .on() 附加事件处理程序。

$(document).on(events, selector, data, handler);