Necesito probar si el valor de un formulario onsubmit
es una función. El formato suele ser 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 que no me ayuda mucho.
EDITAR : Por supuesto, entiendo que "return valid ();" es una cuerda. Lo he replace
reducido a "válido ();", e incluso "válido ()". Quiero saber si alguno de esos 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;
}
} );
EDITAR 2 : Aquí está el nuevo código. Parece que todavía tengo que usar una evaluación, porque llamar a form.submit () no activa los 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;
}
} );
¿Sugerencias sobre posiblemente cómo hacer esto mejor?
fuente
f
es una instancia de formulario. Lo pasa a la función testOnsubmitAndSubmit como argumento. (Sé que esta pregunta es bastante antigua, pero tal vez mi respuesta le ahorre algo de tiempo a alguien :))Tratar
if (this.onsubmit instanceof Function) { // do stuff; }
fuente
Simplemente puede usar el
typeof
operador junto con un operador ternario para abreviar:onsubmit="return typeof valid =='function' ? valid() : true;"
Si es una función, la llamamos y devolvemos su valor de retorno, de lo contrario, simplemente devuelve
true
Editar:
No estoy muy seguro de lo que realmente quiere hacer, pero intentaré explicarle lo que podría estar sucediendo.
Cuando declaras tu
onsubmit
código dentro de tu html, se convierte en una función y, por lo tanto, se puede llamar 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 serán funciones y ambas serán invocables. Puede probar cualquiera de los que utilizan el
typeof
operador que debe Yeld el mismo resultado:"function"
.Ahora, si asigna una cadena a la propiedad "onsubmit" a través de JavaScript, seguirá siendo una cadena, por lo que no se puede llamar. Tenga en cuenta que si aplica el
typeof
operador en su contra, obtendrá en"string"
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 y se puede llamar, el
typeof
operador debería hacer el truco. Aunque no estoy seguro de si funciona correctamente en varios marcos.Salud
fuente
¿Qué navegador estás usando?
alert(typeof document.getElementById('myform').onsubmit);
Esto me da "
function
" en IE7 y FireFox.fuente
usando una variable basada en una cadena como ejemplo y haciendo uso
instanceof Function
Registra la función ... asigna la variable ... verifica que la variable sea el nombre de la función ... haz el preproceso ... asigna la función a la nueva var ... luego llamar 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(); }
fuente
Asegúrese de llamar a typeof en la función real, no en un literal de cadena:
function x() { console.log("hi"); } typeof "x"; // returns "string" typeof x; // returns "function"
fuente
Puede intentar modificar esta técnica para adaptarla a 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.'); }
fuente
form.onsubmit siempre será una función cuando se defina como un atributo de HTML el elemento de formulario. Es una especie de función anónima adjunta a un elemento HTML, que tiene el puntero this vinculado a ese elemento FORM y también tiene un parámetro llamado
event
que contendrá datos sobre el evento de envío.En estas circunstancias, no entiendo cómo obtuvo una cadena como resultado de un tipo de operación. Deberías dar más detalles, mejor algo de código.
Editar (como respuesta a su segunda edición):
Creo que el controlador adjunto al atributo HTML se ejecutará independientemente del código anterior. Además, podría intentar detenerlo de alguna manera, pero parece que FF 3, IE 8, Chrome 2 y Opera 9 están ejecutando el controlador de atributos HTML en primer lugar y luego el adjunto (no probé con jQuery aunque, pero con addEventListener y attachEvent). Entonces ... ¿qué estás tratando de lograr exactamente?
Por cierto, su código no funciona porque su expresión regular extraerá la cadena "valid ();", que definitivamente no es una función.
fuente
Si es una cadena, puede asumir / esperar que siempre tenga la forma
return SomeFunction(arguments);
analizar el nombre de la función y luego ver si esa función se define usando
if (window[functionName]) { // do stuff }
fuente
Bueno,
"return valid();"
es una cuerda, eso es correcto.Si desea verificar si tiene una función adjunta en su lugar, puede probar esto:
formId.onsubmit = function (){ /* */ } if(typeof formId.onsubmit == "function"){ alert("it's a function!"); }
fuente
Creo que la fuente de confusión es la distinción entre el atributo de un nodo y la propiedad correspondiente .
Estás usando:
$("a.button").parents("form").attr("onsubmit")
Estás leyendo directamente el valor del
onsubmit
atributo (que debe ser una cadena). En su lugar, debe acceder a laonsubmit
propiedad del nodo:$("a.button").parents("form").prop("onsubmit")
He aquí una prueba rápida:
<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>
Esto produce:
fuente
if ( window.onsubmit ) { // } else { alert("Function does not exist."); }
fuente
¿No es
typeof xxx === 'function'
el mejor y el más rápido?Hice un banco en el que puedes probarlo, en comparación con instanceof y _undercore
Aquí un banco: https://jsbench.me/qnkf076cqb/1
fuente
Siempre puede utilizar una de las funciones typeOf en blogs de JavaScript como el de Chris West . Usar una definición como la siguiente para la
typeOf()
función funcionaría:function typeOf(o){return {}.toString.call(o).slice(8,-1)}
Esta función (que se declara en el espacio de nombres global, se puede utilizar así:
alert("onsubmit is a " + typeOf(elem.onsubmit));
Si es una función, se devolverá "Función". Si es una cadena, se devolverá "Cadena". Aquí se muestran otros valores posibles .
fuente
// 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 } }
fuente
Una simple verificación como esta le permitirá saber si existe / definido:
if (this.onsubmit) { // do stuff; }
fuente