是否可以编写一个html属性来存储javascript函数的名称,然后提取val()并执行该函数?例如:
<button id="example" data-function-name="showAllElements()">
然后在js / jq
fn = $('#example').data('function-name');
fn;
答案 0 :(得分:17)
你可以,是的。你应该是否完全是另一个问题,答案几乎肯定是“不”(就执行字符串而言;就下面显示的替代方案而言,有时它很有用)。
你评估代码片段的方式(你的不是只是一个函数名,因为()
)将使用可怕的{{1 }}:
eval
几乎总是比使用eval(fn);
更好的选择。 (见下文。)
eval
示例:
eval
$("#example").on("click", function() {
var fn = $("#example").attr("data-function-name");
eval(fn);
});
function showAllElements() {
alert("showAllElements was called");
}
一个更好的选项是将函数引用存储为对象的属性,然后使用括号表示法根据函数名称获取函数引用:
示例:
<button type="button" id="example" data-function-name="showAllElements()">Click Me</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
var functions = {
showAllElements: function() {
alert("showAllElements was called");
}
};
$("#example").on("click", function() {
var fn = $("#example").attr("data-function-name");
functions[fn]();
});
请注意,我只是存储函数名,而不是任意代码。
更新:如果您的功能嵌套在对象内,请参阅canon's answer以便巧妙地处理它,例如<button type="button" id="example" data-function-name="showAllElements">Click Me</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
,使用mumble.foo.doSomething
。 (reduce
是ES5功能,但它可以进行多种填充。)
旁注:除非您执行的操作不仅仅是检索reduce
属性的值,否则请勿使用data-*
,请使用data
。 attr
初始化元素的数据高速缓存,读入该元素的所有data
属性,并将它们复制到高速缓存。如果你没有使用它,没有理由这样做。您使用data-*
访问data
属性的想法是一种常见的误解。
答案 1 :(得分:8)
当然......假设showAllElements
是全球性的......
function showAllElements() {
console.log("test!");
}
document.querySelector("button").addEventListener("click", function(e) {
var functionName = this.getAttribute("data-function-name");
window[functionName]();
});
<button id="example" data-function-name="showAllElements">x</button>
现在,假设您的属性实际上是一种障碍,例如:foo.bar.showAllElements
...
var foo = {
bar: {
showAllElements: function() {
console.log("test!");
}
}
};
document.querySelector("button").addEventListener("click", function(e){
var functionName = this.getAttribute("data-function-name");
// Split by "." and resolve each segment starting at the window. Invoke with ()
functionName.split(".").reduce((o,n) => o[n], window)();
});
<button id="example" data-function-name="foo.bar.showAllElements">x</button>
答案 2 :(得分:0)
虽然我认为你不能直接用HTML属性这样做(除了上面提到的全局函数),如果你可以在页面加载时用javascript添加数据元素,你可以直接进行。如上所述,jquery的$.data()
与data-*
属性不同。根据{{3}},使用.data()
存储的值“新数据值;除了未定义之外,这可以是任何Javascript类型。”
所以你可以直接使用
存储一个函数function my_func(){
// Do stuff
}
$(function(){
$('#foo').data('func', my_func);
});
然后是
var func = $('#foo').data('func');
if( $.isFunction( func ) ) {
func.call( $('#foo'), somearg );
}
我有jQuery docs。
这样做的好处是,只要将它们添加到同一机箱范围内的元素中,就可以在机箱等中使用这些功能。