日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
【HTML5&CSS3進階學(xué)習(xí)01】氣泡組件的實現(xiàn)

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

成都創(chuàng)新互聯(lián)服務(wù)項目包括神木網(wǎng)站建設(shè)、神木網(wǎng)站制作、神木網(wǎng)頁制作以及神木網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,神木網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到神木省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

我們這里所謂氣泡組件是指列表型氣泡組件,這里就其dom實現(xiàn),css實現(xiàn),js實現(xiàn)做一個討論,***對一些細節(jié)點做一些說明,希望對各位有用

小釵最近初學(xué)CSS,這里做一個專題,便于自身CSS提升,文章有不少問題與可優(yōu)化點,請各位指導(dǎo)

組件分類

單由氣泡組件來說,他仍然屬于“彈出層”類組件,也就是說其會具有這些特性:

① 布局為脫離文檔流

② 可以具有mask蒙版,并且可配置點擊蒙版是否關(guān)閉的特性

③ 可選的特性有點擊瀏覽器回退關(guān)閉組件以及動畫的顯示與隱藏動畫特性

其中比較不同的是:

① 不是居中定位

② 具有一個箭頭標識,并且可以設(shè)置再上或者在下

③ 因為具有箭頭,而且這個箭頭是相對于一個元素的,一般意義上我們?nèi)蝿?wù)是相對某個按鈕,所以說具有一個triggerEL

所以單從這里論述來說,我們的組件名為BubbleLayer,其應(yīng)該繼承與一個通用的Layer

但是,就由Layer來說,其最少會具有以下通用特性:

① 創(chuàng)建——create

② 顯示——show

③ 隱藏——hide

④ 摧毀——destroy

而以上特性并不是Layer組件所特有的,而是所有組件所特有,所以在Layer之上還應(yīng)該存在一個AbstractView的抽象組件

至此繼承關(guān)系便出來了,拋開多余的接口不看,簡單來說是這樣的:

#p#

組件dom層面實現(xiàn)

最簡單實現(xiàn)

單從dom實現(xiàn)來說,其實一個簡單的ul便可以完成任務(wù)

 
 
  1. 價格:¥35
  2. 評分:80
  3. 級別:5

當(dāng)然這里要有相關(guān)的css

 
 
  1. .cui-bubble-layer {
  2.     background: #f2f2f2;
  3.     border: #bcbcbc 1px solid;
  4.     border-radius: 3px
  5. }

