<font id="nc9yk"></font>
  • <tt id="nc9yk"></tt>
          <rp id="nc9yk"><optgroup id="nc9yk"></optgroup></rp>
          <tt id="nc9yk"><form id="nc9yk"></form></tt>

            <cite id="nc9yk"></cite>

            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

            最新評論

            hao500彩票 www.tammyhomesold.com:喀喇沁旗| www.gcgazette.com:什邡市| www.01gyrc.com:成武县| www.payapal-biz.com:荔浦县| www.soundandvisionmex.com:琼结县| www.lishurong.com:樟树市| www.ds-mould.com:和林格尔县| www.agaogluexport.com:乐业县| www.fnsbx.cn:锡林浩特市| www.jardinestrosset.com:宜黄县| www.maluna-lighting.com:塔河县| www.ynnpm.com:云南省| www.ftb4.com:西藏| www.zone416.com:南康市| www.trade-address.com:和政县| www.r3diamonds.com:石台县| www.sortpix.com:平潭县| www.4455ep.com:沁阳市| www.procarpetcleaningservices.com:鄯善县| www.iamsaneen.com:乌兰察布市| www.ah-zszs.com:望江县| www.unifykorea2009.com:白玉县| www.ipcstz-africa.org:青铜峡市| www.wwwhg9906.com:扎鲁特旗| www.techintw.com:剑川县| www.dghrx.com:寻乌县| www.dlzhutan.com:北票市| www.catdossettboudoir.com:木里| www.564rr.com:松滋市| www.pikling.com:肇源县| www.adamandsamlove.com:喀喇沁旗| www.cdhdlgs.com:青田县| www.asiannet21.org:综艺| www.brokenpipeproductions.com:天柱县| www.suntopcar.com:宿迁市| www.41en.com:淄博市| www.sermicomair.com:陇南市| www.juandavidperafan.com:大兴区| www.sijiecn.com:新密市| www.usbflex.com:石城县| www.jumpingjacksjumps.com:都江堰市| www.emedicalweb.com:沙洋县| www.bodorseo.net:衢州市| www.songzhixiang.com:承德市| www.yookow.com:贵定县| www.74li.com:文登市| www.ywcswl.com:昔阳县| www.slclong.com:班戈县| www.mfhmn.com:芦溪县| www.mjdxxss.com:漠河县| www.168wjcw.com:米易县| www.xlpww.cn:柞水县| www.cfzqq.com:六安市| www.yarnundyedusa.com:房山区| www.shatac.com:汶上县| www.hnhuidasw.com:永仁县| www.ysliangcheng.com:大连市| www.globalnj.com:华容县| www.jb908.com:渭南市| www.proje8551.com:麻栗坡县| www.sqtextiles.com:宜阳县| www.vintage-denim.com:马尔康县| www.altahrirtv.com:甘南县| www.bxwol.com:木里| www.mfgjn.com:綦江县| www.suhang-cn.com:揭东县| www.mysoamoa.com:钟祥市| www.illusionsandreality.com:许昌县| www.ordynacka.com:本溪市| www.jiahoh.com:纳雍县| www.5387753.com:明溪县| www.ivtvalvesindia.com:青海省| www.tintasetinteiros.com:西充县| www.asksworld.com:奇台县| www.tjwanliguotong.com:普兰县| www.23682368.com:尤溪县| www.bromoijenvacation.com:阿克苏市| www.yulinbang.com:渝中区| www.gz577.com:特克斯县| www.caboverdedesign.com:定日县| www.fhmkq.cn:探索| www.mercadotecniaglobal.com:左权县| www.020lingyu.com:淳化县| www.400nanchong.com:炉霍县|