2013-01-25 16 views
2

我想寫一個通用表生成器,我可以告訴它函數在每個單元的onclick事件中調用。該函數然後定義在頁面上的其他位置。如何將存儲在字符串中的函數添加到jquery.click事件

問題是我無法在正確的時刻讓頁面評估函數。我希望它將字符串轉換爲構建DOM時的函數,而不是在觸發click事件時。也許這在Javascript/JQuery中是不可能的?

我原來寫在服務器端的C#代碼的簡化版本是:

string functionCall = "DoSomething(4);"; 
TableCell detailCell = new TableCell(); 
detailCell.Attributes.Add("onClick", functionCall); 
functionCall = "DoSomething(5);"; 
detailCell = new TableCell(); 
detailCell.Attributes.Add("onClick", functionCall); 

,當它被呈現在瀏覽器的HTML這就工作。它變成:

function DoSomething(p) 
{ 
     alert(p); 
} 

<td onclick="DoSomething(4)"></td> 
<td onclick="DoSomething(5)"></td> 

我想在Javascript中複製此功能。

如果我做的:

var functionCall = 'DoSomething(4);'; 
$('#detailCell').attr('onclick', functionCall); 

它不會火在IE7事件由於某種原因而觸發它在Chrome中。

如果我做的:

var functionCall = 'DoSomething(4);'; 
$('#detailCell1').click(function() { eval(functionCall); }); 
functionCall = 'DoSomething(5);'; 
$('#detailCell2').click(function() { eval(functionCall); }); 

那麼它不添加時單擊事件被改變functionCall的一段文字。相反,它會在單擊單元格時顯示functionCall。這意味着functionCall的值現在是錯誤的。

例如即使我點擊detailCell1,它總是會執行DoSomething(5),因爲這是functionCall的最後一個值。

如果我做的:

var functionCall = 'DoSomething(4);'; 
$('#detailCell1').click(eval(functionCall)); 

它添加click事件時,而被點擊時比立即運行在functionCall功能。

我希望這是有道理的,因爲它很難解釋。

基本上,我只希望能夠使用jQuery做

<td onclick="any javascript I feel like storing in a string"></td> 

這甚至可能嗎?

這是我第一次張貼在計算器所以請溫柔...

+0

爲什麼你需要它像一個字符串? –

+0

爲什麼你問他爲什麼需要它像一個字符串? – jAndy

+0

爲什麼不能直接調用該函數。 –

回答

2

嘗試......

var functionCall = 'DoSomething(4);'; 

$('#detailCell1').click((function (code) { 
    return function() { 
    eval(code); 
    }; 
}(functionCall))); 

這裏會發生什麼事是你在捕捉您所創建的時間字符串處理程序通過將其分配給參數「代碼」。

在您當前的場景中,單擊處理程序在單擊時使用該字符串的值,而不是在創建處理程序時使用該值。

這被稱爲閉包!

(function (code) { 
    return function() { 
    eval(code); 
    }; 
}(functionCall)); 

functionCall值被分配給代碼參數。 現在,當您更改functionCall時,代碼參數仍指舊值。

+0

哇這個工程,但我真的不明白它。如果我只能在瀏覽器中編寫可愛的編譯C#程序!我將對封閉進行一些研究。非常感謝您的時間巴特。 – I3enners

+0

@ user2010602而不是發出函數調用作爲字符串使用函數文字。它使代碼更快更容易閱讀。沒有理由爲什麼你應該有額外的步驟來評估一個常量(你的函數調用) –

0

不清楚爲什麼函數調用應該是字符串。正如我所看到的,你有很多單元應該爲每個單元使用不同的參數激發一個函數。

在這種情況下,我接下來會做:

TableCell detailCell = new TableCell(); 
detailCell.Attributes.Add("class", "detailCell"); 
detailCell.Attributes.Add("data-num", "4"); 

detailCell = new TableCell(); 
detailCell.Attributes.Add("class", "detailCell"); 
detailCell.Attributes.Add("data-num", "5"); 

而且比,介於JS:上表單元格

$(function() { 
    $(".detailCell").click(function(){ 
     DoSomething($(this).data("num")); 
    }); 
}) 

class是需要的,以便輕鬆地分配單擊處理程序的所有細節細胞,所以你不需要寫這樣的東西:

$('#detailCell1').click(function() { DoSomething(4); }); 
$('#detailCell2').click(function() { DoSomething(5); }); 

This detailCell.Attributes.Add("data-num", "5");允許將應該用作DoSomething的參數的數字。你可以看到它在這一行中被採用:DoSomething($(this).data("num"));jQuery.data函數正在被使用。並且this將指向被點擊的元素。 $(function() {}) - 這是jQuery.ready函數的簡寫。使用它可以保證當頁面準備好使用時,該函數中的代碼將被執行。

+0

感謝FAngel,如果我找不到像我一樣的方式來執行它,那麼使用id屬性就會成爲我的備份方法最初設想。 – I3enners

0

,而不是首先創建它作爲一個字符串,然後試圖評估該字符串,你可以簡單地創建一個函數值(函數對象太JS)

所以不是

var functionCall = 'DoSomething(4);'; 
$('#detailCell1').click(eval(functionCall)); 

$('#detailCell1').click(function(e){DoSomething(4);}); 

這會爲每次點擊創建一個新功能。 (在你的情況,你可以省略e參數,它只是存在,使需要的任何變化很容易

,如果你有一組參數你逝去,你可以創建一個工廠方法

var doSomethingFactory = function(num){ 
    return function(e) { DoSomething(num);}; 
} 
$('#detailCell1').click(doSomethingFactory(4)); 
0

由於根據我的理解,你必須用不同的參數來調用不同的函數。爲了達到這個目的,你要生成字符串,並嘗試使用eval()函數來調用這些函數。讓我們按如下方式做:

1.只要通過函數調用字符串爲數組,因此在加載您的JavaScript代碼如下所示,

var functioncalls = ['DoSomething(1)','DoSomethingMore(1,2)','DoDifferent("hello world")']; 

2.然後循環在JavaScript中的函數調用陣列,並將它們分配到不同的點擊事件,爲了避免複雜性,我假設你選擇器是#detailCell0,#detailCell1,#detailCell2等。然後你的代碼如下所示,

$(function(){ 
     functioncalls.forEach(function(functioncall,index){ 
      $("detailCell"+index).click(function(){ 
       eval(functioncall); 
      }) 
     }); 
    }) 

注意:有很多方法可以做到這一點。

相關問題