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

问题描述 投票:21回答:6

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

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

我感兴趣的是定义一个自定义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>

我把样品粘贴到jsBin

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

javascript jquery custom-data-attribute
6个回答
12
投票

一种方法是使用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()
    }
});

但是:ぁzxswい

注意:确保它在您的环境中是安全的,即由于用户输入错误而无法注入脚本


9
投票

我认为更好的想法是动态绑定事件并触发它们。如果您希望它们仅为其他代码所知,则可以使用自定义事件。

Eval is Evil, Part One

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


7
投票

只需:

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

3
投票

如果你真的想将函数(有或没有参数)从一件事传递到另一件事而不将它们作为事件绑定它们就可以这样做(我从@Taplar的答案开始)

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

然后,您可以在其他组件中访问它们:

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

2
投票

您只需将函数绑定为数据属性即可

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

0
投票

另一种方法是使用const ele = $('button'); ele.data('onClick', evt => { alert('bye'); }) ele.click(evt => { const ele = $(evt.target); ele.data('onClick')(evt); })

window[func](args)类似,但您必须将功能名称和参数分别存储在HTML属性中。

这是一个简单的例子...... eval()

CodePen
© www.soinside.com 2019 - 2024. All rights reserved.