Testare se il valore è una funzione
-
18-09-2019 - |
Domanda
Ho bisogno di verificare se il valore di onsubmit
di un modulo è una funzione. Il formato è in genere onsubmit="return valid();"
. C'è un modo per dire se si tratta di una funzione, e se è richiamabile? Utilizzando typeof restituisce solo che si tratta di una stringa, che non mi aiuta molto.
Modifica : Certo, capisco che "tornare valido ();" è una stringa. Ho replace
d giù a "valido ();", e anche "valido ()". Voglio sapere se uno di questi è una funzione.
Modifica : Ecco un po 'di codice, che può aiutare a spiegare il mio 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;
}
} );
Modifica 2 : Ecco il nuovo codice. Sembra che devo ancora utilizzare un eval, perché chiamando form.submit () non scatta esistente 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;
}
} );
Suggerimenti su eventualmente come fare questo meglio?
Soluzione
Sono la sostituzione di un pulsante di invio con una Link ancoraggio. Dal momento chiamando form.submit () non attiva onSubmit di, mi sto trovando, e eval () ing io stesso. Ma mi piacerebbe verificare se la funzione esiste prima solo eval () ing cosa c'è. - 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: manca il parametro f in funzione testOnsubmitAndSubmit
È possibile che questo dovrebbe funzionare indipendentemente dal fatto che si assegna l'attributo onsubmit
HTML o assegnarla in JavaScript:
document.forms['theForm'].onsubmit = onsubmitHandler;
Altri suggerimenti
Prova
if (this.onsubmit instanceof Function) {
// do stuff;
}
Si potrebbe semplicemente utilizzare l'operatore typeof
insieme a un operatore ternario in breve:
onsubmit="return typeof valid =='function' ? valid() : true;"
Se si tratta di una funzione che chiamiamo e il ritorno è il valore di ritorno, altrimenti solo tornare true
Modifica
Io non sono molto sicuro di quello che si vuole veramente fare, ma cercherò di spiegare che cosa potrebbe accadere.
Quando si dichiara il codice onsubmit
nel tuo html, esso viene trasformato in una funzione e quindi la sua callable dal "mondo" JavaScript. Ciò significa che questi due metodi sono equivalenti:
HTML: <form onsubmit="return valid();" />
JavaScript: myForm.onsubmit = function() { return valid(); };
Questi due saranno entrambe le funzioni ed entrambi sarà richiamabile. È possibile verificare qualsiasi di coloro che usano l'operatore typeof
che dovrebbe resa lo stesso risultato:. "function"
Ora, se si assegna una stringa per la proprietà "onsubmit" tramite JavaScript, rimarrà una stringa, quindi non callable. Si noti che se si applica l'operatore typeof
contro di esso, si otterrà "string"
invece di "function"
.
Spero che questo potrebbe chiarire un paio di cose. Poi di nuovo, se si vuole sapere se tali beni (o qualsiasi identificatore per la materia) è una funzione ed esigibili, l'operatore typeof
dovrebbe fare il trucco. Anche se non sono sicuro se funziona correttamente su più fotogrammi.
Saluti
Quale browser stai usando?
alert(typeof document.getElementById('myform').onsubmit);
Questo mi dà "function
" in IE7 e Firefox.
Assicurarsi che si sta chiamando typeof sulla funzione reale, non una stringa letterale:
function x() {
console.log("hi");
}
typeof "x"; // returns "string"
typeof x; // returns "function"
utilizzando una variabile basata stringa come esempio e facendo uso instanceof Function
Si registra il function..assign la variabile ... controlla la variabile è il nome della funzione di ... fare pre-processo ... assegnare la funzione di nuova var ... quindi chiamare la funzione.
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();
}
Si può provare a modificare questa tecnica base alle proprie esigenze:
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 sarà sempre una funzione quando definita come attributo HTML elemento del modulo. E 'una sorta di funzione anonima collegato a un elemento HTML, che ha il questo puntatore legata a quell'elemento FORM e ha anche un parametro denominato event
che conterrà i dati relativi all'evento presentare.
In queste circostanze non capisco come hai una stringa come risultato di un'operazione di typeof. Si dovrebbe dare maggiori dettagli, meglio qualche codice.
Modifica (come una risposta alla tua seconda modifica):
Credo che il gestore attaccato al attributo HTML eseguirà indipendentemente dal codice di cui sopra. Più ulteriormente più, si potrebbe provare a fermarlo in qualche modo, ma, sembra che FF 3, IE 8, Chrome 2 e Opera 9 sono in esecuzione il gestore attributo HTML, in primo luogo e poi quello allegato (non ho provato con jQuery però, ma con addEventListener e attachEvent). Allora ... cosa stai cercando di realizzare esattamente?
Tra l'altro, il codice non funziona perché l'espressione regolare estrarrà la stringa "valido ();"., Che sicuramente non è una funzione
Se si tratta di una stringa, si potrebbe supporre / sperare è sempre della forma
return SomeFunction(arguments);
analizzare per il nome della funzione, e poi vedere se tale funzione è definita utilizzando
if (window[functionName]) {
// do stuff
}
Bene, "return valid();"
è una stringa, in modo che è corretto.
Se si desidera controllare se ha una funzione in allegato, invece, si potrebbe provare questo:
formId.onsubmit = function (){ /* */ }
if(typeof formId.onsubmit == "function"){
alert("it's a function!");
}
Credo la fonte di confusione è la distinzione tra attributo di un nodo e il corrispondente proprietà .
Si sta utilizzando:
$("a.button").parents("form").attr("onsubmit")
Stai leggendo direttamente il onsubmit
attributo il valore s '(che deve essere una stringa). Invece, si dovrebbe accedere al onsubmit
Proprietà del nodo:
$("a.button").parents("form").prop("onsubmit")
Ecco un rapido 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>
Questo produce:
form1 onsubmit property: (function) function onsubmit(event) { return valid(); } form1 onsubmit attribute: (string) return valid()
if ( window.onsubmit ) {
//
} else {
alert("Function does not exist.");
}
È sempre possibile utilizzare una delle funzioni TypeOf sul blog di JavaScript, come di Chris occidentale . Utilizzando una definizione come il seguente per la funzione typeOf()
avrebbe funzionato:
function typeOf(o){return {}.toString.call(o).slice(8,-1)}
Questa funzione (che viene dichiarato nel namespace globale, può essere utilizzato in questo modo:
alert("onsubmit is a " + typeOf(elem.onsubmit));
Se si tratta di una funzione, "Funzione" verrà restituito. Se si tratta di una stringa, "Stringa" verrà restituito. Altri valori possibili sono mostrati href="http://gotochriswest.com/blog/2012/07/03/javascript-better-typeof-function/" qui .
// 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
}
}
Un semplice controllo come questo ti consente di sapere se esiste / definita:
if (this.onsubmit)
{
// do stuff;
}