新聞中心
氣泡組件在實(shí)際工作中非常普遍,無論是網(wǎng)頁中還是app中,比如:

成都創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括神木網(wǎng)站建設(shè)、神木網(wǎng)站制作、神木網(wǎng)頁制作以及神木網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,神木網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到神木省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
我們這里所謂氣泡組件是指列表型氣泡組件,這里就其dom實(shí)現(xiàn),css實(shí)現(xiàn),js實(shí)現(xiàn)做一個(gè)討論,***對一些細(xì)節(jié)點(diǎn)做一些說明,希望對各位有用
小釵最近初學(xué)CSS,這里做一個(gè)專題,便于自身CSS提升,文章有不少問題與可優(yōu)化點(diǎn),請各位指導(dǎo)
組件分類
單由氣泡組件來說,他仍然屬于“彈出層”類組件,也就是說其會具有這些特性:
① 布局為脫離文檔流
② 可以具有mask蒙版,并且可配置點(diǎn)擊蒙版是否關(guān)閉的特性
③ 可選的特性有點(diǎn)擊瀏覽器回退關(guān)閉組件以及動(dòng)畫的顯示與隱藏動(dòng)畫特性
其中比較不同的是:
① 不是居中定位
② 具有一個(gè)箭頭標(biāo)識,并且可以設(shè)置再上或者在下
③ 因?yàn)榫哂屑^,而且這個(gè)箭頭是相對于一個(gè)元素的,一般意義上我們?nèi)蝿?wù)是相對某個(gè)按鈕,所以說具有一個(gè)triggerEL
所以單從這里論述來說,我們的組件名為BubbleLayer,其應(yīng)該繼承與一個(gè)通用的Layer
但是,就由Layer來說,其最少會具有以下通用特性:
① 創(chuàng)建——create
② 顯示——show
③ 隱藏——hide
④ 摧毀——destroy
而以上特性并不是Layer組件所特有的,而是所有組件所特有,所以在Layer之上還應(yīng)該存在一個(gè)AbstractView的抽象組件
至此繼承關(guān)系便出來了,拋開多余的接口不看,簡單來說是這樣的:
#p#
組件dom層面實(shí)現(xiàn)
最簡單實(shí)現(xiàn)
單從dom實(shí)現(xiàn)來說,其實(shí)一個(gè)簡單的ul便可以完成任務(wù)
- 價(jià)格:¥35
- 評分:80
- 級別:5
當(dāng)然這里要有相關(guān)的css
- .cui-bubble-layer {
- background: #f2f2f2;
- border: #bcbcbc 1px solid;
- border-radius: 3px
- }
至此形成的效果是醬紫滴:
Blade Demo - body, button, input, select, textarea { font: 400 14px/1.5 Arial, "Lucida Grande" ,Verdana, "Microsoft YaHei" ,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: #bcbcbc 1px solid; border-radius: 3px; }
- 價(jià)格:¥35
- 評分:80
- 級別:5
這個(gè)時(shí)候在為其加一個(gè)偽類,做點(diǎn)樣式上的調(diào)整,便基本實(shí)現(xiàn)了,這里用到了偽類的知識點(diǎn):
- cui-bubble-layer:before {
- position: absolute; content: ""; width: 10px; height: 10px; -webkit-transform: rotate(45deg);
- background: #f2f2f2;
- border-top: #bcbcbc 1px solid;
- border-left: #bcbcbc 1px solid;
- top: -6px; left: 50%; margin-left: -5px; z-index: 1;
- }
這里設(shè)置了一個(gè)絕對定位的矩形框,為其兩個(gè)邊框設(shè)置了值,然后變形偏斜45度形成小三角,然后大家都知道了
Blade Demo - body, button, input, select, textarea { font: 400 14px/1.5 Arial, "Lucida Grande" ,Verdana, "Microsoft YaHei" ,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: #bcbcbc 1px solid; border-radius: 3px; }
- .cui-bubble-layer > li { padding: 5px 10px; }
- .cui-bubble-layer:before { position: absolute; content: ""; width: 10px; height: 10px; -webkit-transform: rotate(45deg); background: #f2f2f2; border-top: #bcbcbc 1px solid; border-left: #bcbcbc 1px solid; top: -6px; left: 50%; margin-left: -5px; z-index: 1;
- 價(jià)格:¥35
- 評分:80
- 級別:5
http://sandbox.runjs.cn/show/9ywitfn8
不足與擴(kuò)展
上面作為基本實(shí)現(xiàn),沒有什么問題,但是其實(shí)際應(yīng)用場景會有以下不足:
① 基本的ul層級需要一個(gè)包裹層,包裹層具有一個(gè)up或者down的class,然后在決定那個(gè)箭頭是向上還是向下
② 我們這里不能使用偽類,其原因是,我們的小三角標(biāo)簽并不是一定在中間,其具有一定滑動(dòng)的特性,也就是說,這個(gè)小三角需要被js控制其左右位置,他需要是一個(gè)標(biāo)簽
根據(jù)以上所述,我們的結(jié)構(gòu)似乎應(yīng)該是這個(gè)樣子滴:
- 價(jià)格:¥35
- 評分:80
- 級別:5
① 根元素上我們可以設(shè)置當(dāng)前應(yīng)該是up還是down的樣式
② i標(biāo)簽根據(jù)根元素的up或者down選擇是向上還是向下,并且該標(biāo)簽可被js操作
到此,似乎整個(gè)組件便比較完全了,但是真實(shí)的情況卻不是如此,怎么說了,上面的結(jié)構(gòu)太局限了
該組件需要一個(gè)容器,這個(gè)容器標(biāo)簽應(yīng)該位于ul之上,這個(gè)時(shí)候容器內(nèi)部所裝載的dom結(jié)構(gòu)便可以不是ul而是其他什么結(jié)構(gòu)了
其次,在手機(jī)上,我們可視項(xiàng)目在4S手機(jī)上不會超過5個(gè),往往是4個(gè),所以我們應(yīng)該在其容器上設(shè)置類似overflow之類的可滾動(dòng)屬性
組件回歸·最終結(jié)構(gòu)
由上所述,基于其是繼承至Layer的事實(shí),我們可以形成這樣的結(jié)構(gòu):
- 價(jià)格:¥35
- 評分:80
- 級別:5
這個(gè)也可以是我們整個(gè)彈出層類的基本結(jié)構(gòu),我們可以在此上做很多擴(kuò)展,但是這里我們不扯太多,單就氣泡組件做論述
就氣泡組件,其結(jié)構(gòu)是:
- 價(jià)格:¥35
- 評分:80
- 級別:5
#p#
js層面的實(shí)現(xiàn)
這里仍然是采用的blade中的那一套繼承機(jī)制,如果有不明白又有點(diǎn)興趣的同學(xué)請移步:【blade的UI設(shè)計(jì)】理解前端MVC與分層思想
關(guān)于模板
因?yàn)槲覀冞@一部分的主題為重構(gòu)相關(guān),所以我們這里的關(guān)注點(diǎn)是CSS,我們首先生成我們的模板:
<%if(dir == 'up'){ %> <%=upClass %> <% } else { %> <%=downClass %> <% } %>"> ">
- <% for(var i = 0, len = data.length; i < len; i++) { %>
- <% var itemData = data[i]; %>
- " data-flag="c" class="<% if(index == i){ %><%=curClass %><%} %>" >
- <%if(typeof itemFn == 'function') { %><%=itemFn.call(itemData) %> <% } else { %><%=itemData.name%><%} %>
- <% } %>
這里給出了幾個(gè)關(guān)鍵的定制化點(diǎn):
① wrapperClass用以添加業(yè)務(wù)團(tuán)隊(duì)定制化的class以改變根元素的class,如此的好處是便于業(yè)務(wù)團(tuán)隊(duì)定制化氣泡組件的樣式
② 給出了項(xiàng)目列表Ul的可定制化className,通用單單只是方便業(yè)務(wù)團(tuán)隊(duì)做樣式改變
③ 默認(rèn)情況下返回的是傳入項(xiàng)目的name字段,但是用戶可傳入一個(gè)itemFn的回調(diào),定制化返回
以上模板基本可滿足條件,如果不滿足,便可把整個(gè)模板作為參數(shù)傳入了
關(guān)于js實(shí)現(xiàn)
由于繼承的實(shí)現(xiàn),我們大部分工作已經(jīng)被做了,我們只需要在幾個(gè)關(guān)鍵地方編寫代碼即可
- define(['UILayer', getAppUITemplatePath('ui.bubble.layer')], function (UILayer, template) {
- return _.inherit(UILayer, {
- propertys: function ($super) {
- $super();
- //html模板
- this.template = template;
- this.needMask = false;
- this.datamodel = {
- data: [],
- wrapperClass: 'cui-bubble-layer',
- upClass: 'cui-pop--triangle-up',
- downClass: 'cui-pop--triangle-down',
- curClass: 'active',
- itemStyleClass: '',
- needBorder: true,
- index: -1,
- dir: 'up' //箭頭方向默認(rèn)值
- };
- this.events = {
- 'click .cui-pop-list>li': 'clickAction'
- };
- this.onClick = function (data, index, el, e) {
- console.log(arguments);
- // this.setIndex(index);
- };
- this.width = null;
- //三角圖標(biāo)偏移量
- this.triangleLeft = null;
- this.triangleRight = null;
- this.triggerEl = null;
- },
- initialize: function ($super, opts) {
- $super(opts);
- },
- createRoot: function (html) {
- this.$el = $(html).hide().attr('id', this.id);
- },
- clickAction: function (e) {
- var el = $(e.currentTarget);
- var i = el.attr('data-index');
- var data = this.datamodel.data[i];
- this.onClick.call(this, data, i, el, e);
- },
- initElement: function () {
- this.el = this.$el;
- this.triangleEl = this.$('.cui-pop-triangle');
- this.windowWidth = $(window).width();
- },
- setIndex: function (i) {
- var curClass = this.datamodel.curClass;
- i = parseInt(i);
- if (i < 0 || i > this.datamodel.data.length || i == this.datamodel.index) return;
- this.datamodel.index = i;
- //這里不以datamodel改變引起整個(gè)dom變化了,不劃算
- this.$('.cui-pop-list li').removeClass(curClass);
- this.$('li[data-index="' + i + '"]').addClass(curClass);
- },
- //位置定位
- reposition: function () {
- if (!this.triggerEl) return;
- var offset = this.triggerEl.offset();
- var step = 6, w = offset.width - step;
- var top = 0, left = 0, right;
- if (this.datamodel.dir == 'up') {
- top = (offset.top + offset.height + 8) + 'px';
- } else {
- top = (offset.top - this.el.offset().height - 8) + 'px';
- }
- left = (offset.left + 2) + 'px';
- 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,
- top: top,
- left: left
- });
- }
- if (this.triangleLeft) {
- this.triangleEl.css({ 'left': this.triangleLeft, 'right': 'auto' });
- }
- if (this.triangleRight) {
- this.triangleEl.css({ 'right': this.triangleRight, 'left': 'auto' });
- }
- },
- addEvent: function ($super) {
- $super();
- this.on('onCreate', function () {
- this.$el.removeClass('cui-layer');
- this.$el.css({ position: 'absolute' });
- });
- this.on('onShow', function () {
- this.setzIndexTop(this.el);
- });
- }
- });
- });
這里開始調(diào)用的,便可做簡單實(shí)現(xiàn):
- 'click .demo1': function (e) {
- if (!this.demo1) {
- var data = [{ name: '普通會員' },
- { name: 'vip' },
- { name: '高級vip' },
- { name: '鉆石vip'}];
- this.list = new UIBubbleLayer({
- datamodel: {
- data: data
- },
- triggerEl: $(e.currentTarget),
- width: '150px',
- triangleLeft: '20px'
- });
- }
- this.list.show();
- }
稍作修改便可形成另一種樣子:
只不過我們還得考慮這個(gè)場景的發(fā)生,在項(xiàng)目過多過長時(shí)我們?nèi)孕枰鎏幚恚?/p>
這里有很多辦法可以處理,***個(gè)是直接傳入maxHeight,如果高度超出的話便出現(xiàn)滾動(dòng)條,第二個(gè)是動(dòng)態(tài)在組件內(nèi)部計(jì)算,查看組件與可視區(qū)域的關(guān)系
我們這里還是采用可視區(qū)域計(jì)算吧,于是對原組件做一些改造,加一個(gè)接口:
- this.checkHeightOverflow();
就這一簡單接口其實(shí)可分為幾個(gè)段落的實(shí)現(xiàn)
***個(gè)接口為檢測可視區(qū)域,這個(gè)可以被用戶重寫
- isSizeOverflow
第二個(gè)接口是如果可視區(qū)域超出,也就是***個(gè)接口返回true時(shí)的處理邏輯
- handleSizeOverflow
考慮到超出的未必是高度,所以這里height改為了Size
當(dāng)然,這里會存在資源銷毀的工作,所以會新增一個(gè)hide接口
- isSizeOverflow: function () {
- if (!this.el) return false;
- if (this.el.height() > this.windowHeight * 0.8) return true;
- return false;
- },
- handleSizeOverflow: function () {
- if (!this.isSizeOverflow()) return;
- this.listWrapper.css({
- height: (parseInt(this.windowHeight * 0.8) + 'px'),
- overflow: 'hidden',
- position: 'relative'
- });
- this.listEl.css({ position: 'absolute', width: '100%' });
- //調(diào)用前需要重置位置
- this.reposition();
- this.scroll = new UIScroll({
- wrapper: this.listWrapper,
- scroller: this.listEl
- });
- },
- checkSizeOverflow: function () {
- this.handleSizeOverflow();
- },
- addEvent: function ($super) {
- $super();
- this.on('onCreate', function () {
- this.$el.removeClass('cui-layer');
- this.$el.css({ position: 'absolute' });
- });
- this.on('onShow', function () {
- //檢查可視區(qū)域是否超出;
- this.checkSizeOverflow();
- this.setzIndexTop(this.el);
- });
- this.on('onHide', function () {
- if (this.scroll) this.scroll.destroy();
- });
- }
到此,我們的功能也基本結(jié)束了,***實(shí)現(xiàn)一個(gè)定制化一點(diǎn)的功能,將我們的氣泡組件變成黑色:
結(jié)語
今天的學(xué)習(xí)到此為止,因?yàn)樾♀Ocss也算是初學(xué),若是文中有誤,請?zhí)岢?/p>
該組件的動(dòng)畫以來我準(zhǔn)備做到Layer基類上,而是會介紹css3的動(dòng)畫技術(shù),這里便不介紹了
下一期,我們就mobile的整體布局,以及header組件的實(shí)現(xiàn)做說明學(xué)習(xí)
代碼地址:https://github.com/yexiaochai/cssui/tree/gh-pages
demo地址:http://yexiaochai.github.io/cssui/demo/debug.html#bubble.layer
本文名稱:【HTML5&CSS3進(jìn)階學(xué)習(xí)01】氣泡組件的實(shí)現(xiàn)
鏈接URL:http://m.fisionsoft.com.cn/article/cdocgie.html


咨詢
建站咨詢
