javascript - 将函数添加到数组中,循环执行后再移除

3
我正在尝试创建一个数组,用于保存出现在DOM上的所有待处理错误消息(使用jquery实现),然后循环遍历该数组以查看是否存在任何错误消息需要调用,如果有,则在执行后将其删除。
我的问题是我无法想出如何将函数推入数组并执行。以下是我目前的代码:
var dialogQueue = []

dialogQueue.push(errorCall("test", "test", "test", "test"));

for (var queueNum = 1, 1 < dialogQueue.length, 1++) {
    alert(dialogQueue[1])
}

如果有帮助的话,以下是显示错误消息的代码:

function dialogShow() {
    $(".dialog-con").css("display", "block").css("background", "rgba(0,0,0,.8)")
    $(".body-wrapper").addClass("errorFilter");
    $(".dialog-anim").animate({
        opacity: 1,
        marginTop: "-=20px"
    })
    setTimeout(function () {
        $(".errorFilter").addClass("blur");
    }, 100);

}

function dialogHide() {
    $(".dialog-con").css("background", "rgba(0,0,0,.0")
    $(".body-wrapper").removeClass("blur");
    $(".dialog-anim").animate({
        opacity: 0,
        marginTop: "-=25px"
    }, 300)
    setTimeout(function () {
        $(".dialog-con").css("display", "none");
        $(".body-wrapper").removeClass("errorFilter");

        // Code for removing the function from the array after pushing OK on the dialog

    }, 1000);
}

function errorCall(title, sub, text, code) {
    $(".dialog .title").text(title);
    $(".dialog .subtitle").text(sub);
    $(".dialog .text").html(text);
    $(".dialog .error-code").html(code);
    dialogShow();
}

我会给您展示一个完整的errorCall()函数示例:

代码如下:

function dialogShow() {
    $(".dialog-con").css("display", "block").css("background", "rgba(0,0,0,.8)")
    $(".body-wrapper").addClass("errorFilter");
    $(".dialog-anim").animate({
        opacity: 1,
        marginTop: "-=20px"
    })
    setTimeout(function () {
        $(".errorFilter").addClass("blur");
    }, 100);

}

function dialogHide() {
    $(".dialog-con").css("background", "rgba(0,0,0,.0")
    $(".body-wrapper").removeClass("blur");
    $(".dialog-anim").animate({
        opacity: 0,
        marginTop: "-=25px"
    }, 300)
    setTimeout(function () {
        $(".dialog-con").css("display", "none");
        $(".body-wrapper").removeClass("errorFilter");
    }, 1000);
}

function errorCall(title, sub, text, code) {
    $(".dialog .title").text(title);
    $(".dialog .subtitle").text(sub);
    $(".dialog .text").html(text);
    $(".dialog .error-code").html(code);
    dialogShow();
}

errorCall("Hello stackoverflow!","This is how my error message dialog looks!","Blah blah blah blah","Code code code");
.dialog-con {
    height: 100%;
    display: none;
    position: fixed;
    width: 100%;
    background-color: rgba(0, 0, 0, .0);
    z-index: 50;
    transition: ease 300ms;
}

.dialog-anim {
    width: 100%;
    height: 100%;
    display: none;
    display: flex;
    flex-direction: column;
    justify-content: center;
    opacity: 0;
    margin-top: -20px;
}

.dialog {
    margin: auto;
    padding: 12px 27px;
    background: white;
    border-radius: 3px;
    width: 520px;
    transform: translateY(30px)
}

.dialog .title-con {
    margin-bottom: 25px;
}

.dialog .title {
    font-size: 35px;
    padding-bottom: 7px;
}

.dialog .error-code {
    margin-top: 15px;
    color: rgba(0, 0, 0, .6);
    font-family: "Courier New", Courier, monospace
}

.dialog .subtitle {
    font-size: 17px;
    color: rgba(0, 0, 0, 0.4);
}

.dialog .text {}

.dialog .button-con {
    margin-top: 25px;
}

.dialog button {
    margin: auto;
    float: right;
    color: white;
    border: none;
    padding: 9px 37px;
    background: #10b5ff;
    text-transform: uppercase;
    font-weight: bold;
    border-radius: 3px;
}

