javascript - 减少重复点击事件

时间:2012-08-13 15:42:50

标签: javascript

我刚刚进入我的javascript(模式,命名空间,对象等),并且我正在尝试在我的最新项目中实践其中一些。

我有一个简单的表单,我想根据正在检查的复选框显示/隐藏某些内容。 HTML无法改变(长篇故事)所以我只关注手头的javascript问题,也就是说,当有多个ID时,如何才能很好地减少重复性?

脚本(我确定可以压缩)如下:

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);

2 个答案:

答案 0 :(得分: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 委托人功能来处理所有事件,你可以,但是你必须switch...case所有e.type,当然这通常是最终成为一个无用的,不可维护的monter-function。但只是你知道: 是可能的。

需要关闭吗?当然,没问题:

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);

谷歌更多的事件授权示例,你不会后悔......这是JavaScript的一个特点,它们被严重低估,并不像它们应该的那样众所周知。我希望我能给你一个关闭-delegator组合的更好的例子,因为那是一个非常强大的组合。以移动设备为例:没有点击事件,只有touchstart和touchend事件。因此,您将touchstart处理程序设置为绑定touchend侦听器,并通过闭包将超时ID添加到touchend事件的处理程序中。如果过了一段时间,用户可能没有点击该元素,而是使用他/她的手机的其他触摸功能,所以你可以分离听众。

我不擅长解释这个问题,但是看看自定义tab事件如何运作的一些例子,它通常归结为类似于我运球的东西,现在我要睡觉了......祝你好运

答案 1 :(得分: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
    };
}());

如果您想多次执行此操作,修改此项以接受复选框和元素数组作为参数样式将是微不足道的。