您可以将 javascript 函数名称设置为 html 属性吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27447755/
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
Can you set a javascript function name as an html attribute?
提问by Jarryd Goodman
Is it possible to write an html attribute that will store the name of a javascript function and then extract that val() and execute that function? Example:
是否可以编写一个 html 属性来存储 javascript 函数的名称,然后提取该 val() 并执行该函数?例子:
<button id="example" data-function-name="showAllElements()">
and then in js/jq
然后在 js/jq
fn = $('#example').data('function-name');
fn;
回答by T.J. Crowder
You can, yes. Whether you shouldis another question entirely, to which the answer is almost certainly "no" (in terms of executing the string; in terms of the alternative shown below, there are times it's useful).
你可以,是的。您是否应该完全是另一个问题,答案几乎肯定是“否”(就执行字符串而言;就下面显示的替代方案而言,有时它很有用)。
The way you'd evaluate that snippet of code (what you have isn'tjust a function name, because of the ()
) would be to use the dreaded eval
:
您评估该代码片段的方式(您拥有的不仅仅是函数名称,因为()
)将使用 dreaded eval
:
eval(fn);
There's almost always a better option than using eval
. (See below.)
几乎总是有比使用更好的选择eval
。(见下文。)
eval
example:
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>
Oneof the better options is to store your function references as properties on an object, and then use brackets notation to get the function reference based on the function name:
其中的更好的选择是给你的函数的引用存储为一个对象的属性,然后使用方括号表示法基于函数名来获取函数引用:
Example:
例子:
var functions = {
showAllElements: function() {
alert("showAllElements was called");
}
};
$("#example").on("click", function() {
var fn = $("#example").attr("data-function-name");
functions[fn]();
});
<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>
Note that there, I'm just storing the function name, not arbitrary code.
请注意,在那里,我只是存储函数名称,而不是任意代码。
Update: See canon's answerfor a clever way to handle it if you have your functions nested inside an object, e.g. mumble.foo.doSomething
, using reduce
. (reduce
is an ES5 feature, but it's polyfillable.)
更新:见佳能的答案对一个聪明的方法来处理它,如果你有你的函数嵌套在一个对象的内部,例如mumble.foo.doSomething
,使用reduce
。(reduce
是一个 ES5 特性,但它是可填充的。)
Side note: Unless you're doing something more than just retrieving the value of a data-*
attribute, don't use data
, use attr
. data
initializes a data cache for the element, reads in all of the data-*
attributes for that element, and copies them to cache. If you're not using it, there's no reason to do that. The idea that you use data
to access data-*
attributes is a common misconception.
旁注:除非你做的不仅仅是检索data-*
属性的值,否则不要使用data
,使用attr
。data
初始化元素的数据缓存,读入该元素的所有data-*
属性,并将它们复制到缓存。如果您不使用它,则没有理由这样做。您data
用来访问data-*
属性的想法是一种常见的误解。
回答by canon
Sure... assuming that showAllElements
is global...
当然......假设这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>
Now, let's say your attribute is actually something harrier, like: foo.bar.showAllElements
...
现在,让我们假设您的属性实际上是更高级的东西,例如: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>
回答by Adam
While I don't think you can do it this way with an HTML attribute directly (except with global functions as mentiopned above), if you can add the data element with javascript at page load you can do it directly. As said here, jquery's $.data()
is not the same as the data-*
attributes. According to the jQuery docs, the value stored using .data()
"The new data value; this can be any Javascript type except undefined."
虽然我不认为你可以直接使用 HTML 属性来做到这一点(除了上面提到的全局函数),如果你可以在页面加载时使用 javascript 添加数据元素,你可以直接做到这一点。正如这里所说,jquery$.data()
与data-*
属性不同。根据jQuery 文档,使用“新数据值;这可以是除未定义之外的任何 Javascript 类型”存储的值.data()
。
So you can store a function directly using
所以你可以直接使用存储函数
function my_func(){
// Do stuff
}
$(function(){
$('#foo').data('func', my_func);
});
And then later
然后后来
var func = $('#foo').data('func');
if( $.isFunction( func ) ) {
func.call( $('#foo'), somearg );
}
I have an example as a fiddle.
我有一个例子作为小提琴。
This has the advantage that you can have the functions in enclosures, etc. as long as you add them to the elements within the same enclosure scope.
这样做的好处是,只要将它们添加到同一外壳范围内的元素中,就可以拥有外壳等中的功能。