我应该如何编写一个可能只运行一次或多次的方法,但是我希望在调用该方法时只运行一次逻辑?

时间:2011-07-05 19:39:51

标签: javascript jquery javascript-events

奇怪的问题,我知道。请允许我解释一下。

我有一个javascript / jquery函数,用于处理复选框更改。这里有一些伪代码(fyi,我实际上并没有尝试获取红行数 - 这只是PSEUDO代码):

$("input[type='checkbox'].option").change(function() {
    if ($(this).is(":checked")) {
        $("div.special").removeClass("red");
    }
    else {
        $("div.special").addClass("red");
    }

    // I only want to call this after all the checkbox event have been handled
    updateNumRedDivs();
});

function updateNumRedDivs() {
    alert($("div.special.red").length+"red DIVs found");
}

现在,可以在单击单个复选框时(显然)或者在单独的“全选”复选框被调用时调用复选框处理程序:

$(".myForm .selectAllCheckbox").change(function() {
    var $checkboxes = $(this).closest("form").find("input[type='checkbox'].option");

    if ($(this).attr("checked")) {
        $checkboxes.each(function() {
            if (!$(this).attr("checked"))
                $(this).attr("checked", "checked").change();
        });
    }

    updateNumRedDivs();
});

我希望这是有道理的。感谢。

5 个答案:

答案 0 :(得分:3)

将单个复选框更改处理程序的逻辑分成两个函数。然后,对于select all,只需调用所需的函数,而不是调用change()

function changeHandler(chkBox) {
    if (chkBox.is(":checked")) {
        $("div.special").removeClass("red");
    }
    else {
        $("div.special").addClass("red");
    }
}
$("input[type='checkbox'].option").change(function() {
    changeHandler($(this));
    updateNumRedDivs();
});

function updateNumRedDivs() {
    alert($("div.special.red").length+"red DIVs found");
}

$(".myForm .selectAllCheckbox").change(function() {
    var $checkboxes = $(this).closest("form").find("input[type='checkbox'].option");

    if ($(this).attr("checked")) {
        $checkboxes.each(function() {
            if (!$(this).attr("checked"))
                changeHandler($(this).attr("checked", "checked"));
        });
    }

    updateNumRedDivs();
});

答案 1 :(得分:1)

如果你只想让它运行一次,只需破坏函数底部的引用。

var updateNumRedDivs = function() {
    // ... actual handling here
    updateNumRedDivs = function(){};
}

多次,我会使用一个闭包,就像这样

// This will run five times, before destroying
var updateNumRedDivs = function(amount) {
    var calls = 0;
    return function () {
        // handle event
        if (++calls === amount) updateNumRedDivs = function() {};
    };
}(5) 

修改
可能误解了你使用一次或多次运行的函数的意图。您是在寻找一个仅从每个来源运行一次的功能,还是一个不受总呼叫限制的功能,而是来自单个来源的 n 呼叫?

答案 2 :(得分:0)

这是我提出的解决方案 - 不是很漂亮,但它完成了工作:

$(".myForm input[type='checkbox']").change(function() {
    if ($(this).hasClass("selectAllCheckbox") {
        var $checkboxes = $(this).closest("form").find("input[type='checkbox'].option");

        if ($(this).attr("checked")) {
            $checkboxes.each(function() {
                if (!$(this).attr("checked"))
                    $(this).attr("checked", "checked").change();
            });
        }
    }
    else {
        if ($(this).is(":checked")) {
            $("div.special").removeClass("red");
        }
        else {
            $("div.special").addClass("red");
        }
    }

    updateNumRedDivs();
});

function updateNumRedDivs() {
    alert($("div.special.red").length+"red DIVs found");
}

基本上,我合并为一个更改处理程序,并使其递归。

答案 3 :(得分:0)

  

太多的代码   好吧,当您选择Select ALL CheckBox

时,您不希望单个复选框的Change事件被触发
var SelectALLFired=false;
  

在SelectALLCheckBox的处理程序中为SelectALLFired = true设置值;并在完成后将值更改回SelectALLFired = false;

在执行任何操作之前,单个CheckBox更改函数上的

写入If语句

if(!SelectALLFired)
{
Your Code
}

$(".myForm .selectAllCheckbox").change(function() {
SelectALLFired=true;
var $checkboxes = $(this).closest("form").find("input[type='checkbox'].option");

if ($(this).attr("checked")) {
    $checkboxes.each(function() {
        if (!$(this).attr("checked"))
            $(this).attr("checked", "checked").change();
    });
}
    SelectALLFired = false;

updateNumRedDivs();

})

$("input[type='checkbox'].option").change(function() {
if(!SelectALLFired)
{
   if ($(this).is(":checked")) {
       $("div.special").removeClass("red");
    }
    else {
       $("div.special").addClass("red");
    }
}
// I only want to call this after all the checkbox event have been handled
updateNumRedDivs();
});

答案 4 :(得分:0)

我会通过trigger

将更多参数传递给更改事件

注意:愚蠢地说明这个想法。

http://jsfiddle.net/bnWVd/

function doit(){
    alert("done");   
}

$("input").click(function(event,extraParams){
    // do stuff
    if(extraParams && extraParams.noAlert){
       // do nothing or maybe something else
    }else{
        doit(); 
    }
});

$("button").click(function(){
    $("input").each(function(){
        $(this).trigger("click",{noAlert: true});
    }); 

    doit();
});

基本上,当在循环中调用时,我将参数传递给事件,让它知道不运行额外函数。然后当循环完成后我直接调用它。如果没有传递参数,则会调用它。