使用 Mootools 链接 AddClass/RemoveClass 事件

发布于 2024-11-27 02:21:25 字数 621 浏览 1 评论 0原文

我目前正在制作一个 CSS 动画,实现这一目标的一部分涉及以特定的时间间隔更改主体的类名。

作为 mootools(和一般的 js)的新手,我想到实现这一点的最好方法是简单地以延迟的时间间隔向主体添加/删除类,如下所示:

(function() {$(document.body).addClass('load');}).delay(20);
(function() {$(document.body).addClass('load-two');}).delay(2000);
(function() {$(document.body).addClass('load-three');}).delay(2700);
(function() {$(document.body).addClass('load-four');}).delay(4500);

然而,我对这个主题了解得越多,我更确信这是实现我想要的目标的低效方法。

上面的代码适用于我测试过的所有浏览器,但是使用链类来实现我想要的效果会更好吗?我已经查看了有关设置链的 Mootools 文档,但无论出于何种原因,我都在努力让演示正常运行。

所以我要问的关键是,是否有更好的方法来编写上面发布的代码,以及使用不同方法的好处是什么?

谢谢。

I'm currently putting together a css animation, and part of achieving this involves changing the class name of the body at specific intervals.

Being quite new to mootools (and js in general) the best way I've thought of achieving this has been to simply add/remove classes to the body at delayed intervals, like so:

(function() {$(document.body).addClass('load');}).delay(20);
(function() {$(document.body).addClass('load-two');}).delay(2000);
(function() {$(document.body).addClass('load-three');}).delay(2700);
(function() {$(document.body).addClass('load-four');}).delay(4500);

However the more I read up on the subject, the more I'm convinced that this is an inefficient way of achieving what I want to.

The above code works in all the browsers I've tested it in, but would I be better using a chain class to achieve what I want? I have looked over the Mootools docs on setting up a chain, but for whatever reason, I'm struggling to get the demo working.

So the crux of what I'm asking, is if there's a better way of writing the code posted above, and what are the benefits of using a different method?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝礼 2024-12-04 02:21:25

在 mootools 中设置链非常简单。然而,使用 Chain 类作为 mixin 可能会涉及更多一些。

通常,它适合链接基于 Fx 的类和方法,而不是同步的类和方法。假设您有一个正在播放 link: chain 的补间效果,您可以 .chain(function() {}) 实例在之后执行其他操作。

callChain 示例 作为一个独立的例子是很好和简单的,但它在时间控制方面提供的很少。

然后是线性时间线方法。在您的情况下,您的第一个回调在 20 毫秒后运行,1980 毫秒后运行,第二个、第三个回调在第二个回调后 1680 毫秒运行,依此类推。如果您将事情串联起来,以便每个连续的步骤都调用下一个步骤,那么您需要考虑到这一点,并实际上传递两个操作之间等待的时间。

另一种方法是推迟它们,就像你从一开始就做的那样。

我在这里尝试简化前者: http://jsfiddle.net/dimitar/mpzzq/

(function(){
    Chain.implement({
        slowChain: function(duration){
            // console.log(duration);
            this.callChain.delay(duration === null ? 500 : duration, this);
        }
    });

    var db = $(document.body);
    var fixBody = function(cn, delay) {
        console.log(arguments);
        db.addClass(cn);
        console.log(cn, delay);
        if (this.$chain.length) {
            this.slowChain(delay || 0);
        }
    };

    var myChain = new Chain(),
        funcs = [{
            fn: fixBody,
            args: ["load"],
            delay: 1980
        }, {
            fn: fixBody,
            args: ["load-two"],
            delay: 700
        }, {
            fn: fixBody,
            args: ["load-three"],
            delay: 2000
        }, {
            fn: fixBody,
            args: ["load-four"],
            delay: 0
        }];

    myChain.chain(
        funcs.map(function(el) {
            el.args.push(el.delay);
            return el.fn.bind.apply(el.fn, [myChain].concat(el.args));
        })
    );

    document.getElement("button").addEvents({
        click: function() {
            myChain.slowChain(20);
        }
    });
})();

因此,在我的 funcs 对象数组中,我定义了 func 回调、要传递的参数和延迟。请记住,func 本身将 this 范围设置为链实例,并自行调用链上的下一个,但您可以轻松修改它并使用它。

希望它能给你一些想法。

这里是在 take 2 处,带有一个装饰器函数,该函数在延迟时调用链:

// function decorator.
Function.implement({
    chainDelay: function(delay, bind) {
        // allows you to set a delay for chained funcs and auto call stack (if bind is a chain instance)
        var self = this,                 
            args = (arguments.length > 2) ? Array.slice(arguments, 2) : null;
        return function() {
            setTimeout(function() {
                self.apply(bind, args.concat(Array.from(arguments)));
                if (bind && bind.$chain && bind.$chain.length)
                    bind.callChain.call(bind);
            }, delay);
        }
    },
    justChain: function(bind) {
        // runs a chained func when due and auto calls stack for next (if bind is a chain instance and avail)
        var self = this, args = (arguments.length > 1) ? Array.slice(arguments, 1) : null;
        return function() {
            self.call(bind, args);
            if (bind && bind.$chain && bind.$chain.length)
                bind.callChain.call(bind);
        }
    }
});


