【ASP.NET】2度押し防止

下記の内容を外部のjsファイルとしてインクルードする事でボタンの2度押しを防止します。
(document.readyStateで画面が読み込み中かどうか判断しリンクやボタンのクリックを制御)

// windowのload イベントを追加
if (window.addEventListener)    //for W3C DOM
{ 
    window.addEventListener("load", HTMLArea.Initialize, false);
}
else if (window.attachEvent)    //for IE
{
    window.attachEvent("onload", Initialize);
}

// 初期化
function Initialize()
{
    // 全リンクのクリックイベントを submittableObject_Click で取得
    for (var i = 0; i < document.links.length; i ++)
    {
        var item = document.links[i]

        Object.Aspect.around(item, "onclick", checkLoading);
    }

    // 全ボタンのクリックイベントを submittableObject_Click で取得
    for (var i = 0; i < document.forms.length; i ++)
    {
        for (var j = 0; j < document.forms[i].elements.length; j ++)
        {
            var item = document.forms[i].elements[j]
            
            if (item.type == "button" ||
                item.type == "submit" ||
                item.type == "reset")
            {
                Object.Aspect.around(item, "onclick", checkLoading);
            }
        }
    }

    return true;
}

// 2度押し抑止アスペクト
var checkLoading = function(invocation)
{
    if (IsDocumentLoading())
    {
        alert("処理中です・・・"); 
        
        return false;
    }
    
    return invocation.proceed();
}

// 画面描画が終わったかどうか
function IsDocumentLoading()
{
    return (document.readyState != null && 
            document.readyState != "complete" && 
            document.readyState != "interactive");
}

// アスペクト用
Object.Aspect = 
{
    _around: function(target, methodName, aspect)
    {
        var method = target[methodName];
        target[methodName] = function()
        {
            var invocation = 
            {
                "target" : this,
                "method" : method,
                "methodName" : methodName,
                "arguments" : arguments,
                "proceed" : function()
                {
                    if (!method)
                    {
                        return true;
                    }
                    return method.apply(target, this.arguments);
                }
            };
            return aspect.apply(null, [invocation]);
        };
    },
    around: function(target, methodName, aspect)
    {
        this._around(target, methodName, aspect);
    }
}

下記のサイトを参考にさせていただきました。(ほぼそのままです)
http://d.hatena.ne.jp/itaosan/20061225/1167025092
変更内容は下記の通りです。

  • form要素が0個または2個以上の場合にエラーが出ない様にした
  • インクルード先のbody要素にonloadイベントが設定されていた場合に上書きしない様にした(追加する)
  • その他自分好みに