[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表
2017-09-04 21:07
791 查看
所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如:
1、肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的
2、组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的
把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势
比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡
鸡腿堡+鸡翅+紫薯+可乐可以配置出另外一种套餐。
而在我们的前端领域,经常要接触的就是排版,通过不同的html结构+css样式组合成不用绚丽多彩的网页,我们也可以通过组合模式来完成的,
有人可能要问,为什么要用js来生成,直接写html和css不是很省事吗?是的,但是用组合模式做成不同的套餐(模块),是不是可以非常快的生成出不同的模板呢? 大大提高网页编写的速度?
本文我们来实战一个最基本的列表新闻模块,看看怎么使用组合模式?先看下要做出来的效果:
这个是一个无序列表加一个a标签,非常简单的套餐(模块)
1、首先,我们定义父类,2个属性,3个方法
this.element用来存储当前的元素,this.children用来存储当前元素下面的子元素
init方法:用来初始化元素的标签,属性,样式
add方法:把子节点添加在父节点下面
getElement: 获取当前的节点
2、这里我们需要用到寄生组合继承
3,由于这个新闻模块最外层是ul,所以我们要封装一个生成ul元素的容器类
采用寄生组合继承,把父类的方法重写,父类的属性通过子类的借用构造函数复制到子类实例上,新增了一个show方法,这个方法的目的就是,把最终的模板显示出来
4、生成li元素
5、生成图片与a标签组合的方式
6,生成单纯的a标签和内容这种组合
7,生成带分类的新闻标题
8、大功告成,开始调用生成最后的模块
1、肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的
2、组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的
把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势
比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡
鸡腿堡+鸡翅+紫薯+可乐可以配置出另外一种套餐。
而在我们的前端领域,经常要接触的就是排版,通过不同的html结构+css样式组合成不用绚丽多彩的网页,我们也可以通过组合模式来完成的,
有人可能要问,为什么要用js来生成,直接写html和css不是很省事吗?是的,但是用组合模式做成不同的套餐(模块),是不是可以非常快的生成出不同的模板呢? 大大提高网页编写的速度?
本文我们来实战一个最基本的列表新闻模块,看看怎么使用组合模式?先看下要做出来的效果:
这个是一个无序列表加一个a标签,非常简单的套餐(模块)
1、首先,我们定义父类,2个属性,3个方法
/***************父类开始***********************/ var Layout = function () { this.children = []; this.element = null; } Layout.prototype = { init: function () { throw new Error('该方法需要重写'); }, add: function () { throw new Error('该方法需要重写'); }, getElement: function () { throw new Error('该方法需要重写'); } } /***************父类结束***********************/
this.element用来存储当前的元素,this.children用来存储当前元素下面的子元素
init方法:用来初始化元素的标签,属性,样式
add方法:把子节点添加在父节点下面
getElement: 获取当前的节点
2、这里我们需要用到寄生组合继承
function object(o) { var G = function () { }; G.prototype = o; return new G(); } function inheritPrototype(subObj, superObj) { var proObj = object(superObj.prototype); //复制父类superObj的原型对象 proObj.constructor = subObj; //constructor指向子类构造函数 subObj.prototype = proObj; //再把这个对象给子类的原型对象 }
3,由于这个新闻模块最外层是ul,所以我们要封装一个生成ul元素的容器类
/***************列表容器类开始***********************/ var UlContainer = function (id, parent) { Layout.call(this); this.id = id; this.parent = parent; this.init(); } inheritPrototype(UlContainer, Layout); UlContainer.prototype.init = function () { this.element = document.createElement("ul"); this.element.id = this.id; this.element.className = 'news-list'; } UlContainer.prototype.add = function (child) { this.children.push(child); this.element.appendChild(child.getElement()); return this; } UlContainer.prototype.getElement = function () { return this.element; } UlContainer.prototype.show = function () { this.parent.appendChild(this.element); } /***************列表容器类结束***********************/
采用寄生组合继承,把父类的方法重写,父类的属性通过子类的借用构造函数复制到子类实例上,新增了一个show方法,这个方法的目的就是,把最终的模板显示出来
4、生成li元素
/***************列表项li开始***********************/ var LiTag = function (cName) { Layout.call(this); this.className = cName || ''; this.init(); } inheritPrototype(LiTag, Layout); LiTag.prototype.init = function () { this.element = document.createElement("li"); this.element.className = this.className; } LiTag.prototype.add = function (child) { this.children.push(child); this.element.appendChild(child.getElement()); return this; } LiTag.prototype.getElement = function () { return this.element; } /***************列表项li结束***********************/
5、生成图片与a标签组合的方式
/***************图片新闻开始*******************/ var ImageMsg = function (url, href, cName) { Layout.call(this); this.url = url || ''; this.href = href || '#'; this.className = cName || 'default'; this.init(); } inheritPrototype(ImageMsg, Layout); ImageMsg.prototype.init = function () { this.element = document.createElement("a"); var oImg = new Image(); oImg.src = this.url; this.element.appendChild(oImg); this.element.className = 'img-Layout ' + this.className; this.element.href = this.href; } ImageMsg.prototype.add = function () { } ImageMsg.prototype.getElement = function () { return this.element; } /***************图片新闻结束*******************/
6,生成单纯的a标签和内容这种组合
/***************简单新闻开始*******************/ var ATag = function (text, href, cName) { Layout.call(this); this.href = href || '#'; this.className = cName || 'default'; this.text = text || ''; this.init(); } inheritPrototype(ATag, Layout); ATag.prototype.init = function () { this.element = document.createElement("a"); this.element.href = this.href; this.element.innerHTML = this.text; } ATag.prototype.add = function () { } ATag.prototype.getElement = function () { return this.element; } /***************简单新闻结束*******************/
7,生成带分类的新闻标题
/***************分类新闻开始*******************/ var TypeMsg = function (text, href, type, cName, pos) { Layout.call(this); this.text = text || ''; this.href = href || '#'; this.type = type || ''; this.pos = pos || 'left'; this.className = cName || ''; this.init(); } inheritPrototype(TypeMsg, Layout); TypeMsg.prototype.init = function () { this.element = document.createElement("a"); if (this.pos === 'left') { this.element.innerHTML = '[' + this.type + '] ' + this.text; } else { this.element.innerHTML = this.text + ' [' + this.type + ']'; } this.element.href = this.href; this.element.className = this.className; } TypeMsg.prototype.add = function () { } TypeMsg.prototype.getElement = function () { return this.element; } /***************分类新闻结束*******************/
8、大功告成,开始调用生成最后的模块
window.onload = function () { var oUlContainer = new UlContainer('Layout', document.body); oUlContainer.add( new LiTag('default').add( new TypeMsg('es6系列教程 - 新的类语法实战选项卡', 'http://www.cnblogs.com/ghostwu/p/7465066.html', 'js高手之路-ghostwu', 'default', 'left') ) ).add( new LiTag('default').add( new TypeMsg('设计模式系列课程-单例模式实现模态框', 'http://www.cnblogs.com/ghostwu/p/7460301.html', 'js高手之路-ghostwu', 'default', 'left') ) ).add( new LiTag('default').add( new TypeMsg('HTML标签解释成DOM节点', 'http://www.cnblogs.com/ghostwu/p/7455184.html', 'js高手之路-ghostwu', 'default', 'left') ) ).add( new LiTag('default').add( new TypeMsg('HTML标签解释成DOM节点', 'http://www.cnblogs.com/ghostwu/p/7455184.html', 'js高手之路-ghostwu', 'default', 'left') ) ).add( new LiTag('default').add( new ATag('构造函数的基本特性与优缺点', 'http://www.cnblogs.com/ghostwu/p/7434609.html', 'js高手之路-ghostwu' ) ) ).show(); }
相关文章推荐
- [js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表
- [js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表
- [js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表
- [js高手之路]设计模式系列课程-委托模式实战微博发布功能
- [js高手之路] 设计模式系列课程 - 迭代器(1)
- [js高手之路]设计模式系列课程-单例模式实现模态框
- [js高手之路] 设计模式系列课程 - jQuery的链式调用与灵活的构造函数
- [js高手之路]设计模式系列课程-设计一个模块化扩展功能(define)和使用(use)库
- [js高手之路]设计模式系列课程-设计一个模块化扩展功能(define)和使用(use)库
- [js高手之路]设计模式系列课程-发布者,订阅者重构购物车
- [js高手之路]设计模式系列课程-发布者,订阅者重构购物车
- [js高手之路] 设计模式系列课程 - DOM迭代器(2)
- [js高手之路]设计模式系列课程-发布者,订阅者重构购物车
- [js高手之路]设计模式系列课程-设计一个模块化扩展功能(define)和使用(use)库
- [js高手之路]设计模式系列课程-设计一个模块化扩展功能(define)和使用(use)库
- [js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
- [js高手之路]设计模式系列课程-单例模式实现模态框
- [js高手之路] 设计模式系列课程 - jQuery的extend插件机制
- 【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第1节:为什么Spark是大数据必然的现在和未来?(2)
- 【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第2节:Spark架构设计(1)