您可以将 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 07:30:21  来源:igfitidea点击:

Can you set a javascript function name as an html attribute?

javascriptjqueryhtml

提问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。(见下文。)

evalexample:

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. (reduceis 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. datainitializes 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 datato access data-*attributes is a common misconception.

旁注:除非你做的不仅仅是检索data-*属性的值,否则不要使用data,使用attrdata初始化元素的数据缓存,读入该元素的所有data-*属性,并将它们复制到缓存。如果您不使用它,则没有理由这样做。您data用来访问data-*属性的想法是一种常见的误解。

回答by canon

Sure... assuming that showAllElementsis 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.

这样做的好处是,只要将它们添加到同一外壳范围内的元素中,就可以拥有外壳等中的功能。