我有一个这样的选择菜单:
<select name="moduleGroup">
<option data-function="getListing('pages')">Pages</option>
</select>
使用Javascript
function getListing(s) {
console.log(s);
}
$('select').on('change', function() {
var func = $(this).find('option:selected').attr('data-function');
[func]();
});
我也尝试过,$[func]();, $(‘body’)[func]();
我已阅读有关同一问题的多篇帖子,但没有人帮助我:here和here
我确定我做错了什么,但有人能指出我正确的方向吗?
最佳答案 最简单的方法是调用eval(),如下所示:
$('select').change(function() {
var func = $(this).find('option:selected').attr('data-function');
eval(func);
});
小提琴:http://jsfiddle.net/gywzb/4/
但整个世界都认为这是一种不好的做法.正如我最喜欢的linter所说,“eval()是邪恶的.”它会为您打开许多令人讨厌的安全漏洞(特别是当您维护应用程序时,事情会因您最初的编写方式而改变),而且无论如何都表现糟糕.幸运的是,有一种更好的方法.
首先,我将稍微分解一下你的数据属性,这样你就不会有一个包含函数名和参数的属性,而是有两个属性:一个用于函数名,另一个用于参数.
<select name="moduleGroup">
<option data-function="getListing" data-parameter="pages">Pages</option>
</select>
其次,我们将创建一个包含您的函数的“类”,如下所示:
var MyClass = function() {
}
MyClass.prototype = {
getListing: function(s) {
console.log(s);
}
};
最后,以下是使用上述更改来调用函数的方法:
$('select').on('change', function() {
var func = $(this).find('option:selected').attr('data-function');
var param = $(this).find('option:selected').attr('data-parameter');
var myInstance = new MyClass();
var funcRef = myInstance[func];
funcRef.call(myInstance, param);
});
这是整个小提琴:http://jsfiddle.net/7CwH4/2/
当您使用.call method调用您的函数时,会发生魔力. .call()方法的第一个参数是函数将作为其对象看到的对象. .call的下一个参数是函数的第一个参数. (如果你的函数需要更多的参数,.call的第三个参数将是函数的第二个参数,等等.如果这是令人困惑的话,请参阅MDN documentation .call.)
如果需要传递比字符串更复杂的数据作为参数,可以将其作为JSON字符串放在data-parameter属性中,然后在将参数传递给函数之前使用$.parseJSON将其转换为对象:
// If your data-parameter attribute contained a JSON string.
$('select').on('change', function() {
var func = $(this).find('option:selected').attr('data-function');
var param = $(this).find('option:selected').attr('data-parameter');
var paramObj = $.parseJSON(param);
var myInstance = new MyClass();
var funcRef = myInstance[func];
funcRef.call(myInstance, paramObj);
});