Pregunta Probando si el valor es una función


Necesito probar si el valor de un formulario onsubmit es una función. El formato es típicamente onsubmit="return valid();". ¿Hay alguna forma de saber si se trata de una función y si se puede llamar? Usar typeof solo devuelve que es una cadena, lo cual no me ayuda mucho.

EDITAR: Por supuesto, entiendo que "return valid ();" es una cadena He replacedesciéndalo a "válido ();" e incluso "válido ()". Quiero saber si alguno de ellos es una función.

EDITAR: Aquí hay un código, que puede ayudar a explicar mi 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: Aquí está el nuevo código. Parece que todavía tengo que usar una evaluación, porque al llamar a form.submit () no se activan los envíos 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;
    }
} );

Sugerencias sobre posiblemente cómo hacer esto mejor?


76
2018-04-28 14:44


origen


Respuestas:


Estoy reemplazando un botón de enviar con un   enlace de anclaje Desde que llama   form.submit () no se activa   onsubmit's, lo estoy encontrando, y   eval () ing mismo. Pero me gustaría   verificar si la función existe antes   simplemente evalúa () lo que hay allí. - 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>

EDITAR: falta el parámetro f en la función testOnsubmitAndSubmit

Lo anterior debería funcionar independientemente de si asigna el onsubmit Atributo HTML o asignarlo en JavaScript:

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

74
2018-04-28 18:48



Tratar

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

47
2018-04-28 14:50



Podrías simplemente usar el typeof operador junto con un operador ternario para abreviar:

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

Si se trata de una función, la llamamos y le devolvemos el valor de retorno; de lo contrario, solo devuelva true

Editar:

No estoy muy seguro de lo que realmente quieres hacer, pero trataré de explicar qué podría estar pasando.

Cuando declaras tu onsubmit código dentro de su html, se convierte en una función y por lo tanto es invocable desde el "mundo" de JavaScript. Eso significa que esos dos métodos son equivalentes:

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

Estas dos funciones serán ambas y ambas serán invocables. Puede probar cualquiera de los que usan el typeof operador que debería arrojar el mismo resultado: "function".

Ahora, si asigna una cadena a la propiedad "onsubmit" a través de JavaScript, seguirá siendo una cadena, por lo tanto, no se puede llamar. Tenga en cuenta que si aplica el typeof operador contra ella, obtendrá "string" en lugar de "function".

Espero que esto pueda aclarar algunas cosas. Por otra parte, si desea saber si dicha propiedad (o cualquier identificador para el asunto) es una función e invocable, la typeof el operador debería hacer el truco. Aunque no estoy seguro de si funciona correctamente en varios marcos.

Aclamaciones


12
2018-04-28 15:17



¿Qué navegador estás usando?

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

Esto me da "function"en IE7 y FireFox.


5
2018-04-28 14:49



Asegúrese de estar llamando a typeof en la función real, no a un literal de cadena:

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

typeof "x"; // returns "string"

typeof x; // returns "function"

3
2018-04-28 14:48



utilizando una variable basada en cadenas como ejemplo y haciendo uso instanceof Function  Registra la función ... asigna la variable ... comprueba que la variable es el nombre de la función ... haz un preproceso ... asigna la función a una nueva var ... luego llama a la función.

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
2018-04-28 14:49



Puedes intentar modificar esta tecnica para satisfacer sus necesidades:

 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
2018-04-28 17:32