.dialog button:hover {
    background: black;
    cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dialog-con">
        <div class="dialog-anim">
            <div class="dialog">
                <div class="title-con">
                    <div class="title">Error Message Title</div>
                    <div class="subtitle"></div>
                </div>
                <div class="text-con">
                    <div class="text">Error Message</div>
                    <div class="error-code"></div>
                </div>
                <div class="button-con" onclick="dialogHide()">
                    <button>Ok</button>
                </div>
            </div>
        </div>
    </div>

(确定按钮位移是由于视口太小造成的,请忽略它。)

因此,我想这样做的原因是,如果某些事情触发了多个错误,它们会被推送到数组中并逐一显示(按下“确定”按钮会显示下一个错误等等)。


可能更合理的做法是让errorCall将其结果添加到一个数组中。这样,无论在何处或如何调用它,它都将始终使用该数组。 - Malk
3个回答

5

您需要创建一个函数包装器来将它们存储在数组中。目前,当您将其推送到数组时,会调用errorCall。尝试使用以下代码:

var dialogQueue = []

dialogQueue.push(
    function () {
        errorCall("test", "test", "test", "test")
    }
);

for (var queueNum = 0, 1 < dialogQueue.length, queueNum++) {
    alert( dialogQueue[queueNum]() );
}

你想在执行后将其删除,可以使用以下方法代替:

您也想要在执行后删除,因此可以像这样做:

while(dialogQueue.length > 0) {
    alert( dialogueQueue[0]() );
    dialogueQueue.shift();
}

以下是一个简化的示例:

var funcArr = [];

funcArr.push( console.log("Cat") );
// This immediately calls console.log, logging "cat".  After console.log is
// evaluated we push its return value `undefined`

// Instead, we wrap the console.log in an anonymous function.  This gives us
// a function which will execute what we desire when it is called.
funcArr.push( function() { console.log("cat"); } );

// there is nothing to invoke now, because we are creating a new function.
// now if we:
console.log( funcArr );
// we get: [function anonymous()]

// So if we say:
funcArr[0];
// this will evaluate to:
function() {
    console.log("cat");
};

// Therefore invoking funcArr[0] calls an anonymous function, which runs
// the function we actually wanted to run.
funArr[0]();

1
我喜欢你的答案比我的更好。 - chiliNUT
@SebastianOlsen 试试我的兄弟 - chiliNUT
哪个示例会触发未定义错误?在控制台中尝试简化的示例,可能是您代码的实现问题。 - ChadF
@ChadF 看看我的修改!它可以工作了,唯一剩下的问题是如何在用户按下“确定”后调用数组中的下一个函数。 - Sebastian Olsen
如果您只想一次记录一个错误,请将代码包装在我的while循环中的函数中,并在ok上调用它。 - ChadF
显示剩余2条评论

1
一个替代ChadF的方法是实例化一个函数,并在需要显示消息时调用其方法。

// Your base function
function error(a, b, c, d) { 
  this.show = function() {
    alert(a + " " + b + " " + c + " " + d);
  };
}

var dialogQueue = [];

// Creating an instance of "error"
dialogQueue.push(new error("test", "test2", "test3", "test4")); 
dialogQueue.push(new error("testing again", "test2", "test3", "test4")); 

alert("Data finished pushing");

for (var i = 0; i < dialogQueue.length; i++) {
    // Calling the "show" method from "error"
    dialogQueue[i].show();
}


0
你可以将参数推入数组,并使用它来执行函数。你可以使用 apply 来调用一个给定的带有一组参数的函数。
像这样:
dialogQueue=[];
//fill the queue with arguments
dialogQueue.push([1,2,3,4]);
dialogQueue.push(["test","test","test","test"]);
dialogQueue.push(["bla","bla","bla","bla"]);

//fire off everything in the queue
var len=dialogQueue.length;
for (i=0;i<len;i++) {
//pop off the args, and use apply to call them
var args=dialogQueue.pop();
errorCall.apply(this, args);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接