1

私は自分の JavaScript (パターン、名前空間、オブジェクトなど) を始めたばかりで、最新のプロジェクトでこれらのいくつかを実践しようとしています。

シンプルなフォームがあり、チェックボックスがオンになっていることに基づいて何かを表示/非表示にしようとしています。HTML を変更することはできません (長い話) ので、当面の JavaScript の問題にのみ焦点を当てています。

スクリプト(これは確かに要約できる)は以下のとおりです。

var prereg = {

    hideItems: (function() {
        document.getElementById('companyName-element').style.display = 'none';
        document.getElementById('companyName-label').style.display = 'none';
    })(),

    showItems: function() {
        var checkbox = document.getElementById('businessCustomer'); 
        if(checkbox.checked) {
            document.getElementById('companyName-element').style.display = 'block';
            document.getElementById('companyName-label').style.display = 'block';
        } else {
            document.getElementById('companyName-element').style.display = 'none';
            document.getElementById('companyName-label').style.display = 'none';
        }
    },

    addEvent: function (el, ev, fn) {
         if (el.addEventListener) {
             el.addEventListener(ev, fn, false);
         } else if (el.attachEvent) {
             el.attachEvent('on' + ev, fn);
         } else {
             el['on' + ev] = fn;
         }
     }

}

prereg.addEvent(document.getElementById('businessCustomer-label'), 'click', prereg.showItems);
prereg.addEvent(document.getElementById('businessCustomer-element'), 'click', prereg.showItems);
4

2 に答える 2

1

あなたはイベント委任を探していると思います。これは、同じタイプのすべてのイベントに対して単一のハンドラーを使用するという派手な方法です。まあ、異なるタイプでもオプションです。しかし、ほんの一例です:

html が次のようになっているとします。

<form id="formId"><input type="checkbox" id="foo"/>
    <input type="checkbox" id="bar"/>

など(気にすることはできません)。JS は、1 つのイベント リスナーとハンドラーですべてのクリック イベントを処理できます。

var form = document.getElementById('formId');
if (form.addEventListener)
{
    form.addEventListener('click',clickDelegator,false);
}
else
{
    form.attachEvent('onclick',clickDelegator);
}
function clickDelegator(e)
{
    e = e || window.event;
    var target = e.target || e.srcElement;//target holds reference to clicked element
    if (target.tagName.toLowerCase() !== 'input')
    {
        //not interested in this, just let the event pass
        return e;// or return true; or return;... doesn't matter
    }
    switch(target.type.toLowerCase())//target is an input field, we've established that
    {
        case 'checkbox':
            //code for checkboxes;
            //target is a checkbox, use target.checked, target.id, as normal
        break;
        case 'button':
            //deal with buttons here
        break;
        //etc...
    }
}

1 つの delegator-functionですべてのイベントを処理したい場合は可能ですが、もちろん、switch...caseすべてe.typeの を処理する必要があります。しかし、あなたが知っているように、それ可能です.

閉鎖が必要ですか?もちろん問題ありません:

form.addEventListener('click',(function(someVar)
{
    return function(e)
    {
        e = e || window.event;
        clickDelegator.apply(this,[e,someVar]);
        //pass as argument, the clickDelegator was declared outside closure scope
        //and doesn't have access to someVar, but this way, it has the closure var
        //as an argument
    }
})(theClosureVar),false);

イベント デリゲートの例をさらに Google で検索してみてください。後悔することはありません。これは、過小評価され、あまり知られていない JavaScript の機能の 1 つです。クロージャーとデリゲーターの組み合わせのより良い例を紹介できればと思います。これは非常に強力なものだからです。モバイル デバイスを例にとると、クリック イベントはなく、touchstart と touchend イベントのみです。したがって、touchend リスナーをバインドするように touchstart ハンドラーを設定し、クロージャーを介して touchend のイベントのハンドラーにタイムアウト ID を追加します。しばらく時間が経過した場合、ユーザーはおそらく要素をタップしていませんが、電話の他のタッチ機能を使用しているため、リスナーを切り離すことができます。

私はこれを説明するのが得意ではありませんが、カスタムtabイベントがどのように機能するかの例をいくつか見てください。通常、ここでのドリブルに似たものになります。

于 2012-08-13T15:54:24.803 に答える
0

コードをあまり再構築することなく、操作したいオブジェクトを配列にキャッシュし、それらをループで処理したいだけです。

var prereg = (function () {

    // add your style elements to this array. We only call getElementId once
    // and not on each function call.
    var styleObjects = [ 
            document.getElementById('companyName-element'),
            document.getElementById('companyName-label')
        ],

        checkbox = document.getElementById('businessCustomer'),

        i;

    // Function applies display style to all elements in styleObjects array
    function applyStyle(display) {
        var i;
        for (i = 0; i < styleObjects.length; i += 1) {
            styleObjects[i].style.display = display;
        }
    }

    function hideItems() {
        applyStyle('none');
    }

    function showItems() {            
        if(checkbox.checked) {
            applyStyle('block');
        } else {
            applyStyle('none');
        }
    }

    function addEvent(el, ev, fn) {
        if (el.addEventListener) {
         el.addEventListener(ev, fn, false);
        } else if (el.attachEvent) {
         el.attachEvent('on' + ev, fn);
        } else {
         el['on' + ev] = fn;
        }
    }    

    // Attach event handler to all objects in styleObjects array
    for (i = 0; i < styleObjects.length; i += 1) {
        addEvent(styleObjects[i], 'click', showItems);
    }

    return {
        hideItems: hideItems,
        showItems: showItems,
        addEvent: addEvent
    };
}());

これを複数回実行したい場合は、チェックボックスとスタイルを設定する要素の配列を引数として受け入れるようにこれを変更するのは簡単です。

于 2012-08-13T16:13:00.550 に答える