Testowanie, czy wartość jest funkcją

Muszę sprawdzić, czy wartość formularza onsubmit jest funkcją. Format jest zazwyczaj onsubmit="return valid();". Czy istnieje sposób, aby stwierdzić, czy jest to funkcja i czy można ją wywołać? Używanie typeof zwraca tylko, że jest to ciąg znaków, co mi nie pomaga.

EDIT : oczywiście rozumiem, że" return valid (); " jest łańcuchem znaków. Mam replace D do " valid ();", a nawet " valid ()". Chcę wiedzieć, czy któreś z nich jest funkcją.

EDIT : oto jakiś kod, który może pomóż 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;
    }
} );

EDIT 2 : Oto nowy kod. Wygląda na to, że nadal muszę korzystać z evalu, ponieważ formularz wywołujący.submit () nie uruchamia istniejących onsubmitów.

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?

Author: Phil H, 2009-04-28

15 answers

Zamieniam przycisk submit na / align = "left" / Since calling forma.submit() nie aktywuje się onsubmit 'S, I' m finding it, and ewal () Ale chciałbym sprawdź czy funkcja istnieje przed wystarczy ocenić()co tam jest. - 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>

EDIT: Brak parametru f w funkcji testOnsubmitAndSubmit

Powyższe powinno działać niezależnie od tego, czy przypisujesz atrybut onsubmit HTML, czy przypisujesz go w JavaScript:

document.forms['theForm'].onsubmit = onsubmitHandler;
 75
Author: Grant Wagner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-04 08:40:42

Try

if (this.onsubmit instanceof Function) {
    // do stuff;
}
 48
Author: artemb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 14:50:05

Można po prostu użyć operatora typeof wraz z operatorem trójdzielnym w skrócie:

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

Jeśli jest to funkcja wywołujemy ją i zwracamy jej wartość, w przeciwnym razie po prostu zwracamy true

Edit:

Nie jestem do końca pewien, co naprawdę chcesz zrobić, ale postaram się wyjaśnić, co może się dziać.

Kiedy zadeklarujesz swój kod onsubmit w swoim html, zostanie on zamieniony w funkcję, a tym samym jego wywołanie z "świata" JavaScript. To znaczy że te dwie metody są równoważne:

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

Te dwie funkcje będą obiema funkcjami i obie będą wywoływalne. Możesz przetestować dowolne z nich używając operatora typeof, który powinien dać taki sam wynik: "function".

Teraz, jeśli przypiszesz łańcuch do właściwości "onsubmit" za pomocą JavaScript, pozostanie on ciągiem znaków, dlatego nie można go wywołać. Zauważ, że jeśli zastosujesz wobec niego operator typeof, 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 dowolny identyfikator w danej sprawie) jest funkcją i można ją wywołać, operator typeof powinien załatwić sprawę. Chociaż nie jestem pewien, czy działa poprawnie w wielu klatkach.

Cheers

 12
Author: Pablo Cabrera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 17:23:48

Jakiej przeglądarki używasz?

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

To daje mi "function " w IE7 i Firefoksie.

 5
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 14:49:00

Upewnij się, że wywołujesz typeof w rzeczywistej funkcji, a nie literalny łańcuch znaków:

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

typeof "x"; // returns "string"

typeof x; // returns "function"
 3
Author: matt b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 14:48:51

Używanie zmiennej opartej na łańcuchu jako przykładu i używanie instanceof Function Rejestrujesz funkcję..Przypisz zmienną...sprawdź, czy zmienna jest nazwą function...do proces wstępny... przypisanie funkcji do nowego var...następnie wywołaj 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();
}
 3
Author: CrandellWS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-26 22:30:58

Możesz spróbować zmodyfikować tę technikę do własnych 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.');
 }
 3
Author: cletus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-23 08:42:12

Formularz.onsubmit zawsze będzie funkcją, gdy zostanie zdefiniowany jako atrybut HTML elementu formularza. Jest to rodzaj anonimowej funkcji dołączonej do elementu HTML, który ma ten wskaźnik związany z tym elementem formularza, a także ma parametr o nazwie event, który będzie zawierał dane o zdarzeniu submit.

W tych okolicznościach nie rozumiem, skąd masz ciąg znaków w wyniku operacji typeof. Powinieneś podać więcej szczegółów, lepiej trochę kod.

Edit (w odpowiedzi na drugą edycję):

Wierzę, że handler dołączony do atrybutu HTML będzie działał niezależnie od powyższego kodu. Co więcej, możesz spróbować to jakoś zatrzymać, ale wygląda na to, że FF 3, IE 8, Chrome 2 i Opera 9 wykonują atrybut HTML handler w pierwszej kolejności, a następnie ten dołączony (nie testowałem z jQuery, ale z addEventListener i attachEvent). Więc... co próbujesz osiągnąć dokładnie?

Przy okazji, twój kod nie działa, ponieważ twoje Wyrażenie regularne wyodrębni łańcuch " valid ();", który zdecydowanie nie jest funkcją.

 2
Author: Ionuț G. Stan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 17:55:58

Jeśli jest to ciąg znaków, możesz założyć / mieć nadzieję, że zawsze ma postać

return SomeFunction(arguments);

Parse for the function name, and then see if that function is defined using

if (window[functionName]) { 
    // do stuff
}
 2
Author: millimoose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 19:42:44

Dobrze, "return valid();" jest ciągiem znaków, więc to prawda.

Jeśli chcesz sprawdzić, czy ma dołączoną funkcję, możesz spróbować tego:

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

if(typeof formId.onsubmit == "function"){
  alert("it's a function!");
}
 1
Author: Seb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 14:50:22

Myślę, że źródłem nieporozumień jest rozróżnienie pomiędzy atrybutem węzła a odpowiadającą mu właściwością .

Używasz:

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

Czytasz bezpośrednio onsubmit wartość atrybutu (która musi być ciągiem znaków). Zamiast tego powinieneś uzyskać dostęp do onsubmit własność 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> 

Daje to:

form1 onsubmit property: (function) function onsubmit(event) { return valid(); }
form1 onsubmit attribute: (string) return valid()
 1
Author: Ates Goral,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-03 17:46:50
  if ( window.onsubmit ) {
     //
  } else {
     alert("Function does not exist.");
  }
 1
Author: TStamper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-23 08:43:33

Zawsze możesz użyć jednej z funkcji typeOf na blogach JavaScript, takich jak Chrisa Westa . Użycie definicji takiej jak poniżej dla funkcji typeOf() będzie działać:

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ócona "Function". Jeśli jest to łańcuch, zostanie zwrócony "String". Inne możliwe wartości są pokazane tutaj .

 0
Author: Xavier Botomon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-03 17:42:28
// 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
    }
}
 0
Author: Konrad Borowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-31 08:28:34

Takie proste sprawdzenie da Ci znać, czy istnieje / jest zdefiniowane:

if (this.onsubmit)
{
  // do stuff;
}
 -3
Author: Kon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-28 14:47:16