在上一篇《javascript设计模式实践之迭代器--具有百叶窗切换图片效果的JQuery插件(一)》里,通过采用迭代器模式完成了各初始化函数的定义和调用。

接下来就要完成各个切换效果的编写。

先思考一下一个切换效果需要完成的操作

1.准备阶段,将各个strip归位到动画效果开始的位置。

2.动画效果处理。

3.执行。

3.完成。

所有的切换效果都具备上述3步操作。

既然这样就好抽象了。

可以对上述的操作进行单独定义,然后通过模板方法模式对各个操作进行调用。

所谓的模板方法模式,其实就是有这么一个方法完成一个业务流程的处理,在这个业务流程中的某些个细节则交个子对象去处理。就好比组装汽车的流水线就是一个模板,它规定了组装的流程,但是工人是跳着装,还是走着装,还是拿个设备辅助着装那就是安装者的事儿了。

按照模板方法模式编写一个基本效果对象。

    var baseEffect = {
prepare: function (context) {
throw new Error('请重写prepare方法');
},
transform: function (context) {
throw new Error('请重写transform方法');
},
execute: function (context) {
this.prepare(context);
return this.transform(context);
}
};

prepare函数:准备阶段操作。

transform函数:动画效果处理。

这两个方法其实就是各个切换效果根据自身的效果特性需要完成的细节。

execute函数就是执行操作,也是模板方法,在其中完成了对准备阶段和动画处理的流程调用,当然是先准备后进行动画效果处理流程。

按照约定,transform方法必须返回一个jquery的promise对象用来控制动画完成向外部的通知。

关于promise的使用可参考《jquery的promise实践--连续加载图片》。

基本效果对象完成后,接下编写各个实际的效果对象,并从基本效果继承,完成准备操作和动画处理的编写。

先编写从下往上移动各窗帘条strip的效果

    var downToUpEffect = (function (baseEffect) {
var effect = jquery.extend({}, baseEffect);
var imgSrc; effect.prepare = function (context) {
imgSrc = context.nextImgSrc();
for (var i = 0, $strip; $strip = context.$strips[i]; i++) {
$strip.css('background-image', 'url(' + imgSrc + ')');
$strip.css('top', context.stripHeight + 'px');
}
}; effect.transform = function (context) {
var dfd = jquery.Deferred();
for (var i = 0, $strip; $strip = context.$strips[i]; i++) {
if (i == context.$strips.length - 1) {
$strip.animate({top: '0px'}, context.baseDelay + i * context.delayIncrement, function () {
context.$container.css('background-image', 'url(' + imgSrc + ')');
dfd.resolve();
});
} else {
$strip.animate({top: '0px'}, context.baseDelay + i * context.delayIncrement);
}
} return dfd.promise();
}; return effect;
})(baseEffect);

可以看到,一上来,用了jquery.extend函数完成从基本效果对象的继承,书上基本都是在用构造器和原型继承的方式实现继承,但是本质上,在javascript的世界里函数是一等公民,对象实际上就是键值对的集合,没必要生搬硬套OOP的一套东西,这里用了jquery的继承方法,实际上就是将一个对象的方法复制过来生成另一个对象。

downToUpEffect对象只需关心在准备阶段,将所有的窗帘条strip的top都设到容器的下边沿处,在动画处理阶段通过jquery.animate动画方法对各个窗帘条strip的top执行从容器的下沿到上沿的动画。

每个strip的动画都会基于一个简单的计算得出有不同的延迟,这样在视觉上会产生strip是阶梯式的往上移动。

transform函数内通过jquery.deffered对象的resolve方法完成最后一个动画执行完成的通知。并且transform方法将promise返回使得上层可以对动画的完成进行吃处理。

再比如从上往下的效果对象编写

    var upToDownEffect = (function (baseEffect) {
var effect = jquery.extend({}, baseEffect);
var imgSrc; effect.prepare = function (context) {
imgSrc = context.nextImgSrc();
for (var i = 0, $strip; $strip = context.$strips[i]; i++) {
$strip.css('background-image', 'url(' + imgSrc + ')');
$strip.css('top', '-' + context.stripHeight + 'px');
}
}; effect.transform = function (context) {
var dfd = jquery.Deferred();
for (var i = 0, $strip; $strip = context.$strips[i]; i++) {
if (i == context.$strips.length - 1) {
$strip.animate({top: '0px'}, context.baseDelay + i * context.delayIncrement, function () {
context.$container.css('background-image', 'url(' + imgSrc + ')');
dfd.resolve();
});
} else {
$strip.animate({top: '0px'}, context.baseDelay + i * context.delayIncrement);
}
} return dfd.promise();
}; return effect;
})(baseEffect);

从上面的代码看下来,他们的结构是一致的,不同的就是准备阶段和动画处理的细节不同。

upToDownEffect的准备阶段负责把所有窗帘条strip的下沿对准容器的上沿,也就是移动容器的外面去。动画处理阶段就是把strip从上面移下来,并通过延迟造成阶梯式往下移动的效果。

其他的效果对象也是在这样的结构下完成属于效果自身的功能编码。

采用模板方法模式可以使得各个具体的效果对象中的编码只关心属于自己的东西,结构较为清晰,关注重点突出自身的业务逻辑,想到新效果只要专注新效果的实现即可。

