Muszę sprawdzić, czy wartość formularza onsubmit
jest funkcją. Format to zazwyczaj onsubmit="return valid();"
. Czy istnieje sposób, aby stwierdzić, czy jest to funkcja i czy można ją wywołać? Użycie typeof po prostu zwraca, że jest to ciąg znaków, co niewiele mi pomaga.
EDYCJA : Oczywiście rozumiem, że "return valid ();" jest ciągiem. Mam replace
d go do "valid ();", a nawet "valid ()". Chcę wiedzieć, czy któryś z nich jest funkcją.
EDYCJA : Oto kod, który może pomóc wyjaśnić mój problem:
$("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;
}
} );
EDYCJA 2 : Oto nowy kod. Wygląda na to, że nadal muszę używać eval, ponieważ wywołanie form.submit () nie uruchamia istniejących funkcji 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;
}
} );
Sugestie, jak to zrobić lepiej?
źródło
f
jest instancją formularza. Przekazujesz go do funkcji testOnsubmitAndSubmit jako argument. (Wiem, że to pytanie jest dość stare, ale może moja odpowiedź kogoś uratuje :))Próbować
if (this.onsubmit instanceof Function) { // do stuff; }
źródło
Możesz po prostu użyć
typeof
operatora wraz z operatorem trójskładnikowym w skrócie:onsubmit="return typeof valid =='function' ? valid() : true;"
Jeśli jest to funkcja, nazywamy ją i zwracamy jej wartość zwracaną, w przeciwnym razie po prostu zwracamy
true
Edytować:
Nie jestem do końca pewien, co naprawdę chcesz zrobić, ale spróbuję wyjaśnić, co może się dziać.
Kiedy deklarujesz swój
onsubmit
kod w swoim html, zostaje on zamieniony w funkcję i tym samym można go wywołać ze „świata” JavaScript. Oznacza to, że te dwie metody są równoważne:HTML: <form onsubmit="return valid();" /> JavaScript: myForm.onsubmit = function() { return valid(); };
Te dwie będą obiema funkcjami i obie będą wywoływalne. Można przetestować każdy z nich za pomocą
typeof
operatora, który powinien yeld ten sam wynik:"function"
.Teraz, jeśli przypiszesz ciąg do właściwości „onsubmit” za pomocą JavaScript, pozostanie on ciągiem, a więc nie będzie można go wywołać. Zauważ, że jeśli zastosujesz do niego
typeof
operator, otrzymasz"string"
zamiast"function"
.Mam nadzieję, że to może wyjaśnić kilka rzeczy. Z drugiej strony, jeśli chcesz wiedzieć, czy taka właściwość (lub jakikolwiek identyfikator sprawy) jest funkcją i można ją wywołać,
typeof
operator powinien załatwić sprawę . Chociaż nie jestem pewien, czy działa poprawnie w wielu klatkach.Twoje zdrowie
źródło
Jakiej przeglądarki używasz?
alert(typeof document.getElementById('myform').onsubmit);
To daje mi "
function
" w IE7 i FireFox.źródło
używając zmiennej opartej na łańcuchu jako przykładu i używając
instanceof Function
Rejestrujesz funkcję..przydziel zmienną ... sprawdź, czy zmienna jest nazwą funkcji ... wykonaj wstępne przetwarzanie ... przypisz funkcję do nowej zmiennej ... następnie wywołać funkcję.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(); }
źródło
Upewnij się, że wywołujesz typeof dla rzeczywistej funkcji, a nie literału ciągu:
function x() { console.log("hi"); } typeof "x"; // returns "string" typeof x; // returns "function"
źródło
Możesz spróbować zmodyfikować tę technikę do swoich potrzeb:
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.'); }
źródło
form.onsubmit zawsze będzie funkcją, jeśli zostanie zdefiniowana jako atrybut HTML elementu formularza. Jest to rodzaj anonimowej funkcji dołączonej do elementu HTML, który ma wskaźnik this powiązany z elementem FORM, a także ma parametr o nazwie,
event
który będzie zawierał dane o zdarzeniu przesyłania.W tych okolicznościach nie rozumiem, w jaki sposób otrzymałeś ciąg znaków w wyniku operacji. Powinieneś podać więcej szczegółów, lepiej jakiś kod.
Edytuj (jako odpowiedź na twoją drugą edycję):
Uważam, że program obsługi dołączony do atrybutu HTML zostanie wykonany niezależnie od powyższego kodu. Co więcej, możesz spróbować jakoś to zatrzymać, ale wydaje się, że FF 3, IE 8, Chrome 2 i Opera 9 wykonują najpierw procedurę obsługi atrybutów HTML, a następnie tę dołączoną (nie testowałem z jQuery chociaż, ale z addEventListener i attachEvent). Więc ... co dokładnie próbujesz osiągnąć?
Nawiasem mówiąc, Twój kod nie działa, ponieważ wyrażenie regularne wyodrębni ciąg „valid ();”, który z pewnością nie jest funkcją.
źródło
Jeśli jest to ciąg, możesz założyć / mieć nadzieję, że zawsze ma formę
return SomeFunction(arguments);
przeanalizuj nazwę funkcji, a następnie sprawdź, czy ta funkcja jest zdefiniowana przy użyciu
if (window[functionName]) { // do stuff }
źródło
Cóż,
"return valid();"
to ciąg, więc to prawda.Jeśli chcesz sprawdzić, czy zamiast tego ma dołączoną funkcję, możesz spróbować tego:
formId.onsubmit = function (){ /* */ } if(typeof formId.onsubmit == "function"){ alert("it's a function!"); }
źródło
Myślę, że źródłem nieporozumień jest rozróżnienie między atrybutem węzła a odpowiadającą mu właściwością .
Używasz:
$("a.button").parents("form").attr("onsubmit")
Bezpośrednio odczytujesz wartość
onsubmit
atrybutu (która musi być ciągiem znaków). Zamiast tego powinieneś uzyskać dostęp doonsubmit
właściwości węzła:$("a.button").parents("form").prop("onsubmit")
Oto szybki test:
<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>
To daje:
źródło
if ( window.onsubmit ) { // } else { alert("Function does not exist."); }
źródło
Czy nie
typeof xxx === 'function'
jest najlepszy i najszybszy?Zrobiłem ławkę, w której możesz to wypróbować, w porównaniu z instancjami instanceof i _underscore
Tutaj ławka: https://jsbench.me/qnkf076cqb/1
źródło
Zawsze możesz użyć jednej z funkcji typeOf na blogach JavaScript, takich jak Chris West . Użycie definicji takiej jak poniższa dla
typeOf()
funkcji zadziałałoby:function typeOf(o){return {}.toString.call(o).slice(8,-1)}
Ta funkcja (która jest zadeklarowana w globalnej przestrzeni nazw, może być używana w następujący sposób:
alert("onsubmit is a " + typeOf(elem.onsubmit));
Jeśli jest to funkcja, zostanie zwrócony tekst „Funkcja”. Jeśli jest to ciąg znaków, zostanie zwrócony ciąg znaków. Tutaj pokazane są inne możliwe wartości .
źródło
// 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 } }
źródło
Takie proste sprawdzenie da ci znać, czy istnieje / zdefiniowane:
if (this.onsubmit) { // do stuff; }
źródło