<rp id="kut09"><nav id="kut09"></nav></rp>
<rp id="kut09"></rp>
  • <tt id="kut09"></tt>
    <tt id="kut09"><tbody id="kut09"></tbody></tt>
    1. <u id="kut09"></u>
    2. <tt id="kut09"><noscript id="kut09"></noscript></tt>
    3. html5+css3之制作header實例與更新

        發布時間:2020-12-21 15:40:04   作者:佚名   我要評論
      本文主要記錄了使用CSS3的float布局制作header的過程,從最初的結構到最后的定稿的全部記錄以及修改過程,十分的詳細,給需要的小伙伴參考下

      上次,我們形成了兩種header的布局,一種flexbox,一種float,最后與身邊做重構的同事交流下來,選擇了float的布局。

      事實上布局的選型不需要我關注,我的參與或者一些意見多數是自我提升,但要說html結構完全控制于csser的話就不一定了

      在整個header組件的代碼過程中,我與重構同事就一些地方發生了重復的交流,爭論,今天就header組件的布局以及功能實現,聊一聊js與css的配合

      然后header組件本身是一個老組件,我們順便探討下,這類老組件應該如何翻新比較合適。

      最初的結構

      最開始重構的同事給了我一個已經做好了的頁面:

       

      我們針對其中一些小的體驗上做了討論,并且知會到設計組,便改了,很順暢,然后我開始了愉快的代碼,這是其中一塊HTML的結構:

       <header class="cm-header" style="top: 50px;">
         <span class="fl cm-header-icon icon-back "></span>
         <span class="fr cm-header-btn">確認</span>
         <span class="fr cm-header-icon"><i class="icon-home"></i></span>
         <span class="fr cm-header-icon"><i class="icond-list"></i></span>
         <h1 class="cm-page-title">
           頁面標題</h1>
       </header>

      這里除去h1標簽中的文字不說,因為其中可能表現的非常復雜,我們后面再說,其中的按鈕有以下功能:

      ① 第二行:回退按鈕 
      ② 第三行:確認

      PS:左邊采用float布局所以第一個元素在最右邊

      ③ 第四行:home標簽 
      ④ 第五行:三個點,點擊會出一個側邊欄

      以上便是HTML的實現,但是對與程序員來說,頭部除了按鈕(btn)以外就只有圖標(icon),所以以上的結構事實上js一般是不買賬的

      Jser需要的結構

      與重構同事交流下來,原因是這樣的:

      ① 因為回退比較特殊,所以多了一個樣式,具體什么我沒記住了 
      ② icon代表背景圖,icond代表CSS3畫的,CSS3畫的可擴展性高,比如換顏色什么的 
      ③ ......

      當時雙方的討論還是比較激烈的,但是對icond全部變成icon,重構同事不同意,于是也就作罷,經過一輪討論,結構變成了這樣:

      <header class="cm-header" style="top: 50px;">
         <span class="fl cm-header-icon"><i class="icon-back"></i></span>
         <span class="fr cm-header-btn">確認</span>
         <span class="fr cm-header-icon"><i class="icon-home"></i></span>
         <span class="fr cm-header-icon"><i class="icond-list"></i></span>
         <h1 class="cm-page-title">
           頁面標題</h1>
       </header>

      做了很小的變化,將back的結構與其它icon類型按鈕做了統一,于是我開始了愉快的代碼

      PS:注意,icond與icon類型的標簽會不同程度的在header處出現,無法控制

      結構的問題

      因為公司的header一直便存在,我做的過程中必須考慮到兩個方面的問題:

      ① 方便擴展但是要做到接口兼容 
      ② 需要通過各個標簽的tagname與Hybrid進行聯調

      也就是說,每個標簽叫什么名字,是已經定死了的,甚至一些標簽的回調也被限制了,我這里的數據結構大概如下:

       {
       left: [],
       center: [],
       right: [
         {
           'tagname': 'home', callback: function () {
             console.log('返回');
           }
         },
         { 'tagname': 'search' },
         {
           'tagname': 'list', callback: function (e) {
              //......
           }
         },
         { 'tagname': 'tel', 'number': '56973144' },
         {
           'tagname': 'commit', 'value': '登錄', callback: function () {
             console.log('登錄');
           }
         },
         {
           'tagname': 'custom', 'value': '定制化',
           itemFn: function () {
             return '<span class="cm-header-btn fr js_custom">定制化</span>';
           },
           callback: function () {
             console.log('定制化');
           }
         }
      

      可以看到,一個tagname一個按鈕,而現在問題來了:我們并不知道某個tagname應該是icon或者是icond 

      但是根據是否存在value字段,我們是可以判斷其是否應該具有i子標簽,這個時候我們是怎么解決的呢?

      建立tagname與classname的映射關系,比如:

       var map = {
         'home': 'icon',
         'list': 'icond'
       }

      當然,這種做法,自然十分讓人感到難受,如果小圖標統一為icon,我在模板中可以統一如此代碼:

       <span class="cm-header-icon <%=dir %>  js_<%=item.tagname %>" >
         <% if(item.value) { %>
           <%=item.value %>
         <% } else { %>
           <i class="icon-<%=item.tagname %>"></i>
         <% } %>
       </span>

      但是由于多了一個映射關系,我的代碼便不好看了,并且業務邏輯還變得復雜了起來,于是帶著這些考量再次找到了重構同事,重構同事也很明事理,馬上答應改了:

       <header class="cm-header" style="top: 50px;">
         <span class="fl cm-header-icon"><i class="icon-back"></i></span>
         <span class="fr cm-header-btn">確認</span>
         <span class="fr cm-header-icon"><i class="icon-home"></i></span>
         <span class="fr cm-header-icon"><i class="icon-list"></i></span>
         <h1 class="cm-page-title">
           頁面標題</h1>
       </header> 
      

      不考慮h1中的樣式的話,搞定上面的代碼,對我們來說,真的是太簡單了啊!!!

       <header class="cm-header">
       <%
       var i = 0, len = 0, j = 0, keyagain = 0;
       var left = left;
       var right =  right.reverse();
       var item = null;
       var dir;
       var btnObj = null;
       %>
       <%for(keyagain=0; keyagain < 2; keyagain++) { %>
         <% 
           if(keyagain == 0) { dir = 'fl'; btnObj = left; } else { dir = 'fr'; btnObj = right; }
         %>
         <% for(i = 0, len = btnObj.length; i < len; i++) { %>
           <% item = btnObj[i]; %>
           <%if(typeof item.itemFn == 'function') { %>
             <%=item.itemFn() %>
           <%} else { %>
             <span class="cm-header-icon <%=dir %>  js_<%=item.tagname %>" >
               <% if(item.value) { %>
                 <%=item.value %>
               <% } else { %>
                 <i class="icon-<%=item.tagname %>"></i>
               <% } %>
             </span>
           <%} %>
         <%} %>
       <%} %>
       </header> 
      

      PS:從代碼著色來看,js中用到的left與Right是關鍵字,這個得處理...

      定制化需求

      可以看到,一個循環,我們便可以輕易的生成左邊和右邊的按鈕,但是馬上問題來了,我們需要擴展怎么辦,上面就會有以下問題: 

      ① tel標簽默認是a標簽,我們這里卻是span標簽

      <a href="tel:56973144" class="cm-header-btn fr js_tel "><i class="icon-tel"></i></a>

      ② back按鈕我們一般會做成a標簽,用以解決javascript出錯在Hybrid的假死問題

      說白了,就是雖然標簽按鈕應該有統一的結構,但是需要保留定制化的能力 
      這里定制化的工作交給了各個標簽的itemFn這個函數,他返回一個字符串,并且具有一定規則,這里取一個代碼片段:

       handleSpecialParam: function (data) {
         var k, i, len, item;
         for (k in data) {
           if (_.isArray(data[k])) {
             for (i = 0, len = data[k].length; i < len; i++) {
               item = data[k][i];
               if (this['customtHandle_' + item.tagname]) {
                 this['customtHandle_' + item.tagname](data[k][i], k);
               } //if
             } //for
           } //if
         } //for
       },
       
       _getDir: function (dir) {
         var kv = { left: 'fl', right: 'fr' };
         return kv[dir];
       },
       
       //處理back的按鈕邏輯
       customtHandle_back: function (item, dir) {
         dir = this._getDir(dir);
         item.itemFn = function () {
           var str = '<a href="http://m.ctrip.com/html5/" class="cm-header-btn ' + dir + ' js_' + item.tagname + ' " >';
           if (item.value) {
             str += item.value + '</a>';
           } else {
             str += '<i class="icon-' + item.tagname + '"></i></a>';
           }
           return str;
         };
       }, 
      

      當發現某個按鈕不滿足需求或者有定制化需求時,便想辦法設置其itemFn即可,時候上這個代碼可以直接寫到初始化的json串去

      花樣百出的title

      到title時,發現其表現便五花八門了,這個時候一般是根據不同的類型生成不同的HTML結構,框架給默認的幾個選項,不支持便自己定制itemFn

       <% item = center; %>
       <%if(typeof item.itemFn == 'function') { %>
         <%=item.itemFn() %>
       <%} else if(item.tagname=='title' ||  item.tagname=='subtitle') { %>
         <h1 class="cm-page-title js_<%=item.tagname %>" >
           <%if(typeof(item.value) == 'object' && item.title.value == 2) { %>
             <span class="cm-title-l"><%=item.value[0]%></span>
             <span class="cm-title-s"><%=item.value[1]%></span>
           <%} else { %>
             <%=item.value %>
           <%} %>
         </h1>
       <%} else if(item.tagname=='select'){ %>
         <h1 class="cm-page-select-title js_<%=item.tagname %>" >
           <%=item.value %>
         </h1>
       <%} else if(item.tagname=='tabs') { %>
         <h1 class="cm-page-tabs-title js_<%=item.tagname %>" >
           <%for(j = 0; j < item.data.items.length; j ++) { %>
             <span data-key="<%=item.data.items[j].id %>" class="<%if(item.data.index===j){ %>active<%} %>" ><%=item.data.items[j].name %></span>
           <% } %>
         </h1>
       <% } else{ %>
       
       <%} %> 
      

      事件綁定的實現

      header組件本身繼承至Abstract.View這個類,所以只要設置

      this.events = {}

      便能以事件代理的方式將事件綁定至根元素,而header的事件一般就是click事件: 

       setEventsParam: function () {
         var item, data = this.datamodel.left.concat(this.datamodel.right).concat(this.datamodel.center);
       
         for (var i = 0, len = data.length; i < len; i++) {
           item = data[i];
           if (_.isFunction(item.callback)) {
             this.events['click .js_' + item.tagname] = $.proxy(item.callback, this.viewScope);
           }
         }
       }, 
      

      這里有一個需要注意的點便是,事件綁定的鉤子便是我們的tagname,這個是唯一的,我們會為每個標簽動態生成“.js_tagname”的類,以方便事件綁定

      老接口的兼容

      之前便說了,該組件是一個老組件的翻新,于是各個業務團隊已經使用了,比如原來是這樣調用的:

       this.header.set({
         title: '基本Header使用',
         subtitle: '中間副標題',
         back: true,
         backtext: '取消',
         tel: { number: 1111 },
         home: true,
         search: true,
         btn: { title: "登錄", id: 'confirmBtn', classname: 'header_r' },
         events: {
           returnHandler: function () {
             console.log('back');
           },
           homeHandler: function (e) {
           }
         }
       }); 
      

      而現在我們期望的調用方式是這樣的:

      this.header.set({
        left: [],
        center: {},
        right: [
          { tagname: 'home', callback: function () { } },
          { tagname: 'tagname', value: 'value', data: {}, itemFn: function(){}, callback: function () { } }
        ]
      }); 
      

      這個時候我們應該怎么做呢?當然是不破不立,先破后立,當然是要求業務團隊改!!!然后被無情的噴了回來,于是做了接口兼容 
      翻新老組件,接口兼容是必須的,如果不是底層機制發生顛覆,而顛覆可以帶來顛覆性的成績,接口還是不建議改! 
      這里上面便是新接口的調用,下面是老接口的調用,效果如下:

       

      到此這篇關于html5+css3之制作header實例與更新的文章就介紹到這了,更多相關header實例內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章,希望大家以后多多支持腳本之家!

      相關文章

      • html5+css3之CSS中的布局與Header的實現

        本文從CSS3的布局(CSS的布局的演化、CSS3盒模型-box-sizing、float布局中的bfc、Flexbox簡介)Header布局的實現(float實現布局、Header js的實現)向我們展示了HTML5與CS
        2014-11-21
      • css為什么要放在head標簽中

        這篇文章主要介紹了css為什么要放在head標簽中,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
        2020-10-12

      最新評論

      218彩票 www.berniewolfsdorf.com:新民市| www.e2aa.com:湖州市| www.ypiasby.com:珲春市| www.nazliyarim.com:马关县| www.petethesweet.com:固阳县| www.friendsofryankennedy.com:逊克县| www.cp2959.com:城市| www.ffdan.com:哈尔滨市| www.lesprince.com:鄂尔多斯市| www.crowwebdesign.com:策勒县| www.homakimiblog.com:荃湾区| www.intercritics.com:德安县| www.955461.com:永丰县| www.quintamontepalmira.com:从江县| www.rldmw.cn:盐津县| www.boutique-tahitienne.com:柳河县| www.mikeharris-em.com:启东市| www.assa7777.com:灵寿县| www.toystorez.com:大同县| www.jrjhl.com.cn:古浪县| www.glass-suppliers.com:绥滨县| www.waunakeeyoga.com:深水埗区| www.movieforhd.com:平遥县| www.x1900.com:平远县| www.919772.com:长丰县| www.pdqez.com:商南县| www.germanincubator.net:通山县| www.n8785.com:承德市| www.lmfbw.cn:泉州市| www.eegeu.com:万盛区| www.hirdavatciyiz.com:固阳县| www.new-sg.com:松溪县| www.ylsqsly.com:贵港市| www.wearetsk.com:河曲县| www.dickalerts.com:海盐县| www.hao-jiazheng.com:峡江县| www.cp9557.com:丹江口市| www.internationalchalice.com:赣榆县| www.spc2.com:扎赉特旗| www.vinintech.com:永春县| www.mfjqs.com:行唐县| www.yfsco.com:合山市| www.jade-capital.com:丰顺县| www.g3g2.com:怀柔区| www.gzgwg.com:平原县| www.supernac.com:武安市| www.acllo.com:沾化县| www.tuhai023.com:独山县| www.smartwhitesmile.com:玉山县| www.tkozelibitimilijunas.com:内丘县| www.yuanquanfeiye.com:沙洋县| www.ericagarliebphotography.com:杨浦区| www.mesutaydin.com:内黄县| www.aaagascalculator.com:甘孜| www.wisconsingaynews.com:宁乡县| www.shmmlaw.com:万安县| www.218101.com:集贤县| www.ph337.com:建宁县| www.beckymoe.com:江源县| www.jackshomeservices.com:宜丰县| www.fromge.com:锡林郭勒盟| www.huizhicz.com:安新县| www.mycosworld.com:张掖市| www.mjknetworks.com:西安市| www.paperswall.net:美姑县| www.cafe-hofmann.com:连城县| www.hnhuidasw.com:清徐县| www.resetv.com:宜宾县| www.mejoresamigas.net:通许县| www.freeportluxembourg.com:安化县| www.unifykorea2009.com:连云港市| www.sq633.com:精河县| www.discover-trinity.org:高青县| www.guitar-building.com:托克逊县| www.hg89456.com:崇仁县| www.tecnoconfundido.org:峨边| www.bar-dendo.com:保德县| www.jhjxjgc.com:汝城县| www.le-bon-debarras.com:彭山县| www.qqyyzs.com:留坝县| www.ynsh9188.com:南和县| www.santiagopalacios.com:乌鲁木齐县| www.daleysretreat.com:黔西| www.aulahumax.com:永州市|