Pergunta

Eu preciso testar se o valor de onsubmit de um formulário é uma função. O formato é tipicamente onsubmit="return valid();". Existe uma maneira de saber se esta é uma função, e se é que pode ser chamado? Utilizando typeof retorna apenas que é uma string, que não me ajuda muito.

Editar : Claro, eu entendo que o "retorno válido ();" é uma string. Eu replaced-lo para "válido ();", e mesmo "válido ()". Eu quero saber se qualquer uma delas é uma função.

Editar : Aqui está algum código, o que pode ajudar a explicar o 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 eu ainda tenho que usar um eval, porque chamando form.submit () não dispara existente 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;
    }
} );

Sugestões sobre possivelmente como fazer isso melhor?

Foi útil?

Solução

Eu estou substituindo um botão de envio com um link de âncora. desde chamando form.submit () não ativa do onsubmit, eu estou achando, e eval () ing-lo eu mesmo. Mas eu gostaria de verificar se a função existe antes apenas eval () ing o que está lá. - 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: faltando parâmetro f em função testOnsubmitAndSubmit

O acima deve funcionar independentemente de você atribuir o atributo onsubmit HTML ou atribuí-lo em JavaScript:

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

Outras dicas

Tente

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

Você poderia simplesmente usar o operador typeof juntamente com um operador ternário para breve:

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

Se for uma função podemos chamá-lo e devolvê-lo do valor de retorno, caso contrário, basta retornar true

Editar:

Eu não tenho certeza do que você realmente quer fazer, mas vou tentar explicar o que pode estar acontecendo.

Quando você declara o seu código onsubmit dentro do seu html, ele se transformou em uma função e, assim, a sua pode ser chamado de "mundo" do JavaScript. Isso significa que esses dois métodos são equivalentes:

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

Estes dois serão ambas as funções e ambos será exigível. Você pode testar qualquer daqueles que usam o operador typeof que deve Rendimento o mesmo resultado:. "function"

Agora, se você atribuir uma string para a propriedade "onsubmit" via JavaScript, ele permanecerá uma string, portanto, não pode ser chamado. Note que se você aplicar o operador typeof contra ela, você vai ter "string" vez de "function".

Espero que isso possa esclarecer algumas coisas. Então, novamente, se você quer saber se tal propriedade (ou qualquer identificador para o assunto) é uma função e exigível, o operador typeof deve fazer o truque. Embora eu não tenho certeza se ele funciona corretamente em vários frames.

Felicidades

O navegador você está usando?

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

Isso me dá "function" no IE7 e Firefox.

Certifique-se de que você está chamando typeof sobre a função real, não um literal string:

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

typeof "x"; // returns "string"

typeof x; // returns "function"

usando uma variável baseada string como exemplo e fazendo instanceof Function uso Você registrar o function..assign a variável ... verificar a variável é o nome da função ... fazer pré-processo ... atribuir a função a nova var ... em seguida, chamar 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();
}

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.');
 }

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 ligada a um elemento HTML, que tem o este ponteiro ligado a esse elemento FORM e também tem um parâmetro chamado event que conterá dados sobre o evento enviar.

Sob estas circunstâncias, eu não entendo como você tem uma string como resultado de uma operação de typeof. Você deve dar mais detalhes, melhor algum código.

Editar (como uma resposta à sua segunda edição):

Eu acredito que o manipulador anexado ao atributo HTML irá executar independentemente do código acima. Ainda mais, você poderia tentar pará-lo de alguma forma, mas, parece que 3 FF, IE 8, Chrome 2 e Opera 9 estão executando o manipulador atributo HTML em primeiro lugar e, em seguida, a um ligado (eu não testado 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 a sua expressão regular irá extrair a string "válido ();"., Que definitivamente não é uma função

Se for uma string, você poderia supor / espero que seja sempre da forma

return SomeFunction(arguments);

parse para o nome da função, e depois ver se essa função é definida usando

if (window[functionName]) { 
    // do stuff
}

Bem, "return valid();" é uma corda, de modo que é correto.

Se você quiser verificar se ele tem uma função anexado em vez disso, você pode tentar o seguinte:

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

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

Eu acho que a fonte de confusão é a distinção entre atributo de um nó e o correspondente propriedade .

Você está usando:

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

Você está lendo diretamente o onsubmit atributo 's valor (que deve ser uma string). Em vez disso, você deve acessar o onsubmit 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> 

Este rendimentos:

form1 onsubmit property: (function) function onsubmit(event) { return valid(); }
form1 onsubmit attribute: (string) return valid()
  if ( window.onsubmit ) {
     //
  } else {
     alert("Function does not exist.");
  }

Você sempre pode usar uma das funções typeof em JavaScript blogues como de Chris Ocidente. Usando uma definição, como a seguir para a função typeOf() iria funcionar:

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

Esta função (que é declarado no namespace global, pode ser usado como este:

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

Se for uma função, "Função" será devolvido. Se for uma string, "String" será devolvido. Outros valores possíveis são mostradas aqui .

// 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
    }
}

Uma simples verificação como este vai deixar você saber se ele existe / definidos:

if (this.onsubmit)
{
  // do stuff;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top