编辑:这个问题与“我所拥有的是一个包含其名称的字符串时如何调用javascript函数”的重复。 dom互动是一种分心。
当用户从html select元素中选择一个选项时,我想调用N个不同的javascript函数之一。我想这样做而不重复自己或回归到eval()。
修订版1在选项的值字段中存储了字符串,然后将它们用作字典的索引。
<body>
<select onchange="dispatch(this)">
<option value="first_function_name">One</option>
<option value="second_function_name">Two</option>
</select>
</body>
<script>
function first_function() {console.log("There can be only one");}
function second_function() {console.log("Except when there are two");}
function dispatch(selection) {
var name = selection.value;
var lookup_table = {
first_function_name: first_function,
second_function_name: second_function
};
(lookup_table[name])();
}
</script>
Revision 2将函数存储在value字段中,并在其上调用eval。 Eval让我感到非常沉重。
<body>
<select onchange="dispatch(this)"> <!-- Not sure passing this is always OK -->
<option value="first_function()">One</option>
<option value="second_function()">Two</option>
</select>
</body>
<script>
function first_function() {console.log("There can be only one");}
function second_function() {console.log("Except when there are two");}
function dispatch(selection) {eval(selection.value);} /* yuck */
</script>
选项三是针对问题瞄准代码生成器,但这似乎是失败主义者。什么是理智的,惯用的解决方案?
答案 0 :(得分:1)
这是一个小例子(可能必须针对不同的浏览器进行调整):
<select id="mySelect"></select>
<script type="text/javascript">
(function() {
var select = document.getElementById("mySelect");
var options = [ { name: 'One', value:'one', callback: function() {console.log("There can be only one");}},
{ name: 'Two', value:'two', callback: function() {console.log("Except when there are two");}}];
options.forEach(
function(opt) {
var option = document.createElement("option");
option.text = opt.name;
option.value = opt.value;
select.add(option);
});
function onChange() {
options.some(function(option) {
if (option.value===select.value) {
option.callback();
return true;
}
});
}
select.addEventListener("change", onChange);
})();
</script>
答案 1 :(得分:1)
var closureObject = (function(){ // created scope
/* so now "this" becomes the closureObject and which has all functions as property and
can directly refer them by syntax Instance['propertyName'] */
var closureObject = {};
closureObject.first_function = function() {
alert("There can be only one");
}
closureObject.second_function = function(){
alert("Except when there are two");
}
return closureObject;
})();
function dispatch(selection) {
closureObject[selection](); // ClosureObject could be Global or scoped variable
}
<select onchange="dispatch(this.value)">
<option value="first_function">One</option>
<option value="second_function">Two</option>
</select>