用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学习笔记(十)
Jan 17 Javascript
jquery 插件实现图片延迟加载效果代码
Feb 06 Javascript
BootStrap的弹出框(Popover)支持鼠标移到弹出层上弹窗层不隐藏的原因及解决办法
Apr 03 Javascript
BootstrapTable与KnockoutJS相结合实现增删改查功能【二】
May 10 Javascript
修改js confirm alert 提示框文字的简单实例
Jun 10 Javascript
Bootstrap进度条实现代码解析
Mar 07 Javascript
jquery中done和then的区别(详解)
Dec 19 jQuery
微信小程序收藏功能的实现代码
Jun 12 Javascript
详解javascript函数写法大全
Mar 25 Javascript
vue中node_modules中第三方模块的修改使用详解
May 31 Javascript
微信小程序语音同步智能识别的实现案例代码解析
May 29 Javascript
vue render函数动态加载img的src路径操作
Oct 26 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
php5 apache 2.2 webservice 创建与配置(java)
2011/01/27 PHP
php中使用$_REQUEST需要注意的一个问题
2013/05/02 PHP
PHP排序算法之简单选择排序(Simple Selection Sort)实例分析
2018/04/20 PHP
PHP+ajax实现获取新闻数据简单示例
2018/05/08 PHP
对象无length属性时IE6/IE7中无法将其转换成伪数组(ArrayLike)
2011/07/31 Javascript
JS倒计时代码汇总
2014/11/25 Javascript
jQuery实现页面滚动时动态加载内容的方法
2015/03/20 Javascript
JS集成fckeditor及判断内容是否为空的方法
2016/05/27 Javascript
js基础之DOM中document对象的常用属性方法详解
2016/10/28 Javascript
微信小程序 基础组件与导航组件详细介绍
2017/02/21 Javascript
bootstrap实现动态进度条效果
2017/03/08 Javascript
浅析 NodeJs 的几种文件路径
2017/06/07 NodeJs
checkbox:click事件触发span元素内容改变的方法
2017/09/11 Javascript
RequireJS用法简单示例
2018/08/20 Javascript
javascript实现考勤日历功能
2018/11/29 Javascript
vue项目首屏加载时间优化实战
2019/04/23 Javascript
详解如何在Vue项目中发送jsonp请求
2019/10/25 Javascript
[02:00]最后,我终于出了辉耀
2018/03/27 DOTA
Python中Django框架利用url来控制登录的方法
2015/07/25 Python
解决python使用open打开文件中文乱码的问题
2017/12/29 Python
Python 数据处理库 pandas 入门教程基本操作
2018/04/19 Python
pytorch对可变长度序列的处理方法详解
2018/12/08 Python
HTML5中新标签和常用标签详解
2014/03/07 HTML / CSS
京东奢侈品:全球奢侈品牌
2018/03/17 全球购物
ORLY官网:美国专业美甲一线品牌
2019/12/11 全球购物
养殖项目策划书范文
2014/01/13 职场文书
小学模范班主任事迹材料
2014/05/13 职场文书
房屋维修协议书范本
2014/09/25 职场文书
六查六看剖析材料
2014/10/06 职场文书
乡镇民主生活会发言材料
2014/10/20 职场文书
工作作风懒散检讨书
2014/10/29 职场文书
护士求职自荐信范文
2015/03/04 职场文书
2016年师德师风学习心得体会
2016/01/12 职场文书
mysql sum(if())和count(if())的用法说明
2022/01/18 MySQL
船舶调度指挥系统——助力智慧海事
2022/02/18 无线电
InterProcessMutex实现zookeeper分布式锁原理
2022/03/21 Java/Android