在上一篇《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. Code First开发系列实战之使用EF搭建小型博客平台

    返回<8天掌握EF的Code First开发>总目录 本篇目录 理解应用需求 数据库设计 创建实体数据模型 创建实体类 创建关系和导航属性 实现DbContext类 执行数据访问 理解仓储 ...

  2. ABP理论学习之领域服务

    返回总目录 本篇目录 介绍 IDomainService接口和DomainService类 样例 创建一个接口 服务实现 调用应用服务 一些讨论 何不只使用应用服务 如何强制使用领域服务 介绍 领域服 ...

  3. Hadoop学习笔记—8.Combiner与自定义Combiner

    一.Combiner的出现背景 1.1 回顾Map阶段五大步骤 在第四篇博文<初识MapReduce>中,我们认识了MapReduce的八大步凑,其中在Map阶段总共五个步骤,如下图所示: ...

  4. Spring:源码解读Spring IOC原理

    Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...

  5. Entity Framework与ADO.NET批量插入数据性能测试

    Entity Framework是.NET平台下的一种简单易用的ORM框架,它既便于Domain Model和持久层的OO设计,也提高了代码的可维护性.但在使用中发现,有几类业务场景是EF不太擅长的, ...

  6. IEEE754、VAX、IBM浮点型介绍和.NET中互相转换

    [题外话] 最近在做C3D文件的解析,好奇怪的是文件中竟然存储了CPU的类型,原本不以为然,结果后来读取一个文件发现浮点数全部读取错误.查了下发现虽然在上世纪80年代就提出了IEEE754要统一浮点数 ...

  7. SSH实战 · SSH项目开发环境搭建

    一:SSH整合 创建一个新的WEB项目 引入struts2.3.15.3: jar包:                 struts-2.3.15.3\apps\struts2-blank.war\W ...

  8. JSON数据的定义

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. Solr的原理及在项目中的使用实例.

    前面已经讲过 如果安装及配置Solr服务器了, 那么现在我们就来正式在代码中使用Solr.1,这里Solr主要是怎么使用的呢?  当我们在前台页面搜索商品名称关键词时, 我们这时是在Solr库中去查找 ...

  10. Leetcode-2 Add Two Numbers

    #2. Add Two Numbers You are given two linked lists representing two non-negative numbers. The digits ...