用js实现层随着内容大小动态渐变改变 推荐


Posted in Javascript onDecember 19, 2009

下面我们就自己来实现一个这样的组件,没有参考其他资料,纯属自己瞎写。

我觉得我这个方法很简单了,只需要在外边多套一个层就可以,而且可以容纳大量的文字(为什么这样说?因为如果只是单纯的图片,那调整起来简单多了,而如果有一大串文字的话,要变换两次才可以,因为如果你改变了宽度的话,字会被挤得高度增加,这里有两个方法来调整,一个是每次动画循环都更新最新的高和宽,另一种方法就是先变换,变换完后再检查一次,这次变化的只是高度,也就是调节两次,第一种方法效果好,但是每次都更新,自然加重了负担,第二种效果差点,但是性能好,而且也不是那么差)

实现原理很简单,就是在外边放一个主体层,我们调整的就是这个层,我们首先把这个层设置一个很小的宽和高,然后设置其overflow为hidden,然后运行时判断里面内容的大小,再回来调整外部层的大小即可。
本程序用到了YUI的一个动画函数和一个淘宝sns的jsonhtml对象,这个对象的作用是将一个用json形式表示的html转换成真正的html结构,可以使构造html的程序简洁清晰。

主体从Tip开始,我将这个组件写成了单例的模式,也就是不用new就可以在任何地方使用,而且都指向一个对象,而且这个组件封装目前没优化,为了试验,里面很多东西都是直接改的,外部暴露的接口太少:

var Tip=function(){ 
//直接返回一个json对象,这是一种js单例模式的实现 
return { 
//初始化函数 
init:function(options){ 
this.config={ 
container:null,//包装容器 
style:{},//样式配置 
data:{} 
} 
//样式配置 
this.style={tip:null,tip_title:null,tip_pic:null,tip_bd:null} 
//混合配置选项 
mixin(this.config,options) 
//初始数据 
this.data={ 
//标题的数据 
hd_data:this.config.data.hd_data==null?"没有描述":this.config.data.hd_data, 
//图片数据,正常情况下应该是一个网址 
pic_data:this.config.data.pic_data==null?"#":this.config.data.pic_data, 
//主题内容数据 
bd_data:this.config.data.bd_data==null?"没有描述":this.config.data.bd_data 
} 
//这是定义了一个加载的时候显示的滚动的gif的图像 
this.loading_pic=new Image(); 
this.loading_pic.src="http://www.sj33.cn/sc/UploadFiles_6888/200803/20080320132838323.gif"; this.creatHtml();//调用html构造器 
},

关于为什么js写成这样,还有一些从某些库里学来的写法就不多解释了,注释也很清楚,这里就是初始化一些数据,用来给后面的程序处理.
/** 
*构造html结构 
*/ 
creatHtml:function(){ 
//从外边数第二层的样式,它包住了里面的所有元素,大小是随着里面元素大小而变化的 
this.style.tip={ 
backgroundColor:"#fff", 
color:"#fff", 
border:"1px #333 solid", 
padding:"10px", 
overflow:"visible" 
} 
//标题的样式 
this.style.tip_title={ 
color:"#037DF9", 
fontSize:"14px", 
fontWeight: "bold" 
} 
this.style.tip_pic={ } 
//文字内容的样式 
this.style.tip_bd={ 
color:"#333", 
lineHeight:"20px" 
} 
this.style.hr={ 
color:"#037DF9", 
height:"1px", 
border:"0", 
borderTop:"1px #037DF9 solid", 
margin:"10px 0" 
} 
//最外边包装层的样式 
this.style.outer={ 
border:"5px solid #037DF9", 
overflow:"hidden", 
width:"10px", 
height:"10px" 
} 
//混合选项,也就是说这些都可以在外部自己定义样式,然后覆盖默认的样式 
mixin(this.style.tip,this.config.style.tip) 
mixin(this.style.tip_title,this.config.style.tip_title) 
mixin(this.style.tip_pic,this.config.style.tip_pic) 
mixin(this.style.tip_bd,this.config.style.tip_bd) 
//这个json就是html结构,其实不难理解,看看jsonhtml.js的源码就理解了 
var html_config={ 
div:{id:"tip_outer",style:this.style.outer}, 
">>":[ 
{div:{id:"tip_inner",style:this.style.tip}, 
">>":[ 
{div:{className:"tip-title",style:this.style.tip_title,id:"tip-title"},">>":this.data.hd_data}, 
{hr:{style:this.style.hr}}, 
{div:{className:"tip-pic",style:this.style.tip_pic,id:"tip-pic"},">>":[{img:{src:this.data.pic_data}}]}, 
{hr:{style:this.style.hr}}, 
{div:{className:"tip-bd",style:this.style.tip_bd,id:"tip-bd"},">>":this.data.bd_data} 
]} 
] 
} 
//转换成真正的html元素 
var html=JsonHtml.compose(html_config) 
//添加到容器中 
var tip_container=this.config.container||document.body; 
tip_container.appendChild(html) 
//下面获取一些元素,用来后面的操作,例如填充数据,动画等 
this.tip_outer=document.getElementById("tip_outer") 
this.tip_inner=document.getElementById("tip_inner") 
this.tip_title=document.getElementById('tip-title') 
this.tip_pic=document.getElementById('tip-pic') 
this.tip_bd=document.getElementById('tip-bd') 
//此时已经初始化了,首次调用了此函数,这就是大小自适应的函数 
this.updateSize(); 
},

上面首次出现了updateSize()函数,此函数就是今天的主体函数,不过遗憾的是这个函数非常短,
/** 
* 自动调整大小 
*/ 
updateSize:function(size){ 
//这里用了一个很不厚道的hack,那就是在大多数时候,我在外部就计算好要调整的高度,然后传进来,而不是在这里调整的 
//当然也可以不传参数,那样这里的计算就要麻烦点 
var size=size||{width:null,height:null} 
//获取里面的tip的大小,后面就把外边的层的大小变成这个大小 
var _height=size.height||this.tip_inner.offsetHeight; 
var _width=size.width||this.tip_inner.offsetWidth; 
var now_this=this; 
//开始定义动画 
var ani=new YAHOO.util.Anim(this.tip_outer, {height:{to:_height},width:{to:_width}},0.7) 
//第一次动画结束后,文字那里通常是不对的,因为字会因为宽度变了,而改变高度,这个是动态不可预知的,所以这里 
//再检查一遍 
ani.onComplete.subscribe(function(){ 
var _height=now_this.tip_inner.offsetHeight; 
var _width=now_this.tip_inner.offsetWidth; 
var ani2=new YAHOO.util.Anim(now_this.tip_outer, {height:{to:_height},width:{to:_width}},0.7); ani2.animate(); 
}); 
ani.animate(); 
},

注释很详细,无需多说了,这个对象只剩下一个函数了,那就是填充数据,这个函数可以多次执行,每次都会导致数据变化和大小的变化
/** 
* 改变填充数据 
* @param data 一个json对象,包括三部分的数据{hd_data:"",pic_data:"",bd_data:""} 
*/ 
updateData:function(data){ 
this.data={ 
hd_data:null?"没有描述":data.hd_data,//标题的数据 
pic_data:null?"#":data.pic_data,//图片数据,正常情况下应该是一个网址 
bd_data:null?"没有描述":data.bd_data//主题内容数据 
} 
//填充数据 
this.tip_title.innerHTML=this.data.hd_data; 
this.tip_bd.innerHTML=this.data.bd_data; 
this.tip_pic.innerHTML="" 
this.tip_pic.appendChild(this.loading_pic) 
var now_this=this; 
//填充图片 
this.pic=new Image(); 
this.pic.src=this.data.pic_data; 
this.pic.errorpic=new Image(); 
this.pic.errorpic.src="https://3water.com/logo.gif";//图片加载错误时显示的图片 
this.pic.onload=function(){ 
now_this.tip_pic.innerHTML=""; now_this.tip_pic.appendChild(this) 
now_this.updateSize({width:this.width+20}); 
} 
this.pic.onerror=function(){ 
now_this.tip_pic.innerHTML=""; 
now_this.tip_pic.appendChild(this.errorpic) 
now_this.updateSize({width:this.errorpic.width+20}); 
} 
this.updateSize(); 
},

到这里这个对象就结束了,是不是很简单,他已经很完整了,下面我们就来启动它,我们设置一些数据,然后随机地填充,每次点击页面都会填充不同的数据.
window.onload = function(){ 
AddLink.init({ 
class_name: "content" 
}); 
Tip.init(); 
document.body.onclick=function(){ 
Array.prototype.rand=function(){ 
return this[Math.round(Math.random()*(this.length-1))]; 
} 
var hd_arr=[ 
"我是随机的你信不信", 
"不信算了,点击页面我就会变了", 
"每点一次都会变", 
"也有可能重复的", 
"重复的我可不管饿,因为我是随机的" 
]; 
var pic_arr=[ 
"http://www.beiju123.cn/blog/wp-content/uploads/2009/12/2009-12-14-20-53-231.png", 
"http://www.beiju123.cn/blog/wp-content/uploads/2009/12/2009-12-15-23-51-45.png", 
"http://www.beiju123.cn/blog/wp-content/uploads/2009/12/2009-12-16-00-25-38.png", 
"http://www.beiju123.cn/blog/wp-content/uploads/2009/12/2009-12-14-23-25-171.png", 
"http://www.beiju123.cn/blog/wp-content/uploads/2009/12/2009-12-14-20-49-362.png", 
"http://dgdgdg.d" 
] 
var bd_arr=[ 
"最近听人说aptana这个ide不错,也支持我喜欢的ruby,而且对js和html,css支持也很好,我比较来比较去,还是喜欢netbeans,首先因为netbeans里有个插件,可以把着色的代码复制粘贴成html+css,而是代码着色aptana不好看,自己配又配不出感觉来,net串get什么什么的就行了.js已经是够简洁的语言了,提醒太多反而没什么意义,不过在netbeans里的YUI提示和我看的YUI不是一个版本的,全是错的,但是我还是喜欢netbeans多一点,其实编程这东西效率很难说高和低,思路理清楚了,自然效率高.程序写的很快的话,代码提示很智能的话,反而太依赖,对思路理解不深刻,写着后面忘了前面,效率反而慢了", 
"后可以做一些基本的处理,例如加个边框美化下,可以用画笔涂一下,这个比较有用,高清图上有字的背景图,可以涂掉就可以直接用了.下面说一下其他功能吧, 首先,最重磅的就是”标尺”,可以", 
"代码复制粘贴成html+css,而是代码着色aptana不好看,自己配又配不出感觉来,netbeans的界面也比较清爽,至于js提示,其实我从来就没用到过高级的提示,在netbeans里我只需要他在我输入document.的时候出来后面那一串get什么什么的就行了.js已经是够简洁的语言了,提醒太多反而没什么意义,不过在netbeans里的YUI提示和我看的YUI不是一个版本的,全是错的,但是我还是喜欢netbeans多一点,其实编程这东西效率很难说高", 
"这里我只拿我的几个比较宽泛的想法来谈自己对top平台的理解,为自己保留一条秘密,同时也跟大家分享自己的想法.现今社会,很多产业都已经趋向于饱和,例如:超市行业.在南京,苏果超市占据了绝对地位.随处可见其身影,当然也有类似华联和家乐福之类的超市经提供了上述服务了,但是我们可以通过来提供更多个性服务来增加自己的竞争力.我其实也正在策划做一个公益性的垂直搜索网站,可能会争取到政府的资金支持,但是目前我除了我女朋友还没有跟任何人透露过,如果有人对此感兴趣可以找我讨论." 
] 
var config={ 
hd_data:hd_arr.rand(), 
pic_data:pic_arr.rand(), 
bd_data:bd_arr.rand() 
} 
Tip.updateData(config); } 
}

演示地址:http://beiju123.cn/blog/addLink_1.html
作者:http://www.cnblogs.com/mars-bird
Javascript 相关文章推荐
鼠标经过tr时,改变tr当前背景颜色
Jan 13 Javascript
JQuery的$和其它JS发生冲突的快速解决方法
Jan 24 Javascript
JavaScript中的操作符==与===介绍
Dec 31 Javascript
基于jQuery实现网页打印功能
Dec 01 Javascript
jquery弹出遮掩层效果【附实例代码】
Apr 28 Javascript
JavaScript编写页面半透明遮罩效果的简单示例
May 09 Javascript
jQuery调用Webservice传递json数组的方法
Aug 06 Javascript
遍历json 对象的属性并且动态添加属性的实现
Dec 02 Javascript
微信小程序 商城开发(ecshop )简单实例
Apr 07 Javascript
Javascript中的作用域及块级作用域
Dec 08 Javascript
vue.js单文件组件中非父子组件的传值实例
Sep 13 Javascript
vue+element实现表格新增、编辑、删除功能
May 28 Javascript
javascript demo 基本技巧
Dec 18 #Javascript
IE和Firefox下event事件杂谈
Dec 18 #Javascript
替代window.event.srcElement效果的可兼容性的函数
Dec 18 #Javascript
JavaScript 序列化对象实现代码
Dec 18 #Javascript
让div层随鼠标移动的实现代码 ie ff
Dec 18 #Javascript
Javascript在IE或Firefox下获取鼠标位置的代码
Dec 18 #Javascript
javascript 导出数据到Excel(处理table中的元素)
Dec 18 #Javascript
You might like
提升PHP执行速度全攻略(下)
2006/10/09 PHP
php调用新浪短链接API的方法
2014/11/08 PHP
PHP工厂模式简单实现方法示例
2018/05/23 PHP
基于jquery的finkyUI插件与Ajax实现页面数据加载功能
2010/12/03 Javascript
Javascript面向对象之四 继承
2011/02/08 Javascript
JQuery将文本转化成JSON对象需要注意的问题
2011/05/09 Javascript
IE与Firefox在JavaScript上的7个不同句法分享
2011/10/30 Javascript
JavaScript 基础篇(一)
2012/03/30 Javascript
js+CSS实现模拟华丽的select控件下拉菜单效果
2015/09/01 Javascript
jQuery实现的超简单点赞效果实例分析
2015/12/31 Javascript
jQuery给指定的table动态添加删除行的操作方法
2016/10/12 Javascript
超级简易的JS计算器实例讲解(实现加减乘除)
2017/08/08 Javascript
gulp安装以及打包合并的方法教程
2017/11/19 Javascript
总结4个方面优化Vue项目
2019/02/11 Javascript
JQuery省市联动效果实现过程详解
2020/05/08 jQuery
Vue页面渲染中key的应用实例教程
2021/01/12 Vue.js
JavaScript仿京东轮播图效果
2021/02/25 Javascript
Python减少循环层次和缩进的技巧分析
2016/03/15 Python
Python Web程序部署到Ubuntu服务器上的方法
2018/02/22 Python
python 利用文件锁单例执行脚本的方法
2019/02/19 Python
python文件写入write()的操作
2019/05/14 Python
基于h5py的使用及数据封装代码
2019/12/26 Python
手把手教你将Flask应用封装成Docker服务的实现
2020/08/19 Python
如何用python实现一个HTTP连接池
2021/01/14 Python
详解如何在登录过期后跳出Ifram框架
2020/09/10 HTML / CSS
英国最大的专业户外零售商:Mountain Warehouse
2018/06/06 全球购物
北京SQL新华信咨询
2016/09/30 面试题
学生安全责任书
2014/04/15 职场文书
二年级评语大全
2014/04/23 职场文书
医学专业大学生求职信
2014/07/12 职场文书
优秀大专毕业生求职信
2014/08/04 职场文书
2014年党员个人工作总结
2014/12/02 职场文书
基石观后感
2015/06/12 职场文书
在vue中import()语法不能传入变量的问题及解决
2022/04/01 Vue.js
MySQL的存储过程和相关函数
2022/04/26 MySQL
td 内容自动换行 table表格td设置宽度后文字太多自动换行
2022/12/24 HTML / CSS