将 javascript 函数作为 data-* 属性传递并执行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30028331/
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-23 04:31:28  来源:igfitidea点击:

Pass javascript function as data-* attribute and execute

javascriptjquerycustom-data-attribute

提问by Cristian E.

We know such syntaxes as below, when defining a valuefor onClickattribute:

在定义valueforonClick属性时,我们知道如下语法:

<button type="submit" onclick="alert('hi');"></button>
<button type="submit" onclick="doWork"></button> <!-- This one doesn't work -->
<button type="submit" onclick="doWork()"></button>
<button type="submit" onclick="doWork('Mike', 2)"></button>

What I'm interested in is to define a custom data-attributeand execute the value as follows:

我感兴趣的是定义一个自定义data-attribute并执行如下值:

<button type="submit" data-callback="alert('hi');"      class="marker"></button>
<button type="submit" data-callback="doWork"            class="marker"></button>
<button type="submit" data-callback="doWork()"          class="marker"></button>
<button type="submit" data-callback="doWork('Mike', 2)" class="marker"></button>

<script type="text/javascript">
    jQuery("body").on("click","button.marker", function(e) {
        var callback = jQuery(e.currentTarget).data("callback");

        // Now I need to execute the callback no matter of the format
        // 1. Execute as function's body
        // 2. Or by function 'name'
        // 3. Or by function 'name' with 0 parameters
        // 4. Or by function 'name' with n parameters
    })

    function doWork(name, nr){
        var personName = name || "Unnamed";
        var personNr = nr || 0;
        alert("Name is: " + personName + " Nr: " + personNr);
    }
</script>

I've pasted the sample to jsBin

我已将示例粘贴到jsBin

How to accomplish same behaviour using custom data-attributes?

如何使用自定义数据属性完成相同的行为?

采纳答案by Arun P Johny

One way is to use eval()

一种方法是使用eval()

jQuery(".container").on("click", "button.marker", function (e) {
    var callback = jQuery(e.currentTarget).data("callback");

    var x = eval(callback)
    if (typeof x == 'function') {
        x()
    }
});

Demo: Fiddle

演示:小提琴

Note: Make sure it is safe in your environment, ie there is no possibility of script injection because of bad input from users

注意:确保它在您的环境中是安全的,即不会因为用户输入错误而导致脚本注入

回答by Taplar

I think a better idea would be to dynamically bind the events and trigger them. If you wanted them to only be known by other code, you could use custom events.

我认为更好的主意是动态绑定事件并触发它们。如果您希望它们只能被其他代码知道,您可以使用自定义事件。

<button type="submit" class="marker marker1"></button>
<button type="submit" class="marker marker2"></button>
<button type="submit" class="marker marker3"></button>
<button type="submit" class="marker marker4"></button>

<script>
    var $markers = $('.marker');
    $markers.filter('.marker1').bind('customCallback', function(){ alert("hi"); });
    $markers.filter('.marker2').bind('customCallback', function(){ doWork(); });
</script>

Then your other components could invoke them with $(selector).trigger('customCallback');

然后你的其他组件可以用 $(selector).trigger('customCallback'); 调用它们。

回答by Jeremy Thille

Simply with :

只需:

 $("body").on("click","button.marker", function(e) {
     eval($(this).data("callback"));
 })

回答by Michiel Cornille

If you really wanted to pass functions (with or without parameters) from one thing to another without binding them as events you could do it this way (I started from @Taplar's answer)

如果您真的想将函数(带或不带参数)从一件事传递到另一件事而不将它们绑定为事件,您可以这样做(我从@Taplar 的回答开始)

<button type="submit" class="marker marker1"></button>
<button type="submit" class="marker marker2"></button>
<button type="submit" class="marker marker3"></button>
<button type="submit" class="marker marker4"></button>

<script>
  var $markers = $('.marker');
  $markers.filter('.marker1').get(0).customCallback =  doWork;
  $markers.filter('.marker2').get(0).customCallback = function(){ 
    doWork(arg0,arg1); 
  };
</script>

Then you could access them in your other component as:

然后你可以在你的其他组件中访问它们:

<script>
  $('.marker').each(function(){
    var  thisFunction = $(this).get(0).customCallback;
    //do something useful with thisFunction
  });
</script>

回答by Mojimi

You can just bind a function as a data attribute

您可以将函数绑定为数据属性

const ele = $('button');

ele.data('onClick', evt => {
    alert('bye');
})

ele.click(evt => {
    const ele = $(evt.target);
    ele.data('onClick')(evt);
})

回答by Asuka165

Another way is using window[func](args).

另一种方法是使用window[func](args).

Similar to the eval(), but you will have to store the function name and the argument separately in the HTML attribute.

类似于eval(),但您必须将函数名称和参数分别存储在 HTML 属性中。

Here is a quick example... CodePen

这是一个快速示例... CodePen

<button type="submit" data-func="Angel" data-args='use me instead of evil()' class="marker">TEST</button>

<script type="text/javascript">

    //=== The Listener =====
    $(".marker").on("click",function(){

        // Get the function name and arguments
        let func = $(this).attr("data-func");
        let args = $(this).attr("data-args");

        // Call the function
        window[func](args);
    })


    //=== The Function =====
    function Angel(msg){
        alert(arguments.callee.name + " said : " + msg);
    }
</script>