其他效果对象的编写可参考全部代码。

下一篇继续:《javascript设计模式实践之职责链--具有百叶窗切换图片效果的JQuery插件(三)

代码:

javascript设计模式实践之模板方法--具有百叶窗切换图片效果的JQuery插件(二)的更多相关文章

  1. javascript设计模式实践之迭代器--具有百叶窗切换图片效果的JQuery插件(一)

    类似于幻灯片的切换效果,有时需要在网页中完成一些图片的自动切换效果,比如广告,宣传,产品介绍之类的,那么单纯的切就没意思了,需要在切换的时候通过一些效果使得切换生动些. 比较常用之一的就是窗帘切换了. ...

  2. javascript设计模式实践之职责链--具有百叶窗切换图片效果的JQuery插件(三)

    在上一篇<javascript设计模式实践之模板方法--具有百叶窗切换图片效果的JQuery插件(二)>里,通过采用模板方法模式完成了切换效果对象的构建编写. 接下来就是完成各效果对象的调 ...

  3. jquery插件jquery.LightBox.js之点击放大图片并左右点击切换图片(仿相册插件)

    该插件乃本博客作者所写,目的在于提升作者的js能力,也给一些js菜鸟在使用插件时提供一些便利,老鸟就悠然地飞过吧. 此插件旨在实现目前较为流行的点击放大图片并左右点击切换图片的效果,您可以根据自己的实 ...

  4. javascript---简介的切换图片效果。

    <!--切换图片--> <img src="img/9.gif" alt="" id="img"> <butt ...

  5. javascript设计模式实践之策略模式--输入验证

    策略模式中的策略就是一种算法或者业务规则,将这些策略作为函数进行封装,并向外提供统一的调用执行. 先定义一个简单的输入表单: <!DOCTYPE html> <html> &l ...

  6. javascript设计模式实践之代理模式--图片预加载

    图片的预加载就是在加载大图片前,先显示一个loading.gif,就算在网络比较慢的时候也能让人知道正在加载,总比啥反应都没有强. 下面这段代码就是预加载的一个简单的实现,假设先不处理加载图片时的on ...

  7. javascript 设计模式实践之策略模式--输入验证

    博客地址:http://www.cnblogs.com/kongxianghai/p/4985122.html,写的挺好的推荐下!

  8. javascript - 简单实现一个图片延迟加载的jQuery插件

    最近在看一本书<Third-Party Javascript>很不错,推荐给大家,下载地址各位自己搜索了. 步骤: 1.打开google,鉴于google基本打不开,那么就打开这个网址吧. ...

  9. 用CALayer实现淡入淡出的切换图片效果

    由于直接更改layer的contents显示的隐式动画切换的时候的动画持续时间没办法控制, 切换效果不尽人意,所以这里配合了CABasicAnimation实现淡入淡出的切换效果, 另外还可以使用组合 ...

随机推荐

  1. ES6中的模板字符串和新XSS Payload

    ES6中的模板字符串和新XSS Payload 众所周知,在XSS的实战对抗中,由于防守方经常会采用各种各样严格的过滤手段来过滤输入,所以我们使用的XSS Payload也会根据实际情况作出各种各样的 ...

  2. 剑指Offer面试题:19.包含Min函数的栈

    一.题目:包含Min函数的栈 题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数.在该栈中,调用min.push及pop的时间复杂度都是O(1). 这里我们要实现的就是min ...

  3. MySQL MVCC(多版本并发控制)

    概述 为了提高并发MySQL加入了多版本并发控制,它把旧版本记录保存在了共享表空间(undolog),当事务提交之后将重做日志写入磁盘(前提innodb_flush_log_at_trx_commit ...

  4. CSharpGL(5)解析3DS文件并用CSharpGL渲染

    CSharpGL(5)解析3DS文件并用CSharpGL渲染 我曾经写过一个简单的*.3ds文件的解析器,但是只能解析最基本的顶点.索引信息,且此解析器是仿照别人的C++代码改写的,设计的也不好,不方 ...

  5. ASP.NET MVC 5 - 给数据模型添加校验器

    在本节中将会给Movie模型添加验证逻辑.并且确保这些验证规则在用户创建或编辑电影时被执行. 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY ...

  6. MySQL中的全文索引

    之前曾经发表了一篇关于SQL Server全文索引的文章.现在将MySQL全文索引的配置过程记录一下. Step1:创建Student表 CREATE TABLE `student` ( `id` I ...

  7. 完全移除TFS2013的版本控制

    环境:Vs2103(TFS2013) 目的:去掉别人项目里的TFS控制,因为每次打开时会有提示信息 解决方法: 1.删除隐藏的.$tf文件夹,搜索*.vssscc和*.vspscc这两个后缀的文件,删 ...

  8. Spark DAGSheduler生成Stage过程分析实验

    RDD.Action触发SparkContext.run,这里举最简单的例子rdd.count() /** * Return the number of elements in the RDD. */ ...

  9. Eclipse 常用快捷键 (动画讲解)

    Eclipse有强大的编辑功能, 工欲善其事,必先利其器, 掌握Eclipse快捷键,可以大大提高工作效率.  编辑相关快捷键 注释          Ctrl + / 快速修复    Ctrl + ...

  10. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...