欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!
    本文是html5+css3系列教程的第一篇,给大家大概html5+css3实现气泡组件,讲解的十分的详细,这里推荐给大家,希望对大家能有所帮助
 
    前言
 
    气泡组件在实际工作中非常普遍,无论是网页中还是app中,示例:
 
    我们这里所谓的气泡组件是指列表型气泡组件,这里就其dom意识到,css实现,js实现做一个讨论,最后对一些细节点做一些说明,希望对各位有用
 
    小钗最近初学CSS,这里做一个专题,同时自身CSS提升,文章有过多问题与可优化点,请各位指导组件分类
 
    单由气泡组件来说,他仍然属于“投射层”类组件,随之其会具有这些特性:
 
    ①布局为脱离文档流
 
    ②可以具有蒙版蒙版,并且可配置点击蒙版是否关闭的特性
 
    ③可选的特性有点击浏览器回退关闭组件以及动画的显示与隐藏动画特性
 
    其中比较不同的是:
 
    ①不是居中定位
 
    ②具有一个箭头标识,并且可以设置再上或者在下
 
    ③因为具有箭头,而且这个箭头是相对于一个元素的,一般意义上我们任务是相对某个按钮,所以说具有一个triggerEL
 
    所以单从这里可能来说,我们的组件称为BubbleLayer,其应该继承与一个通用的Layer
 
    但是,就由Layer来说,其最少会具有以下通用特性:
 
    ①创建-创建
 
    ②显示-显示
 
    ③隐藏-隐藏
 
    ④破坏-毁灭
 
    而以上特性并不是Layer组件所特有的,其他所有组件所特有,所以在Layer之上还应该存在一个AbstractView的抽象组件
 
    至此继承关系便出来了,抛开多余的接口不看,简单来说是这样的:
 
    组件dom实现最小的实现
 
    单从dom实现来说,其实一个简单的ul便可以完成任务
 
    复制代码
 
    代码如下:
 
    <ulclass=“cui-bubble-layer”style=“位置:绝对;顶部:110px;左侧:220px;”><lidata-index=“0”data-flag=“c”>价格:¥35</li><lidata-index=“1”data-flag=“c”>评分:80</li><lidata-index=“2”data-flag=“c”>等级:5</li></ul>
 
    当然这里要有相关的css
 
    复制代码
 
    代码如下:
 
    .cui-bubble-layer{背景:#f2f2f2;边框:#bcbcbc1像素实线;border-radius:3px}
 
    至此形成的效果是酱紫滴:
 
    复制代码
 
    代码如下:
 
    <!doctypehtml><html><head><metacharset=“utf-8”/><title>刀片演示</title><metaname=“viewport”content=“width=device-width,initial-scale=1.0,最小比例=1.0,最大比例=1.0,用户可缩放=否“><metacontent=”电话=no“name=”格式检测“/><metaname=”apple-mobile-web-app-capable“content=”yes“/><styletype=”text/css“>正文,按钮,输入,选择,textarea{字体:40014px/1.5Arial,“LucidaGrande”,Verdana,“MicrosoftYaHei”,嘿;}
 
    正文,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,代码,表单,字段集,图例,图例,输入,textarea,p,blockquote,th,td,hr,按钮,文章,放在一边,详细信息,figcaption,图,页脚,页眉,hgroup,菜单,导航,部分{边距:0;填充:0;}正文{背景:#f5f5f5;}ul,ol{list-style:none;}.cui-bubble-layer{背景:#f2f2f2;边框:#bcbcbc1像素实线;border-radius:3px;}</style></head><body><ulclass=“cui-bubble-layer”style=“position:absolute;top:110px;left:220px;”><lidata-index=“0”data-flag=“c”>价格:¥35</li><lidata-index=“1”data-flag=“c”>评分:80</li><
 
    </html>
 
    这个时候在为此加上一个伪类,做点样式上的调整,便基本实现了,这里用到了伪类的知识点:
 
    复制代码
 
    代码如下:
 
    cui-bubble-layer:before{position:absolute;内容:“”;宽度:10px;高度:10px;-webkit-transform:旋转(45deg);背景:#f2f2f2;border-top:#bcbcbc1px实线;border-left:#bcbcbc1px实线;顶部:-6px;左:50%;左边距:-5px;z索引:1;}
 
    这里设置了一个绝对定位的矩形框,从而两个边框设置了值,然后变形偏斜45度形成小三角,然后大家都知道了
 
    复制代码
 
    代码如下:
 
    <!doctypehtml>
 
    <html>
 
    <head>
 
    <metacharset="utf-8"/>
 
    <title>BladeDemo</title>
 
    <metaname="viewport"content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
 
    <metacontent="telephone=no"name="format-detection"/>
 
    <metaname="apple-mobile-web-app-capable"content="yes"/>
 
    <styletype="text/css">
 
    body,button,input,select,textarea{font:40014px/1.5Arial,"LucidaGrande",Verdana,"MicrosoftYaHei",hei;}
 
    body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{margin:0;padding:0;}
 
    body{background:#f5f5f5;}
 
    ul,ol{list-style:none;}
 
    .cui-bubble-layer{background:#f2f2f2;border:#bcbcbc1pxsolid;border-radius:3px;}
 
    .cui-bubble-layer>li{padding:5px10px;}
 
    .cui-bubble-layer:before{position:absolute;content:"";width:10px;height:10px;-webkit-transform:rotate(45deg);background:#f2f2f2;border-top:#bcbcbc1pxsolid;border-left:#bcbcbc1pxsolid;top:-6px;left:50%;margin-left:-5px;z-index:1;</style>
 
    </head>
 
    <body>
 
    <ulclass=“cui-bubble-layer”style=“位置:绝对;顶部:110px;左侧:220px;”><lidata-index=“0”data-flag=“c”>价格:¥35</li><lidata-index=“1”data-flag=“c”>评分:80</li><lidata-index=“2”data-flag=“c”>等级:5</li></ul></body></html>
 
    http://sandbox.runjs.cn/show/9ywitfn8不足与扩展
 
    上面作为基本实现,没有什么问题,但是其实际应用场景会有以下不足:
 
    ①基本的ul层级需要一个包裹层,包裹层具有一个up或down的class,然后在决定那个箭头是向上还是向下
 
    ②我们这里不能使用伪类,其原因是,我们的小三角标签并不是一定在中间,其具有一定的滑动的特性,从而,这个小三角需要被js控制其左右位置,他需要是一个标签
 
    根据以上所述,我们的结构似乎应该是这个样子滴:
 
    复制代码
 
    代码如下:
 
    <sectionclass=“cui-bubble-layerup-or-down-class”><iclass=“cui-icon-triangle”></i><ul><lidata-index=“0”数据标志=“c”>价格:¥35</li><lidata-index=“1”data-flag=“c”>评分:80</li><lidata-index=“2”data-flag=“c”>等级:5</li></ul></section>
 
    ①根元素上我们可以设置当前应该是up还是down的样式
 
    ②i标签根据根元素的向上或向下选择是向上还是向下,并且该标签可被js操作
 
    到此之后,似乎整个组件便比较完全了,但是真实的情况却不怎么样,称为了,上面的结构太局限了
 
    该组件需要一个容器,这个容器标签应该放在ul之上,这个时候容器内部所装载的dom结构便可以不是ul其他其他什么结构了
 
    实际上,在手机上,我们可视项目在4S手机上不会超过5个,往往是4个,所以我们应该在其容器上设置类似overflow之类的可滚动属性组件回归·最终结构
 
    由上所述,基于其是继承至Layer的事实,我们可以形成这样的结构:
 
    复制代码
 
    代码如下:
 
    <sectionclass=“cui-popcui-bubble-layer”><iclass=“cui-pop-triangle”></i><divclass=“cui-pop-head”></div><div类=“cui-pop-body”><ul><lidata-index=“0”data-flag=“c”>价格:¥35</li><lidata-index=“1”data-flag=“c”>评分:80</li><lidata-index=“2”data-flag=“c”>等级:5</li></ul></div><divclass=“cui-pop-footer“></div></section>
 
    这个也可以是我们整个弹出层类的基本结构,我们可以在此上做很多扩展,但是这里我们不扯太多,单就气泡组件做改变
 
    就气泡组件,其结构是:
 
    复制代码
 
    代码如下:
 
    <sectionclass=“cui-popcui-bubble-layer”><iclass=“cui-pop-triangle”></i><divclass=“cui-pop-body”><ul><lidata-index=“0”data-flag=“c”>价格:¥35</li><lidata-index=“1”data-flag=“c”>评分:80</li><lidata-index=“2”data-flag=“c”>等级:5</li></ul></div></section>
 
    js的实现
 
    这里仍然是采用的blade中的那一套继承机制,如果有不明白又有点兴趣的同学请移步:【blade的UI设计】理解前端MVC与分层思想关于模板
 
    因为我们这一部分的主题为异步相关,所以我们这里的关注点是CSS,我们首先生成我们的模板:
 
    复制代码
 
    代码如下:
 
    <sectionclass=“cui-pop<%=wrapperClass%><%if(dir=='up'){%><%=upClass%><%}否则{%><%=downClass%><%}%>“><iclass=”cui-pop-triangle“></i><divclass=”cui-pop-body“><ulclass=”cui-pop-list<%=itemStyleClass%>“><%for(vari=0,len=data.length;i<len;i++){%><%varitemData=data[i];%><lidata-index=“<%=i%>”data-flag=“c”class=“<%if(index==i){%><%=curClass%><%}%>”><%if(typeofitemFn=='function'){%><%=itemFn.call(itemData)%><%}否则{%><%=itemData.name%><%}%>
 
    这里称为了几个关键的定制化点:
 
    ①wrapperClass为添加业务团队定制化的类以改变根元素的类,如此的好处是方便业务团队定制化气泡组件的样式
 
    ②提出了项目列表Ul的可定制化className,通用单单只是方便业务团队做样式改变
 
    ③默认情况下返回的是预定项目的名称扩展,但是用户可重定向一个itemFn的替代,定制化返回
 
    以上模板基本可满足条件,如果不满足,替换把整个模板作为参数设定了关于js实现
 
    由于继承的实现,我们大部分工作已经被做成,我们只需要在几个关键地方编写代码即可
 
    复制代码
 
    代码如下:
 
    define(['UILayer',getAppUITemplatePath('ui.bubble.layer')],函数(UILayer,模板){return_.inherit(UILayer,{属性:函数($super){$super();//html模板this.template=template;this.needMask=false;</p><p>this.datamodel={data:[],wrapperClass:'cui-bubble-layer',upClass:'cui-pop--triangle-up”,downClass:“cui-pop--triangle-down”,curClass:“active”,itemStyleClass:“”,needBorder:true,索引:-1,dir:“up”//箭头方向长度值};</p><p>这个。events={'click.cui-pop-list>li':'clickAction'
 
    };</p><p>this.onClick=函数(数据,索引,el,e){console.log(arguments);//this.setIndex(index);};</p><p>this.width=null;</p><p>//三角图标偏移量this.triangleLeft=null;this.triangleRight=null;</p><p>this.triggerEl=null;</p><p>},</p><p>initialize:函数($super,opts){$super(opts);},</p><p>createRoot:function(html){this。$el=$(html).hide()。attr('id',this.id);},</p><p>clickAction:函数(e){varel=$(e.currentTarget);vari=el.attr('data-index');vardata=this。datamodel.data[i];this.onClick.call(this,data,i,el,e);
 
    },</p><p>initElement:function(){this.el=this。$el;this.triangleEl=this。$('。cui-pop-triangle');this.windowWidth=$(window).width();},</p><p>setIndex:function(i){varcurClass=this.datamodel.curClass;i=parseInt(i);如果(i<0||i>this.datamodel.data.length||i==this.datamodel.index)返回;this.datamodel.index=i;</p><p>//这里不以datamodel改变引起整个dom变化了,不划算this。$('。cui-pop-listli')。removeClass(curClass);this。$('li[data-index=“'+i+'”]')。addClass(curClass);},</p><p>//位置定位reposition:
 
    varoffset=this.triggerEl.offset();varstep=6,w=offset.width-step;vartop=0,left=0,right;如果(this.datamodel.dir=='up'){top=(offset.top+offset.height+8)+'px';}else{top=(offset.top-this.el.offset()。height-8)+'px';}</p><p>left=(offset.left+2)+'px';</p><p>if((offset.left+(parseInt(this.width)||w))>this.windowWidth){this.el.css({width:this.width||w,top:top,right:'2px'});}else{this.el.css({width:this.width||w,
 
    左:左});}</p><p>if(this.triangleLeft){this.triangleEl.css({'left':this.triangleLeft,'right':'auto'});}if(this.triangleRight){this.triangleEl.css({'right':this.triangleRight,'left':'auto'});}},</p><p>addEvent:函数($super){$super();this.on('onCreate',function(){this。$el.removeClass('cui-layer');this。$el.css({position:'absolute'});});this.on('onShow',function(){this.setzIndexTop(this.el);});
 
    这里开始调用的,可以做简单实现:
 
    复制代码
 
    代码如下:
 
    'click.demo1':function(e){if(!this.demo1){vardata=[{name:'<spanclass=“center”>普通会员</span>'},{名称:'<spanclass=“center”>vip</span>'},{名称:'<spanclass=“center”>高级vip</span>'},{名称:'<spanclass=“center”>Diamondvip</span>'}];this.list=newUIBubbleLayer({datamodel:{data:data},triggerEl:$(e.currentTarget),width:'150px',triangleLeft:'20px'});}this.list.show();}
 
    稍作修改可以形成另一种样子:
 
    只不过我们还得考虑这个场景的发生,在项目过多过长时我们仍需要做处理:
 
    这里有很多办法可以处理,第一个是直接合并最大高度,如果高度超过的话便出现滚动条,第二个是动态在组件内部计算,查看组件与可视区域的关系
 
    我们这里还是采用可视区域计算吧,于是对原组件做一些改造,加一个接口:
 
    复制代码
 
    代码如下:
 
    this.checkHeightOverflow();
 
    就这一简单接口其实可分为几个初步的实现
 
    第一个接口为检测可视区域,这个可以被用户重写
 
    复制代码
 
    代码如下:
 
    isSizeOverflow
 
    第二个接口是如果可视区域超过,也就是第一个接口返回true时的处理逻辑
 
    复制代码
 
    代码如下:
 
    handleSizeOverflow
 
    考虑到过度的未必是高度,所以这里height替换了Size
 
    当然,这里会存在资源销毁的工作,所以会添加一个hide接口
 
    复制代码
 
    代码如下:
 
    isSizeOverflow:function(){if(!this.el)返回false;如果(this.el.height()>this.windowHeight*0.8)返回true;返回false;},</p><p>handleSizeOverflow:function(){if(!this.isSizeOverflow())return;</p><p>this.listWrapper.css({height:(parseInt(this.windowHeight*0.8)+'px'),溢出:'hidden',位置:'relative'});</p><p>this.listEl.css({position:'absolute',width:'100%'});</p><p>//调用前需要重置位置this.reposition();</p><p>this.scroll=newUIScroll({wrapper:this.listWrapper,scroller:this.listEl});},</p><p>
 
    },</p><p>addEvent:函数($super){$super();this.on('onCreate',function(){this。$el.removeClass('cui-layer');this。$el.css({position:'absolute'});});this.on('onShow',function(){</p><p>//检查可视区域是否可以通过;this.checkSizeOverflow();this.setzIndexTop(this.el);});this.on('onHide',function(){if(this.scroll)this.scroll.destroy();});}
 
    到此,我们的功能也基本结束了,最后实现一个定制化一点的功能,将我们的气泡组件变成黑色:
 
    结语
 
    今天的学习到此为止,因为小钗css3也算是初学,若是文中有误,请提出
 
    该组件的动画以来我准备做到Layer基类上,或者会介绍css3的动画技术,这里便不介绍了

如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h60965.shtml