2015-07-21 79 views
1

编辑:这个问题是“我如何调用一个JavaScript函数,当我拥有的是一个包含其名称的字符串”的副本。 dom交互是一种分心。发送选择元素没有eval或复制和粘贴

当用户从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> 

修订二将函数存储在值字段中并调用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

'(ClosureObject [selection.value])(); // ClosureObject可以是Global或Root scope'或者简单地取决于函数的定义位置 – vinayakj

+0

@vinayakj谢谢你的回复。尽管如此,我还是不能完全一致 - ClosureObject与“修订版本1”有什么区别? –

+0

你不需要创建一个“查找表”对象 – vinayakj

回答

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>

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> 
+0

谢谢。我喜欢从单个字典中填充dom和回调函数的方法。虽然vinayakj的观察优雅很难! –