至此形成的效果是醬紫滴:

 
 
  1.   
  2.   Blade Demo
  3.   
  4.   
  5.   
  6.   
  7.     body, button, input, select, textarea { font: 400 14px/1.5 Arial, "Lucida Grande" ,Verdana, "Microsoft YaHei" ,hei; }
  8.     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; }
  9.     body { background: #f5f5f5; }
  10.     ul, ol { list-style: none; }
  11.     
  12.     .cui-bubble-layer { background: #f2f2f2; border: #bcbcbc 1px solid; border-radius: 3px; }
  13.   
  14.   
  15.     價格:¥35
  16.     評分:80
  17.     級別:5
  18.   

這個時候在為其加一個偽類,做點樣式上的調(diào)整,便基本實現(xiàn)了,這里用到了偽類的知識點:

 
 
  1. cui-bubble-layer:before { 
  2. position: absolute; content: ""; width: 10px; height: 10px; -webkit-transform: rotate(45deg); 
  3. background: #f2f2f2; 
  4. border-top: #bcbcbc 1px solid; 
  5. border-left: #bcbcbc 1px solid; 
  6. top: -6px; left: 50%; margin-left: -5px; z-index: 1;
  7. }

這里設(shè)置了一個絕對定位的矩形框,為其兩個邊框設(shè)置了值,然后變形偏斜45度形成小三角,然后大家都知道了

 
 
  1.   
  2.   Blade Demo
  3.   
  4.   
  5.   
  6.   
  7.     body, button, input, select, textarea { font: 400 14px/1.5 Arial, "Lucida Grande" ,Verdana, "Microsoft YaHei" ,hei; }
  8.     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; }
  9.     body { background: #f5f5f5; }
  10.     ul, ol { list-style: none; }
  11.     
  12.     .cui-bubble-layer { background: #f2f2f2; border: #bcbcbc 1px solid; border-radius: 3px; }
  13.     .cui-bubble-layer > li { padding: 5px 10px; }
  14.     .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;
  15.   
  16.     價格:¥35
  17.     評分:80
  18.     級別:5
  19.   

http://sandbox.runjs.cn/show/9ywitfn8

不足與擴展

上面作為基本實現(xiàn),沒有什么問題,但是其實際應(yīng)用場景會有以下不足:

① 基本的ul層級需要一個包裹層,包裹層具有一個up或者down的class,然后在決定那個箭頭是向上還是向下

② 我們這里不能使用偽類,其原因是,我們的小三角標簽并不是一定在中間,其具有一定滑動的特性,也就是說,這個小三角需要被js控制其左右位置,他需要是一個標簽

根據(jù)以上所述,我們的結(jié)構(gòu)似乎應(yīng)該是這個樣子滴:

 
 
  1.   
  2.   
    •     價格:¥35
    •     評分:80
    •     級別:5
    •   

① 根元素上我們可以設(shè)置當(dāng)前應(yīng)該是up還是down的樣式

② i標簽根據(jù)根元素的up或者down選擇是向上還是向下,并且該標簽可被js操作

到此,似乎整個組件便比較完全了,但是真實的情況卻不是如此,怎么說了,上面的結(jié)構(gòu)太局限了

該組件需要一個容器,這個容器標簽應(yīng)該位于ul之上,這個時候容器內(nèi)部所裝載的dom結(jié)構(gòu)便可以不是ul而是其他什么結(jié)構(gòu)了

其次,在手機上,我們可視項目在4S手機上不會超過5個,往往是4個,所以我們應(yīng)該在其容器上設(shè)置類似overflow之類的可滾動屬性

組件回歸·最終結(jié)構(gòu)

由上所述,基于其是繼承至Layer的事實,我們可以形成這樣的結(jié)構(gòu):

 
 
  1.   
  2.   
  3.   
  •   
  •     
    •       價格:¥35
    •       評分:80
    •       級別:5
    •     
  •   
  •   
  •   
  • 這個也可以是我們整個彈出層類的基本結(jié)構(gòu),我們可以在此上做很多擴展,但是這里我們不扯太多,單就氣泡組件做論述

    就氣泡組件,其結(jié)構(gòu)是:

     
     
    1.   
    2.   
    3.     
      •       價格:¥35
      •       評分:80
      •       級別:5
      •     
    4.   
  • #p#

    js層面的實現(xiàn)

    這里仍然是采用的blade中的那一套繼承機制,如果有不明白又有點興趣的同學(xué)請移步:【blade的UI設(shè)計】理解前端MVC與分層思想

    關(guān)于模板

    因為我們這一部分的主題為重構(gòu)相關(guān),所以我們這里的關(guān)注點是CSS,我們首先生成我們的模板:

     
     
    1.  <%if(dir == 'up'){ %> <%=upClass %> <% } else { %> <%=downClass %> <% } %>">
    2.   
    3.   
    4.     ">
    5.     <% for(var i = 0, len = data.length; i < len; i++) { %>
    6.       <% var itemData = data[i]; %>
    7.       " data-flag="c" class="<% if(index == i){ %><%=curClass %><%} %>" >
    8.         <%if(typeof itemFn == 'function') { %><%=itemFn.call(itemData) %> <% } else { %><%=itemData.name%><%} %>
    9.     <% } %>
    10.     
    11.   
  • 這里給出了幾個關(guān)鍵的定制化點:

    ① wrapperClass用以添加業(yè)務(wù)團隊定制化的class以改變根元素的class,如此的好處是便于業(yè)務(wù)團隊定制化氣泡組件的樣式

    ② 給出了項目列表Ul的可定制化className,通用單單只是方便業(yè)務(wù)團隊做樣式改變

    ③ 默認情況下返回的是傳入項目的name字段,但是用戶可傳入一個itemFn的回調(diào),定制化返回

    以上模板基本可滿足條件,如果不滿足,便可把整個模板作為參數(shù)傳入了

    關(guān)于js實現(xiàn)

    由于繼承的實現(xiàn),我們大部分工作已經(jīng)被做了,我們只需要在幾個關(guān)鍵地方編寫代碼即可

     
     
    1. define(['UILayer', getAppUITemplatePath('ui.bubble.layer')], function (UILayer, template) {
    2.   return _.inherit(UILayer, {
    3.     propertys: function ($super) {
    4.       $super();
    5.       //html模板
    6.       this.template = template;
    7.       this.needMask = false;
    8.       this.datamodel = {
    9.         data: [],
    10.         wrapperClass: 'cui-bubble-layer',
    11.         upClass: 'cui-pop--triangle-up',
    12.         downClass: 'cui-pop--triangle-down',
    13.         curClass: 'active',
    14.         itemStyleClass: '',
    15.         needBorder: true,
    16.         index: -1,
    17.         dir: 'up'  //箭頭方向默認值
    18.       };
    19.       this.events = {
    20.         'click .cui-pop-list>li': 'clickAction'
    21.       };
    22.       this.onClick = function (data, index, el, e) {
    23.         console.log(arguments);
    24. //        this.setIndex(index);
    25.       };
    26.       this.width = null;
    27.       //三角圖標偏移量
    28.       this.triangleLeft = null;
    29.       this.triangleRight = null;
    30.       this.triggerEl = null;
    31.     },
    32.     initialize: function ($super, opts) {
    33.       $super(opts);
    34.     },
    35.     createRoot: function (html) {
    36.       this.$el = $(html).hide().attr('id', this.id);
    37.     },
    38.     clickAction: function (e) {
    39.       var el = $(e.currentTarget);
    40.       var i = el.attr('data-index');
    41.       var data = this.datamodel.data[i];
    42.       this.onClick.call(this, data, i, el, e);
    43.     },
    44.     initElement: function () {
    45.       this.el = this.$el;
    46.       this.triangleEl = this.$('.cui-pop-triangle');
    47.       this.windowWidth = $(window).width();
    48.     },
    49.     setIndex: function (i) {
    50.       var curClass = this.datamodel.curClass;
    51.       i = parseInt(i);
    52.       if (i < 0 || i > this.datamodel.data.length || i == this.datamodel.index) return;
    53.       this.datamodel.index = i;
    54.       //這里不以datamodel改變引起整個dom變化了,不劃算
    55.       this.$('.cui-pop-list li').removeClass(curClass);
    56.       this.$('li[data-index="' + i + '"]').addClass(curClass);
    57.     },
    58.     //位置定位
    59.     reposition: function () {
    60.       if (!this.triggerEl) return;
    61.       var offset = this.triggerEl.offset();
    62.       var step = 6, w = offset.width - step;
    63.       var top = 0, left = 0, right;
    64.       if (this.datamodel.dir == 'up') {
    65.         top = (offset.top + offset.height + 8) + 'px';
    66.       } else {
    67.         top = (offset.top - this.el.offset().height - 8) + 'px';
    68.       }
    69.       left = (offset.left + 2) + 'px';
    70.       if (offset.left + (parseInt(this.width) || w) > this.windowWidth) {
    71.         this.el.css({
    72.           width: this.width || w,
    73.           top: top,
    74.           right: '2px'
    75.         });
    76.       } else {
    77.         this.el.css({
    78.           width: this.width || w,
    79.           top: top,
    80.           left: left
    81.         });
    82.       }
    83.       if (this.triangleLeft) {
    84.         this.triangleEl.css({ 'left': this.triangleLeft, 'right': 'auto' });
    85.       }
    86.       if (this.triangleRight) {
    87.         this.triangleEl.css({ 'right': this.triangleRight, 'left': 'auto' });
    88.       }
    89.     },
    90.     addEvent: function ($super) {
    91.       $super();
    92.       this.on('onCreate', function () {
    93.         this.$el.removeClass('cui-layer');
    94.         this.$el.css({ position: 'absolute' });
    95.       });
    96.       this.on('onShow', function () {
    97.         this.setzIndexTop(this.el);
    98.       });
    99.     }
    100.   });
    101. });

    這里開始調(diào)用的,便可做簡單實現(xiàn):

     
     
    1. 'click .demo1': function (e) {
    2.   if (!this.demo1) {
    3.     var data = [{ name: '普通會員' },
    4.     { name: 'vip' },
    5.     { name: '高級vip' },
    6.     { name: '鉆石vip'}];
    7.     this.list = new UIBubbleLayer({
    8.       datamodel: {
    9.         data: data
    10.       },
    11.       triggerEl: $(e.currentTarget),
    12.       width: '150px',
    13.       triangleLeft: '20px'
    14.     });
    15.   }
    16.   this.list.show();
    17. }

    稍作修改便可形成另一種樣子:

    只不過我們還得考慮這個場景的發(fā)生,在項目過多過長時我們?nèi)孕枰鎏幚恚?/p>

    這里有很多辦法可以處理,***個是直接傳入maxHeight,如果高度超出的話便出現(xiàn)滾動條,第二個是動態(tài)在組件內(nèi)部計算,查看組件與可視區(qū)域的關(guān)系

    我們這里還是采用可視區(qū)域計算吧,于是對原組件做一些改造,加一個接口:

      
     
    1. this.checkHeightOverflow();

    就這一簡單接口其實可分為幾個段落的實現(xiàn)

    ***個接口為檢測可視區(qū)域,這個可以被用戶重寫

      
     
    1. isSizeOverflow

    第二個接口是如果可視區(qū)域超出,也就是***個接口返回true時的處理邏輯

      
     
    1. handleSizeOverflow

    考慮到超出的未必是高度,所以這里height改為了Size

    當(dāng)然,這里會存在資源銷毀的工作,所以會新增一個hide接口

      
     
    1. isSizeOverflow: function () {
    2.   if (!this.el) return false;
    3.   if (this.el.height() > this.windowHeight * 0.8) return true;
    4.   return false;
    5. },
    6. handleSizeOverflow: function () {
    7.   if (!this.isSizeOverflow()) return;
    8.   this.listWrapper.css({
    9.     height: (parseInt(this.windowHeight * 0.8) + 'px'),
    10.     overflow: 'hidden',
    11.     position: 'relative'
    12.   });
    13.   this.listEl.css({ position: 'absolute', width: '100%' });
    14.   //調(diào)用前需要重置位置
    15.   this.reposition();
    16.   this.scroll = new UIScroll({
    17.     wrapper: this.listWrapper,
    18.     scroller: this.listEl
    19.   });
    20. },
    21. checkSizeOverflow: function () {
    22.   this.handleSizeOverflow();
    23. },
    24. addEvent: function ($super) {
    25.   $super();
    26.   this.on('onCreate', function () {
    27.     this.$el.removeClass('cui-layer');
    28.     this.$el.css({ position: 'absolute' });
    29.   });
    30.   this.on('onShow', function () {
    31.     //檢查可視區(qū)域是否超出;
    32.     this.checkSizeOverflow();
    33.     this.setzIndexTop(this.el);
    34.   });
    35.   this.on('onHide', function () {
    36.     if (this.scroll) this.scroll.destroy();
    37.   });
    38. }

    到此,我們的功能也基本結(jié)束了,***實現(xiàn)一個定制化一點的功能,將我們的氣泡組件變成黑色:

    結(jié)語

    今天的學(xué)習(xí)到此為止,因為小釵css也算是初學(xué),若是文中有誤,請?zhí)岢?/p>

    該組件的動畫以來我準備做到Layer基類上,而是會介紹css3的動畫技術(shù),這里便不介紹了

    下一期,我們就mobile的整體布局,以及header組件的實現(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進階學(xué)習(xí)01】氣泡組件的實現(xiàn)
    當(dāng)前地址:http://www.dlmjj.cn/article/cdocgie.html