你可以将javascript函数名称设置为html属性吗?

时间:2014-12-12 16:19:08

标签: javascript jquery html

是否可以编写一个html属性来存储javascript函数的名称,然后提取val()并执行该函数?例如:

<button id="example" data-function-name="showAllElements()">

然后在js / jq

fn = $('#example').data('function-name');

fn;

3 个答案:

答案 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-*,请使用dataattr初始化元素的数据高速缓存,读入该元素的所有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

这样做的好处是,只要将它们添加到同一机箱范围内的元素中,就可以在机箱等中使用这些功能。