Heim > Web-Frontend > js-Tutorial > 用js实现层随着内容大小动态渐变改变 推荐_javascript技巧

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

WBOY
Freigeben: 2016-05-16 18:38:45
Original
1059 Leute haben es durchsucht

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

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

实现原理很简单,就是在外边放一个主体层,我们调整的就是这个层,我们首先把这个层设置一个很小的宽和高,然后设置其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="http://www.jb51.net/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
Verwandte Etiketten:
div
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage