2015-07-21 105 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的觀察優雅很難! –