Preciso testar se o valor de um formulário onsubmit
é uma função. O formato é tipicamenteonsubmit="return valid();"
. Existe uma maneira de saber se esta é uma função e se ela pode ser chamada? Usar typeof apenas retorna que é uma string, o que não me ajuda muito.
EDIT : Claro, eu entendo que "return valid ();" é uma string. Eu tenhoreplace
para "valid ();" e até "valid ()". Quero saber se alguma delas é uma função.
EDIT : Aqui está um código, que pode ajudar a explicar meu problema:
$("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 : Aqui está o novo código. Parece que ainda preciso usar um eval, porque chamar form.submit () não dispara onsubmits existentes.
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;
}
} );
Sugestões sobre como fazer isso melhor?
fonte
f
é uma instância de formulário. Você o passa para a função testOnsubmitAndSubmit como um argumento. (Eu sei que esta pergunta é muito antiga, mas talvez minha resposta poupe algum tempo :))Experimentar
if (this.onsubmit instanceof Function) { // do stuff; }
fonte
Você poderia simplesmente usar o
typeof
operador junto com um operador ternário para abreviar:onsubmit="return typeof valid =='function' ? valid() : true;"
Se for uma função, nós a chamamos e retornamos seu valor de retorno, caso contrário, apenas retornamos
true
Editar:
Não tenho certeza do que você realmente deseja fazer, mas tentarei explicar o que pode estar acontecendo.
Quando você declara seu
onsubmit
código dentro de seu html, ele se transforma em uma função e, portanto, pode ser chamado a partir do "mundo" do JavaScript. Isso significa que esses dois métodos são equivalentes:HTML: <form onsubmit="return valid();" /> JavaScript: myForm.onsubmit = function() { return valid(); };
Essas duas serão funções e ambas poderão ser chamadas. Você pode testar qualquer daqueles que usam o
typeof
operador que deve Rendimento o mesmo resultado:"function"
.Agora, se você atribuir uma string à propriedade "onsubmit" via JavaScript, ela permanecerá uma string, portanto, não pode ser chamada. Observe que se você aplicar o
typeof
operador a ele, obterá em"string"
vez de"function"
.Espero que isso esclareça algumas coisas. Então, novamente, se você quiser saber se essa propriedade (ou qualquer identificador para o assunto) é uma função e pode ser chamada, o
typeof
operador deve fazer o truque. Embora eu não tenha certeza se ele funciona corretamente em vários quadros.Felicidades
fonte
Qual navegador você está usando?
alert(typeof document.getElementById('myform').onsubmit);
Isso me dá "
function
" no IE7 e FireFox.fonte
usando uma variável baseada em string como exemplo e fazendo uso
instanceof Function
Você registra a função ... atribui a variável ... verifica se a variável é o nome da função ... faz o pré-processamento ... atribui a função a nova var ... então chame a função.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(); }
fonte
Certifique-se de chamar typeof na função real, não em um literal de string:
function x() { console.log("hi"); } typeof "x"; // returns "string" typeof x; // returns "function"
fonte
Você pode tentar modificar esta técnica para atender às suas necessidades:
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.'); }
fonte
form.onsubmit será sempre uma função quando definido como um atributo do elemento HTML do formulário. É algum tipo de função anônima anexada a um elemento HTML, que tem o ponteiro this ligado a esse elemento FORM e também tem um parâmetro chamado
event
que conterá dados sobre o evento submit.Nessas circunstâncias, não entendo como você obteve uma string como resultado de uma operação typeof. Você deve dar mais detalhes, melhor algum código.
Editar (como uma resposta à sua segunda edição):
Acredito que o manipulador anexado ao atributo HTML será executado independentemente do código acima. Além disso, você poderia tentar pará-lo de alguma forma, mas, parece que FF 3, IE 8, Chrome 2 e Opera 9 estão executando o manipulador de atributo HTML em primeiro lugar e depois o anexado (não testei com jQuery embora, mas com addEventListener e attachEvent). Então ... o que você está tentando realizar exatamente?
A propósito, seu código não está funcionando porque sua expressão regular irá extrair a string "valid ();", que definitivamente não é uma função.
fonte
Se for uma string, você pode assumir / esperar que esteja sempre na forma
return SomeFunction(arguments);
analise o nome da função e, em seguida, veja se essa função é definida usando
if (window[functionName]) { // do stuff }
fonte
Bem,
"return valid();"
é uma string, então está correto.Se você quiser verificar se há uma função anexada, você pode tentar o seguinte:
formId.onsubmit = function (){ /* */ } if(typeof formId.onsubmit == "function"){ alert("it's a function!"); }
fonte
Acho que a fonte de confusão é a distinção entre o atributo de um nó e a propriedade correspondente .
Você está usando:
$("a.button").parents("form").attr("onsubmit")
Você está lendo diretamente o valor do
onsubmit
atributo (que deve ser uma string). Em vez disso, você deve acessar aonsubmit
propriedade do nó:$("a.button").parents("form").prop("onsubmit")
Aqui está um teste rápido:
<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>
Isso produz:
fonte
if ( window.onsubmit ) { // } else { alert("Function does not exist."); }
fonte
Não é
typeof xxx === 'function'
o melhor e o mais rápido?Eu fiz um banco no qual você pode experimentá-lo, em comparação com instanceof e _underscore
Aqui está um banco: https://jsbench.me/qnkf076cqb/1
fonte
Você sempre pode usar uma das funções typeOf em blogs de JavaScript, como o de Chris West . Usar uma definição como a seguinte para a
typeOf()
função funcionaria:function typeOf(o){return {}.toString.call(o).slice(8,-1)}
Esta função (que é declarada no namespace global, pode ser usada assim:
alert("onsubmit is a " + typeOf(elem.onsubmit));
Se for uma função, "Function" será retornado. Se for uma string, "String" será retornado. Outros valores possíveis são mostrados aqui .
fonte
// 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 } }
fonte
Uma verificação simples como esta permitirá que você saiba se ele existe / está definido:
if (this.onsubmit) { // do stuff; }
fonte