将 javascript 函数作为 data-* 属性传递并执行
Pass javascript function as data-* attribute and execute
当为 onClick
属性定义 value
时,我们知道如下语法:
<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
如何使用自定义数据属性完成相同的行为?
只需:
$("body").on("click","button.marker", function(e) {
eval($(this).data("callback"));
})
一种方法是使用 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()
}
});
演示:Fiddle
注意:确保它在您的环境中是安全的,即不可能因为用户的错误输入而导致脚本注入
- Why is using the JavaScript eval function a bad idea?
- When is JavaScript's eval() not evil?
- eval() isn’t evil, just misunderstood
- Eval is Evil, Part One
我认为一个更好的主意是动态绑定事件并触发它们。如果您希望它们只被其他代码知道,您可以使用自定义事件。
<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>
然后您的其他组件可以使用 $(selector).trigger('customCallback');
调用它们
如果你真的想将函数(带或不带参数)从一个事物传递到另一个事物而不将它们绑定为事件,你可以这样做(我从@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>
然后您可以在其他组件中访问它们:
<script>
$('.marker').each(function(){
var thisFunction = $(this).get(0).customCallback;
//do something useful with thisFunction
});
</script>
你可以只绑定一个函数作为数据属性
const ele = $('button');
ele.data('onClick', evt => {
alert('bye');
})
ele.click(evt => {
const ele = $(evt.target);
ele.data('onClick')(evt);
})
另一种方法是使用 window[func](args)
。
类似于eval()
,但您必须将函数名称和参数分别存储在HTML 属性中。
这是一个简单的例子...
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>
当为 onClick
属性定义 value
时,我们知道如下语法:
<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
如何使用自定义数据属性完成相同的行为?
只需:
$("body").on("click","button.marker", function(e) {
eval($(this).data("callback"));
})
一种方法是使用 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()
}
});
演示:Fiddle
注意:确保它在您的环境中是安全的,即不可能因为用户的错误输入而导致脚本注入
- Why is using the JavaScript eval function a bad idea?
- When is JavaScript's eval() not evil?
- eval() isn’t evil, just misunderstood
- Eval is Evil, Part One
我认为一个更好的主意是动态绑定事件并触发它们。如果您希望它们只被其他代码知道,您可以使用自定义事件。
<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>
然后您的其他组件可以使用 $(selector).trigger('customCallback');
调用它们如果你真的想将函数(带或不带参数)从一个事物传递到另一个事物而不将它们绑定为事件,你可以这样做(我从@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>
然后您可以在其他组件中访问它们:
<script>
$('.marker').each(function(){
var thisFunction = $(this).get(0).customCallback;
//do something useful with thisFunction
});
</script>
你可以只绑定一个函数作为数据属性
const ele = $('button');
ele.data('onClick', evt => {
alert('bye');
})
ele.click(evt => {
const ele = $(evt.target);
ele.data('onClick')(evt);
})
另一种方法是使用 window[func](args)
。
类似于eval()
,但您必须将函数名称和参数分别存储在HTML 属性中。
这是一个简单的例子... 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>