在上一篇《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. 【腾讯优测干货分享】Android 相机预览方向及其适配探索

    本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/583ba1df25d735cd2797004d 由于Android系统的开放策略 ...

  2. java中文乱码解决之道(八)-----解决URL中文乱码问题

    我们主要通过两种形式提交向服务器发送请求:URL.表单.而表单形式一般都不会出现乱码问题,乱码问题主要是在URL上面.通过前面几篇博客的介绍我们知道URL向服务器发送请求编码过程实在是实在太混乱了.不 ...

  3. Objective-C 工厂模式(上) -- 简单工厂模式

    简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂 ...

  4. 逻辑回归(LR)总结复习

    摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 最基本的LR分类器适合于对两分类(类0,类1)目标进行分类:这个模型以样 ...

  5. Android开发学习之路-下拉刷新怎么做?

    因为最近的开发涉及到了网络读取数据,那么自然少不了的就是下拉刷新的功能,搜索的方法一般是自己去自定义ListView或者RecyclerView来重写OnTouch或者OnScroll方法来实现手势的 ...

  6. React 生命周期

    前言 学习React,生命周期很重要,我们了解完生命周期的各个组件,对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1.g ...

  7. iOS-----dSYM 文件分析工具

    来到新公司后,前段时间就一直在忙,前不久 项目 终于成功发布上线了,最近就在给项目做优化,并排除一些线上软件的 bug,因为项目中使用了友盟统计,所以在友盟给出的错误信息统计中能比较方便的找出客户端异 ...

  8. 有关binlog的那点事(三)(mysql5.7.13)

    这次我们要探索更精细的binlog内容,上次讨论的Query_event和Rows_event肯定有让你疑惑不解的问题.Query_event中的status-vars环境变量有哪些,Rows_eve ...

  9. 谈谈php里的DAO Model AR

    这次要谈的3个关键字:DAO.Model.AR,是我们在做web应用时常见的几个概念,也被称作设计模式(design pattern),先简单看看它们的全拼和中文: DAO:Data Access O ...

  10. EF-DbUpdateException--实体类和数据库列不对应的解决方案

    错误信息 1.VS实体类里面的字段 2数据库里面的字段 猜测是因为字段数不匹配导致的 3删除多余字段 5.结果 错误信息贴上: -------------------------Log_Header- ...