var moo = new Chain();

moo.chain(
    // some delayed ones.
    (function(what) {
        console.log(what);
    }).chainDelay(3000, moo, "hi"),
    (function(what, ever) {
        console.log(what, ever);
    }).chainDelay(3000, moo, "there", "coda"),
    (function(what) {
        new Element("div[id=foo][html=" + what +"]").inject(document.body);
    }).chainDelay(1000, moo, "mootools FTW!"),
    // regular ones here for good measure!    
    (function() {
        document.id("foo").setStyle("color", "red")
    }).justChain(moo),
    (function() {
        document.id("foo").setStyle("background-color", "blue")
    })    
);

moo.callChain();

示例: http: //jsfiddle.net/dimitar/Y4KCB/4/

setting up a chain in mootools is quite simple. however, using the Chain class as a mixin can be a little more involved.

typically, it's geared up towards chaining of Fx-based classes and methods and not ones that are synchronous. say you have a tween effect which has link: chain in play, you can .chain(function() {}) the instance to do something else after.

the callChain example as a standalone is fine and easy enough but it offers little in terms of timing controls.

then there's the linear timeline approach. in your case, your first callback runs after 20 ms, 1980 ms after that the second, third runs 1680 ms after the second and so forth. if you chain things so that each successive step calls the next one, you need to take that into account and actually pass on the time to wait between the 2 actions instead.

the other way to do so is to just defer them as you have done from the start.

I had a go at streamlining the former a little here: http://jsfiddle.net/dimitar/mpzzq/

(function(){
    Chain.implement({
        slowChain: function(duration){
            // console.log(duration);
            this.callChain.delay(duration === null ? 500 : duration, this);
        }
    });

    var db = $(document.body);
    var fixBody = function(cn, delay) {
        console.log(arguments);
        db.addClass(cn);
        console.log(cn, delay);
        if (this.$chain.length) {
            this.slowChain(delay || 0);
        }
    };

    var myChain = new Chain(),
        funcs = [{
            fn: fixBody,
            args: ["load"],
            delay: 1980
        }, {
            fn: fixBody,
            args: ["load-two"],
            delay: 700
        }, {
            fn: fixBody,
            args: ["load-three"],
            delay: 2000
        }, {
            fn: fixBody,
            args: ["load-four"],
            delay: 0
        }];

    myChain.chain(
        funcs.map(function(el) {
            el.args.push(el.delay);
            return el.fn.bind.apply(el.fn, [myChain].concat(el.args));
        })
    );

    document.getElement("button").addEvents({
        click: function() {
            myChain.slowChain(20);
        }
    });
})();

so in my funcs array of objects i define the func callback, the arguments to pass on and the delay. keep in mind that the func itself has the this scope set to the chain instance and self calls next one on the chain but you can easily mod this and work with it.

hope it gives you some ideas.

here it is at take 2 with a decorator function that calls the chain on a delay:

// function decorator.
Function.implement({
    chainDelay: function(delay, bind) {
        // allows you to set a delay for chained funcs and auto call stack (if bind is a chain instance)
        var self = this,                 
            args = (arguments.length > 2) ? Array.slice(arguments, 2) : null;
        return function() {
            setTimeout(function() {
                self.apply(bind, args.concat(Array.from(arguments)));
                if (bind && bind.$chain && bind.$chain.length)
                    bind.callChain.call(bind);
            }, delay);
        }
    },
    justChain: function(bind) {
        // runs a chained func when due and auto calls stack for next (if bind is a chain instance and avail)
        var self = this, args = (arguments.length > 1) ? Array.slice(arguments, 1) : null;
        return function() {
            self.call(bind, args);
            if (bind && bind.$chain && bind.$chain.length)
                bind.callChain.call(bind);
        }
    }
});


var moo = new Chain();

moo.chain(
    // some delayed ones.
    (function(what) {
        console.log(what);
    }).chainDelay(3000, moo, "hi"),
    (function(what, ever) {
        console.log(what, ever);
    }).chainDelay(3000, moo, "there", "coda"),
    (function(what) {
        new Element("div[id=foo][html=" + what +"]").inject(document.body);
    }).chainDelay(1000, moo, "mootools FTW!"),
    // regular ones here for good measure!    
    (function() {
        document.id("foo").setStyle("color", "red")
    }).justChain(moo),
    (function() {
        document.id("foo").setStyle("background-color", "blue")
    })    
);

moo.callChain();

example of that: http://jsfiddle.net/dimitar/Y4KCB/4/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文