<body>
<h3>设计模式知识连载(25)---享元模式:</h3>
<p>
运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销【优化用的】
</p>
<hr>
<div id = 'container'>
</div>
<div>
<span id = 'next_page'>下一页</span>
</div>
<script type="text/javascript">
/****
* 模拟数据
****/
article = [
'01、test111111',
'02、test222222',
'03、test333333',
'04、test444444',
'05、test555555',
'06、test666666',
'07、test777777',
'08、test888888',
'09、test999999'
] ;
/**
* 案例一:翻页需求,方式一:初始
*/
// // 缓存创建的新闻标题元素
// var dom = null ;
// // 当前页数
// var paper = 0 ;
// // 每页显示新闻数目
// num = 5 ;
// // 创建新闻元素时保存变量
// var i = 0 ;
// // 新闻数据长度
// var len = article.length ;
// for(; i < len; i++) {
// // 创建包装新闻标题元素
// dom = document.createElement('div') ;
// // 向元素中添加新闻标题
// dom.innerHTML = article[i] ;
// // 默认显示第一页
// if(i >= num) {
// // 超出第一页新闻隐藏
// dom.style.display = 'none' ;
// }
// // 添加到页面中
// document.getElementById('container').appendChild(dom) ;
// } ;
// // 下一页绑定事件
// document.getElementById('next_page').onclick = function() {
// // 获取所有新闻标题包装元素
// var div = document.getElementById('container').getElementsByTagName('div');
// // j, k循环变量,n当前页显示的第一个新闻序号
// var j = k = n = 0 ;
// // 获取当前页显示的第一个新闻序号
// n = ++paper % Math.ceil(len/num) * num ;
// for(; j < len; j++) {
// // 隐藏所有新闻
// div[j].style.display = 'none' ;
// }
// for(; k < 5; k++){
// if(div[n + k]) {
// //显示当前页新闻
// div[n + k].style.display = 'block' ;
// }
// }
// } ;
/**
* 案例一:翻页需求,方式二:享元模式
*/
// 提供一个操作方法
var Flyweight = (function() {
// 已创建的元素
var created = [] ;
// 创建一个新闻包装容器
function create() {
// 获取所有新闻标题包装元素
var _dom = document.createElement('div') ;
// 将容器插入新闻列表容器中
document.getElementById('container').appendChild(_dom) ;
// 缓存新创建的元素
created.push(_dom) ;
return _dom ;
} ;
return {
// 获取创建新闻元素方法
getDiv : function() {
// 如果已创建的元素小于当前页元素总个数,则创建
if(created.length < 5) {
return create() ;
}else{
// 获取第一个元素,并插入最后面
var _div = created.shift() ;
created.push(_div) ;
return _div ;
}
}
}
})() ;
/*初始化页面*/
var paper = 0 ;
var num = 5 ;
len = article.length ;
// 添加5条新闻
for(var i = 0; i < 5; i++) {
if(article[i]) {
// 通过享元类获取创建的元素并写入新闻内容
Flyweight.getDiv().innerHTML = article[i] ;
}
} ;
// 下一页按钮绑定事件
document.getElementById('next_page').onclick = function() {
// 如果新闻内容不足5条则返回
if(article.length < 5) {
return ;
} ;
// 获取当前页的第一条新闻索引
var n = ++paper * num % len ;
// 循环变量
var j = 0 ;
// 插入5条新闻
for(; j < 5; j++) {
// 如果存在第n+j条则插入
if(article[n + j]) {
Flyweight.getDiv().innerHTML = article[n + j] ;
// 否则插入起始位置第n+j-len条
}else if(article[n + j - len]){
Flyweight.getDiv().innerHTML = article[n + j - len] ;
// 如果都不存在则插入空字符串
}else{
Flyweight.getDiv().innerHTML = '' ;
}
}
} ;
/**
* 案例二:游戏人物动作,方式一:
*/
// 享元类
var Flyweight2 = {
moveX : function(x) {
this.x = x ;
},
moveY : function(y) {
this.y = y ;
}
} ;
// 角色
var Player = function (x, y, c) {
this.x = x ;
this.y = y ;
this.color = c ;
} ;
Player.prototype = Flyweight2 ;
Player.prototype.changeColor = function(c) {
this.color = c ;
};
// 精灵
var Spirit = function(x, y, r) {
this.x = x ;
this.y = y ;
this.r = r ;
} ;
Spirit.prototype = Flyweight2 ;
Spirit.prototype.changeR = function(r) {
this.r = r ;
} ;
// 创建实例
var player1 = new Player(10, 10, 'red') ;
console.log(player1) ;
console.log('修改后的数据为:--------') ;
player1.moveX(5) ;
player1.moveY(5) ;
player1.changeColor('blue') ;
console.log(player1) ;
// 创建精灵实例
var spirit1 = new Spirit(10, 10, 10) ;
console.log(spirit1) ;
console.log('修改后的数据为:--------') ;
spirit1.moveX(30) ;
spirit1.moveX(30) ;
spirit1.changeR(30) ;
console.log(spirit1) ;
</script>
</body>