Проверка того, является ли значение функцией
-
18-09-2019 - |
Вопрос
Мне нужно проверить, соответствует ли значение формы onsubmit
является функцией.Формат, как правило, onsubmit="return valid();"
.Есть ли способ определить, является ли это функцией и можно ли ее вызвать?Использование typeof просто возвращает, что это строка, что мне не очень помогает.
Редактировать:Конечно, я понимаю, что "return valid();" - это строка.У меня есть replace
уменьшите его до "valid();" и даже "valid()".Я хочу знать, является ли что-либо из этого функцией.
Редактировать:Вот некоторый код, который может помочь объяснить мою проблему:
$("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;
}
} );
ПРАВКА 2:Вот новый код.Похоже, мне все еще приходится использовать eval , потому что вызов form.submit() не запускает существующие 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;
}
} );
Предложения о том, возможно, как сделать это лучше?
Решение
Я заменяю кнопку отправки на ссылку привязки .Поскольку вызов form.submit() не активируется onsubmit's, я нахожу его и оцениваю() его сам.Но я хотел бы проверить, существует ли функция перед просто eval(), что там есть.– 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>
Редактировать :отсутствует параметр f в функции testOnsubmitAndSubmit
Вышесказанное должно работать независимо от того, назначаете ли вы onsubmit
HTML атрибут или назначьте его в JavaScript:
document.forms['theForm'].onsubmit = onsubmitHandler;
Другие советы
Попробуй
if (this.onsubmit instanceof Function) {
// do stuff;
}
Вы могли бы просто использовать typeof
оператор вместе с троичным оператором для краткости:
onsubmit="return typeof valid =='function' ? valid() : true;"
Если это функция, мы вызываем ее и возвращаем возвращаемое значение, в противном случае просто возвращаем true
Редактировать:
Я не совсем уверен, что вы на самом деле хотите сделать, но я попытаюсь объяснить, что может произойти.
Когда вы заявляете о своем onsubmit
код внутри вашего html превращается в функцию и, таким образом, его можно вызвать из "мира" JavaScript.Это означает, что эти два метода эквивалентны:
HTML: <form onsubmit="return valid();" />
JavaScript: myForm.onsubmit = function() { return valid(); };
Эти две функции будут обеими, и обе будут вызываемыми.Вы можете протестировать любой из них, используя typeof
оператор, который должен выдать тот же результат: "function"
.
Теперь, если вы присвоите строку свойству "onsubmit" с помощью JavaScript, она останется строкой, следовательно, не может быть вызвана.Обратите внимание, что если вы примените typeof
оператор против этого, вы получите "string"
вместо того , чтобы "function"
.
Я надеюсь, что это могло бы прояснить некоторые вещи.С другой стороны, если вы хотите знать, является ли такое свойство (или любой соответствующий идентификатор) функцией и может ли оно вызываться, то typeof
оператор должен сделать свое дело.Хотя я не уверен, что это работает должным образом в нескольких кадрах.
Ваше здоровье
Какой браузер вы используете?
alert(typeof document.getElementById('myform').onsubmit);
Это дает мне "function
" в IE7 и FireFox.
Убедитесь, что вы вызываете typeof для фактической функции, а не для строкового литерала:
function x() {
console.log("hi");
}
typeof "x"; // returns "string"
typeof x; // returns "function"
используя в качестве примера переменную на основе строк и используя instanceof Function
Вы регистрируете функцию .. присваиваете переменную ... проверяете, соответствует ли переменная имени function...do предварительная обработка...назначьте функцию новой переменной ... затем вызовите функцию.
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();
}
Вы можете попробовать изменить эта техника в соответствии с вашими потребностями:
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 всегда будет функцией, когда определен как атрибут HTML элемента form.Это своего рода анонимная функция, прикрепленная к HTML-элементу, который имеет это указатель привязан к этому элементу ФОРМЫ, а также имеет параметр с именем event
который будет содержать данные о событии отправки.
При таких обстоятельствах я не понимаю, как вы получили строку в результате операции typeof .Вам следует предоставить больше деталей, лучше какой-нибудь код.
Редактировать (в ответ на вашу вторую правку):
Я полагаю, что обработчик, прикрепленный к атрибуту HTML, будет выполняться независимо от приведенного выше кода.Более того, вы могли бы попытаться как-то остановить это, но, похоже, что FF 3, IE 8, Chrome 2 и Opera 9 в первую очередь выполняют обработчик атрибута HTML, а затем прикрепленный (хотя я тестировал не с jQuery, а с addEventListener и attachEvent).Итак...чего именно вы пытаетесь достичь?
Кстати, ваш код не работает, потому что ваше регулярное выражение извлечет строку "valid();", которая определенно не является функцией.
Если это строка, вы могли бы предположить / надеяться, что она всегда имеет вид
return SomeFunction(arguments);
проанализируйте имя функции, а затем посмотрите, определена ли эта функция с помощью
if (window[functionName]) {
// do stuff
}
Что ж, "return valid();"
является строка, так что это правильно.
Если вы хотите проверить, есть ли у него вместо этого подключенная функция, вы могли бы попробовать это:
formId.onsubmit = function (){ /* */ }
if(typeof formId.onsubmit == "function"){
alert("it's a function!");
}
Я думаю, что источником путаницы является различие между атрибут и соответствующий свойство.
Ты используешь:
$("a.button").parents("form").attr("onsubmit")
Вы непосредственно читаете onsubmit
атрибутзначение (которое должен быть строкой).Вместо этого вы должны получить доступ к onsubmit
свойство узла:
$("a.button").parents("form").prop("onsubmit")
Вот краткий тест:
<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>
Это приводит к:
form1 onsubmit property: (function) function onsubmit(event) { return valid(); } form1 onsubmit attribute: (string) return valid()
if ( window.onsubmit ) {
//
} else {
alert("Function does not exist.");
}
Вы всегда можете использовать одну из функций typeOf в блогах JavaScript, таких как Криса Уэста.Используя определение , подобное следующему , для typeOf()
функция будет работать:
function typeOf(o){return {}.toString.call(o).slice(8,-1)}
Эта функция (которая объявлена в глобальном пространстве имен, может использоваться следующим образом:
alert("onsubmit is a " + typeOf(elem.onsubmit));
Если это функция, то будет возвращено "Function".Если это строка, будет возвращено "String".Показаны другие возможные значения здесь.
// 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
}
}
Простая проверка, подобная этой, позволит вам узнать, существует ли она / определена:
if (this.onsubmit)
{
// do stuff;
}