用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 相关文章推荐
javascript call和apply方法
Nov 24 Javascript
JavaScript中json使用自己总结
Aug 13 Javascript
json的定义、标准格式及json字符串检验
May 11 Javascript
JavaScript实现数字数组按照倒序排列的方法
Apr 06 Javascript
基于jquery实现放大镜效果
Aug 17 Javascript
学习JavaScript鼠标响应事件
Dec 25 Javascript
分享jQuery插件的学习笔记
Jan 14 Javascript
ionic开发中点击input时键盘自动弹出
Dec 23 Javascript
使用DeviceOne实现微信小程序功能
Dec 29 Javascript
Angualrjs和bootstrap相结合实现数据表格table
Mar 30 Javascript
基于滚动条位置判断的简单实例
Dec 14 Javascript
如何根据业务封装自己的功能组件
Apr 19 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
关于我转生变成史莱姆这档事:第二季PV上线,萌王2021年回归
2020/05/06 日漫
Zend公司全球首推PHP认证
2006/10/09 PHP
用PHP连接Oracle数据库
2006/10/09 PHP
攻克CakePHP系列一 连接MySQL数据库
2008/10/22 PHP
php escape URL编码
2008/12/10 PHP
Mac系统下安装PHP Xdebug
2018/03/30 PHP
Mootools 1.2教程(2) DOM选择器
2009/09/14 Javascript
javascript的onchange事件与jQuery的change()方法比较
2009/09/28 Javascript
JQuery Dialog的内存泄露问题解决方法
2010/06/18 Javascript
javascript 冒泡排序 正序和倒序实现代码
2010/12/14 Javascript
jqgrid 简单学习笔记
2011/05/03 Javascript
Jquery index()方法 获取相应元素索引值
2012/10/12 Javascript
动态加载jquery库的方法
2014/02/12 Javascript
Javascript中的五种数据类型详解
2014/12/26 Javascript
js中字符串编码函数escape()、encodeURI()、encodeURIComponent()区别详解
2016/04/01 Javascript
通过BootStrap-select插件 js jQuery控制select属性变化
2017/01/03 Javascript
JS实现获取汉字首字母拼音、全拼音及混拼音的方法
2017/11/14 Javascript
webpack下实现动态引入文件方法
2018/02/22 Javascript
js事件on动态绑定数据,绑定多个事件的方法
2018/09/15 Javascript
layui 地区三级联动 form select 渲染的实例
2019/09/27 Javascript
Python多进程机制实例详解
2015/07/02 Python
Python之inspect模块实现获取加载模块路径的方法
2018/10/16 Python
Python利用字典破解WIFI密码的方法
2019/02/27 Python
关于python字符串方法分类详解
2019/08/20 Python
python 中不同包 类 方法 之间的调用详解
2020/03/09 Python
Django调用百度AI接口实现人脸注册登录代码实例
2020/04/23 Python
Python3开发环境搭建详细教程
2020/06/18 Python
Python 创建TCP服务器的方法
2020/07/28 Python
css3中检验表单的required,focus,valid和invalid样式
2014/02/21 HTML / CSS
房地产财务管理制度
2014/02/02 职场文书
商场消防演习方案
2014/02/12 职场文书
社区党建工作汇报材料
2014/08/14 职场文书
公司向个人借款协议书范本
2014/10/09 职场文书
家长高考寄语
2015/02/27 职场文书
2019企业给员工的慰问信
2019/06/24 职场文书
pytorch中的model=model.to(device)使用说明
2021/05/24 Python