简体   繁体   English

如何使用Mootools链接单击事件,以便它们按顺序执行?

[英]How can I chain click events with Mootools so that they execute in order?

I have a series of buttons that fire the list function when they are clicked. 我有一系列按钮,在单击它们时会触发列表功能。 The list function itself contains an AJAX request and a bunch of other stuff before and after which loads in a separate section of the page. 列表函数本身包含一个AJAX请求和一堆其他东西,在此之前和之后,它们会加载到页面的单独部分中。

var list = function() { }
$$('.buttons').addEvent('click', list);

Everything works fine if I wait for list to complete before clicking on another button. 如果我在单击另一个按钮之前等待列表完成,则一切正常。 However, if I click on two buttons quickly, the page will start to return incorrect responses. 但是,如果我快速单击两个按钮,页面将开始返回错误的响应。 In fact, it appears as though the responses get out of sync by 1. So if I quickly click on button A then button B, it will load response A. Then if I click (much later) on button C, it will load response B. 实际上,似乎响应不同步了1。因此,如果我快速单击按钮A,然后单击按钮B,它将加载响应A。然后,如果我(稍后)单击按钮C,它将加载响应B.

There are two ways I can see to solve this: 我可以通过两种方法解决此问题:

1) Remove the click event from other buttons when any button is clicked and then restore it when list is complete. 1)单击任何按钮时,请从其他按钮中删除click事件,然后在列表完成后将其恢复。 Unfortunately, I have tried placing $$('.buttons').removeEvents() at the top of the list function and then $$('.buttons').addEvent('click', list); 不幸的是,我尝试将$$('.buttons').removeEvents()放在列表函数的顶部,然后将$$('.buttons').addEvent('click', list); at the bottom but this has no effect on the problem. 在底部,但这对问题没有影响。

2) Chain the click events so that list is only ever executed when the preceding list has finished. 2)链接click事件,以便仅在前面的列表完成后才执行列表。

So can anybody tell me how to get the second solution working? 那么有人可以告诉我如何使第二个解决方案起作用吗? Additionally, if anybody knows why the first solution doesn't work and why I get the weird delayed AJAX response behaviour, that would be great! 此外,如果有人知道为什么第一个解决方案不起作用以及为什么我得到了奇怪的延迟的AJAX响应行为,那就太好了!

The first solution doesn't work because events on an element are fired in order, but are executed asynchronously. 第一个解决方案不起作用,因为元素上的事件是按顺序触发的,但是是异步执行的。 You'll need to setup a queue of callbacks that you can process when the event is triggered. 您需要设置触发事件时可以处理的回调队列。

Here's the basic idea: 这是基本思想:

addQueuedEvent = function(node, event, callback) {
    if ( typeof callback != "function" ) {
        throw "Callback must be a function";
    }

    event = event.toLowerCase();
    var eventQueue = "_" + event;
    if ( !node.hasOwnProperty(eventQueue) ) {
        node[eventQueue] = [];
    }

    node[eventQueue].push(callback)
};

processEventQueue = function(node, event) {
    var eventQueue = "_" + event;
    if ( node.hasOwnProperty(eventQueue) ) {
        for ( var i=0, l=node[eventQueue].length; i<l; ++i ) {
            node[eventQueue][i]();
        }
    }
};

And the usage: 以及用法:

var someElement = $("#some-element");
addQueuedEvent(someElement, "click", callback1);
addQueuedEvent(someElement, "click", callback2);
addQueuedEvent(someElement, "click", callback3);

someElement.addEvent("click", function() {
    processEventQueue(this, "click");
});

The syntax checks out, but this is not tested. 语法签出,但未经过测试。 Hope that helps. 希望能有所帮助。

i would personally just set a global / scoped variable in your class or whatever - something like 'isClicked = false'. 我个人将只在您的类中设置一个全局/范围内的变量或诸如此类的变量,例如“ isClicked = false”。

then simply check at the the the click event function, something like: 然后只需检查一下click事件功能即可,例如:

var isClicked = false, click = function() {
    if (isClicked)
        return false;

    isClicked = true;
    // ... do stuff, chained or otherwise...

    // when done, make click function work again:
    isClicked = false; // you can do this onComplete on the fx class also if you use it
};

i would go against chaining events with effects - if you have an animation going on, simply wait for it to end--otherwise it can get messy for any trigger happy user that thinks double clicking is the way to go. 我会反对用效果链接事件-如果您正在播放动画,只需等待它结束-否则对于认为双击是可行方式的任何触发快乐用户,它都会变得混乱。 an alternative is to stop / cancel any effects that are taking place on a new click. 另一种方法是停止/取消新点击所产生的任何效果。 for instance, you can stop any tweens etc through FX by something like: 例如,您可以通过FX停止任何补间等,例如:

if (isClicked === true) fxinstance.cancel(); 

http://mootools.net/docs/core/Fx/Fx http://mootools.net/docs/core/Fx/Fx

the other thing you can do is look at the mootools .chain class 您可以做的另一件事是查看mootools .chain类

http://mootools.net/docs/core/Class/Class.Extras#Chain http://mootools.net/docs/core/Class/Class.Extras#Chain

and also, on any fx instances, you can pass on link: "chain" and simply queue them up. 而且,在任何fx实例上,您都可以传递链接:“链”,并简单地将它们排队。

good luck 祝好运

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM