質問

フォームの値が正しいかどうかをテストする必要があります 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:新しいコードは次のとおりです。form.submit() を呼び出しても既存の onsubmit が起動されないため、まだ eval を使用する必要があるようです。

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()を自分で実行します。でも、やりたいのは 関数が前に存在するかどうかを確認します そこにあるものを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>

編集 :関数 testOnsubmitAndSubmit にパラメータ f がありません

上記は、を割り当てるかどうかに関係なく機能するはずです。 onsubmit HTML 属性を使用するか、JavaScript で割り当てます。

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

他のヒント

試す

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

単純に使用できます typeof 演算子と略して三項演算子:

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

関数の場合は呼び出してその戻り値を返します。それ以外の場合は単に return します。 true

編集:

あなたが本当に何をしたいのかよくわかりませんが、何が起こっているのか説明してみます。

申告するときは、 onsubmit HTML 内のコードは関数に変換されるため、JavaScript の「ワールド」から呼び出すことができます。つまり、これら 2 つのメソッドは同等です。

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

これら 2 つは両方とも関数であり、両方とも呼び出し可能です。を使用してそれらのいずれかをテストできます typeof 同じ結果を返す演算子: "function".

ここで、JavaScript を介して「onsubmit」プロパティに文字列を割り当てた場合、それは文字列のままになるため、呼び出すことはできません。を適用すると、 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 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 要素に関連付けられたある種の匿名関数であり、 これ その FORM 要素にバインドされており、という名前のパラメータも持つポインタ event これには送信イベントに関するデータが含まれます。

このような状況では、typeof 操作の結果として文字列をどのように取得したのか理解できません。より詳細なコードを提供する必要があります。

編集 (2 回目の編集に対する応答として):

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 関数の 1 つは、次のような 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;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top