2009-04-28 50 views
72

我需要測試窗體的值onsubmit是否爲函數。格式通常是onsubmit="return valid();"。有沒有辦法判斷這是一個函數,如果它是可調用的?使用typeof只是返回它是一個字符串,這對我沒有多大幫助。測試值是否爲函數

編輯:當然,我明白「return valid();」是一個字符串。我已將replace記錄爲「valid();」,甚至「valid()」。我想知道這些是否是一種功能。

編輯:下面是一些代碼,這可能有助於解釋我的問題:

$("a.button").parents("form").submit(function() { 
    var submit_function = $("a.button").parents("form").attr("onsubmit"); 
    if (submit_function && typeof(submit_function.replace(/return /,"")) == 'function') { 
     return eval(submit_function.replace(/return /,"")); 
    } else { 
     alert("onSubmit is not a function.\n\nIs the script included?"); return false; 
    } 
}); 

編輯2:這裏是新的代碼。看來我仍然必須使用eval,因爲調用form.submit()不會觸發現有的onsubmits。

var formObj = $("a.button").parents("form"); 
formObj.submit(function() { 
    if (formObj[0].onsubmit && typeof(formObj.onsubmit) == 'function') { 
     return eval(formObj.attr("onsubmit").replace(/return /,"")); 
    } else { 
     alert("onSubmit is not a function.\n\nIs the script included?"); 
     return false; 
    } 
}); 

關於可能如何做得更好的建議?

回答

70

我更換提交按鈕與 錨鏈接。由於調用 form.submit()不會激活 onsubmit,我正在查找它,並自行評估它。但我想 檢查功能是否存在 只是eval()有什麼。 - gms8994

<script type="text/javascript"> 
function onsubmitHandler() { 
    alert('running onsubmit handler'); 
    return true; 
} 
function testOnsubmitAndSubmit(f) { 
    if (typeof f.onsubmit === 'function') { 
     // onsubmit is executable, test the return value 
     if (f.onsubmit()) { 
      // onsubmit returns true, submit the form 
      f.submit(); 
     } 
    } 
} 
</script> 

<form name="theForm" onsubmit="return onsubmitHandler();"> 
<a href="#" onclick=" 
    testOnsubmitAndSubmit(document.forms['theForm']); 
    return false; 
"></a> 
</form> 

編輯:缺少參數f在功能testOnsubmitAndSubmit

您是否分配onsubmit HTML屬性或JavaScript中分配給它上面應該不論工作:

document.forms['theForm'].onsubmit = onsubmitHandler; 
-3

這樣一個簡單的檢查將讓你知道,如果它存在/定義:

if (this.onsubmit) 
{ 
    // do stuff; 
} 
+5

這是行不通的。當onsubmit也是非空字符串時,if將斷言爲TRUE。 – Seb 2009-04-28 14:48:59

+1

一個可怕的測試方法,如果某個東西是一個函數 - 如前所述,並且更清晰:任何「真理」都會導致此代碼「做東西」,而這可能不是預期的結果。如果將this.onsubmit設置爲值5或「hello」或JavaScript中的任何其他值爲true的值,您將會遇到意外的行爲。 – 2009-04-28 20:22:20

+0

問題的主題是詢問如何檢查是否存在問題。這就是我所說的 - 不多也不少。 – Kon 2009-04-29 20:33:19

3

確保您的實際功能,而不是一個字符串的typeof呼籲:

function x() { 
    console.log("hi"); 
} 

typeof "x"; // returns "string" 

typeof x; // returns "function" 
5

什麼瀏覽器是否在使用?

alert(typeof document.getElementById('myform').onsubmit); 

這給了我在IE7和FireFox中的「function」。

+0

即使你的onsubmit是「返回有效();」? – 2009-04-28 15:23:58

+1

是的 - 不要忘記,你不能在功能之外「返回」。 – Greg 2009-04-28 16:01:45

+0

只要定義爲HTML屬性,form.onsubmit將始終是一個函數。看到我的答案。 – 2009-04-28 17:39:53

3

你可以嘗試修改this technique,以滿足您的需求:

function isFunction() { 
    var functionName = window.prompt('Function name: '); 
    var isDefined = eval('(typeof ' + functionName + '==\'function\');'); 
    if (isDefined) 
    eval(functionName + '();'); 
    else 
    alert('Function ' + functionName + ' does not exist'); 
} 
function anotherFunction() { 
    alert('message from another function.'); 
} 
46

嘗試

if (this.onsubmit instanceof Function) { 
    // do stuff; 
} 
1

好,"return valid();"一個字符串,所以這是正確的。

如果你想檢查是否有代替附加的功能,你可以試試這個:

formId.onsubmit = function(){ /* */ } 

if(typeof formId.onsubmit == "function"){ 
    alert("it's a function!"); 
} 
2

如果它是一個字符串,你可以假設/希望它的形式總是

return SomeFunction(arguments); 

解析爲函數的名稱,然後看看是否函數被定義使用

if (window[functionName]) { 
    // do stuff 
} 
1
if (window.onsubmit) { 
    // 
    } else { 
    alert("Function does not exist."); 
    } 
12

你可以簡單地用一個三元運營商使用typeof運營商一起簡稱:

onsubmit="return typeof valid =='function' ? valid() : true;" 

如果我們把它並返回它的返回值的函數,否則直接返回true

編輯:

我不太清楚你真正想做什麼,但我會盡力解釋可能發生的事情。

當你在你的html中聲明你的onsubmit代碼時,它會變成一個函數,因此它可以從JavaScript「世界」中調用。這意味着這兩種方法是等價的:

HTML: <form onsubmit="return valid();" /> 
JavaScript: myForm.onsubmit = function() { return valid(); }; 

這兩個都是函數,都是可調用的。您可以使用typeof運算符來測試其中的任何運算符,它們應該具有相同的結果:"function"

現在,如果您通過JavaScript爲「onsubmit」屬性指定一個字符串,它仍然是一個字符串,因此無法調用。請注意,如果您將typeof運算符應用於此運算符,則會得到"string"而不是"function"

我希望這可以澄清一些事情。再次,如果你想知道這樣的屬性(或任何標識符)是一個函數並且可以調用,那麼typeof運營商應該做的。儘管我不確定它是否能夠在多個幀中正常工作。當定義爲HTML形式元素的屬性

乾杯

2

form.onsubmit將始終是一個函數。它是附加到HTML元素的某種匿名函數,其中這個指針綁定到該FORM元素,並且還有一個名爲event的參數,該參數將包含有關submit事件的數據。

在這些情況下,我不明白你是如何得到一個字符串作爲typeof操作的結果。你應該提供更多的細節,更好的代碼。

編輯(如你的第二個編輯的響應):

我相信不管連接到HTML屬性的處理程序將執行上面的代碼。此外,你可以嘗試以某種方式阻止它,但是,看起來FF 3,IE 8,Chrome 2和Opera 9首先執行HTML屬性處理程序,然後是附加的屬性處理程序(我沒有使用jQuery進行測試雖然,但與addEventListener和attachEvent)。所以...你想要完成什麼?

順便說一句,你的代碼不工作,因爲你的正則表達式會提取字符串「valid();」,這絕對不是一個函數。

1

我認爲混淆的根源是節點的屬性和相應的屬性之間的區別。

您使用:

$("a.button").parents("form").attr("onsubmit") 

你直接讀取onsubmit屬性的值(必須是一個字符串)。相反,你應該訪問節點的onsubmit財產

$("a.button").parents("form").prop("onsubmit") 

下面是一個簡單的測試:

<form id="form1" action="foo1.htm" onsubmit="return valid()"></form> 
<script> 
window.onload = function() { 
    var form1 = document.getElementById("form1"); 

    function log(s) { 
     document.write("<div>" + s + "</div>"); 
    } 

    function info(v) { 
     return "(" + typeof v + ") " + v; 
    } 

    log("form1 onsubmit property: " + info(form1.onsubmit)); 
    log("form1 onsubmit attribute: " + info(form1.getAttribute("onsubmit"))); 
}; 
</script> 

這產生了:

 
form1 onsubmit property: (function) function onsubmit(event) { return valid(); } 
form1 onsubmit attribute: (string) return valid() 
0

你可以始終在JavaScript博客上使用typeOf函數之一,例如Chris West's。使用的定義,如爲typeOf()功能下面將工作:

function typeOf(o){return {}.toString.call(o).slice(8,-1)} 

此功能(在全局命名空間中聲明,可以用這樣的:

alert("onsubmit is a " + typeOf(elem.onsubmit)); 

如果它是一個功能,「功能」將使用基於字符串的無功返回。如果它是一個字符串,「字符串」將被退回。其他可能的值顯示here

0
// This should be a function, because in certain JavaScript engines (V8, for 
// example, try block kills many optimizations). 
function isFunction(func) { 
    // For some reason, function constructor doesn't accept anonymous functions. 
    // Also, this check finds callable objects that aren't function (such as, 
    // regular expressions in old WebKit versions), as according to EcmaScript 
    // specification, any callable object should have typeof set to function. 
    if (typeof func === 'function') 
     return true 

    // If the function isn't a string, it's probably good idea to return false, 
    // as eval cannot process values that aren't strings. 
    if (typeof func !== 'string') 
     return false 

    // So, the value is a string. Try creating a function, in order to detect 
    // syntax error. 
    try { 
     // Create a function with string func, in order to detect whatever it's 
     // an actual function. Unlike examples with eval, it should be actually 
     // safe to use with any string (provided you don't call returned value). 
     Function(func) 
     return true 
    } 
    catch (e) { 
     // While usually only SyntaxError could be thrown (unless somebody 
     // modified definition of something used in this function, like 
     // SyntaxError or Function, it's better to prepare for unexpected. 
     if (!(e instanceof SyntaxError)) { 
      throw e 
     } 

     return false 
    } 
} 
3

作爲例子和使用instanceof Function 您註冊的函數..分配變量...檢查變量是函數的名稱...做前處理...分配功能,以新的變種...然後調用功能。

function callMe(){ 
    alert('You rang?'); 
} 

var value = 'callMe'; 

if (window[value] instanceof Function) { 
    // do pre-process stuff 
    // FYI the function has not actually been called yet 
    console.log('callable function'); 
    //now call function 
    var fn = window[value]; 
    fn(); 
}