Angularjs實(shí)現(xiàn)mvvm式選項(xiàng)卡效果

選項(xiàng)卡是現(xiàn)代web網(wǎng)頁(yè)中最常用的效果之一。
本文重點(diǎn)是用angularjs這個(gè)非持宓猓火mvvm框架询一,實(shí)現(xiàn)選項(xiàng)卡效果。在此之前癌椿,先搬出我們常用的jquery實(shí)現(xiàn)健蕊。

1、jquery實(shí)現(xiàn)簡(jiǎn)單粗暴的選項(xiàng)卡效果

var nav = $(".tabs");//tab切換
var box = $(".box");//容器
nav.on("click", function(){ //點(diǎn)擊事件
  var this_index=$(this).index();
  $(this).addClass("active").siblings().removeClass("active");
  box.eq(this_index).show().siblings().hide();
});

在這里只給出js核心部分踢俄,html和css不做贅述缩功。
以上代碼,簡(jiǎn)單粗暴的實(shí)現(xiàn)了選項(xiàng)卡效果都办,用點(diǎn)擊事件獲得elem.index(), 把索引和容器串起來(lái)控制顯示隱藏嫡锌。

2虑稼、angularjs實(shí)現(xiàn)一個(gè)簡(jiǎn)單選項(xiàng)卡效果

Html部分

 <section ng-app="myApp">
       <div class="tabs tabs-style" ng-controller="TabController as tab">
         <nav>
           <ul>
             <li ng-class="{'current':tab.isSet(1)}">
               <a href="#" ng-click="tab.setCurrent(1)"><span>Home</span></a></li>
             <li ng-class="{'current':tab.isSet(2)}">
               <a href="#" ng-click="tab.setCurrent(2)"><span>Work</span></a></li>
             <li ng-class="{'current':tab.isSet(3)}">
               <a href="#" ng-click="tab.setCurrent(3)"><span>Blog</span></a></li>
             <li ng-class="{'current':tab.isSet(4)}">
               <a href="#" ng-click="tab.setCurrent(4)"><span>About</span></a></li>
             <li ng-class="{'current':tab.isSet(5)}">
               <a href="#" ng-click="tab.setCurrent(5)"><span>Contact</span></a></li>
           </ul>
         </nav>
         <div class="content">
           <section id="section-1"  ng-show="tab.isSet(1)">
             <p>1</p>
           </section>
           <section id="section-2"  ng-show="tab.isSet(2)">
             <p>2</p>
           </section>
           <section id="section-3" ng-show="tab.isSet(3)">
             <p>3</p>
           </section>
           <section id="section-4" ng-show="tab.isSet(4)">
             <p>4</p>
           </section>
           <section id="section-5" ng-show="tab.isSet(5)">
             <p>5</p>
           </section>
         </div>
       </div>
   </section>

css 部分(這里為了方便我們使用Less語(yǔ)法,童鞋們可以自定義css實(shí)現(xiàn)個(gè)性效果)

* {
  margin: 0;
  padding: 0;
}

body {
  background: #e7ecea;
  font-weight: 600;
  font-family: 'Raleway', Arial, sans-serif;
  text-align: center;
}

a {
    color: #2CC185;
    text-decoration: none;
    outline: none;
  
    &:hover {
    color: #74777b;
    }
}

.tabs {
  position: relative;
  width: 100%;
  margin: 30px auto 0 auto;

  nav {
    ul {
      position: relative;
      display: flex;
      max-width: 1200px;
      margin: 0 auto;
      list-style: none;
      flex-flow: row wrap;
      justify-content: center;
      
        li {
          flex: 1;
          
          &.current a {
            color: #74777b;
          }
        }
      }
    }  
    a {
      display: block;
      position: relative;
      overflow : hidden;
      line-height: 2.5;
      
      span {
        vertical-align: middle;
        font-size: 1.5em;
      }
    }
}

.content {
  position: relative; 
  
  section {
    /* display: none; */
    margin: 0 auto;
    max-width: 1200px;

    &.content-current {
      /* display: block; */
    }
    
    p {
      color: rgba(40,44,42, 0.4);
      margin: 0;
      padding: 1.75em 0;
      font-weight: 900;
      font-size: 5em;
      line-height: 1;
    }
  }
}

.tabs-style {
  nav {
    /* background: rgba(255,255,255,0.4); */
    
    ul li {
      a {
        overflow: visible; 
        border-bottom: 1px solid rgba(0,0,0,0.2);
        -webkit-transition: color 0.2s;
        transition: color 0.2s;
      }
    }
    
    ul li.current a{
      &:after, &:before {
        content: '';
        position: absolute;
        top: 100%;
        left: 50%;
        width: 0;
        height: 0;
        border: solid transparent;
        }
      &:after {
        margin-left: -10px;
        border-width: 10px;
        border-top-color: #e7ecea;
      }
      &:before {
        margin-left: -11px;
        border-width: 11px;
        border-top-color: rgba(0,0,0,0.2);
      }
    }
  }
}

js部分

angular.module('myApp', [])
  .controller('TabController', function() {
    this.current = 1;
  
  this.setCurrent = function (tab) {
    this.current = tab;
  };
  
  this.isSet = function(tab) {
    return this.current == tab;
  };
});

最后效果如下圖所示:


angularjs-tabs.png

通過(guò)以上代碼势木,我們可以發(fā)現(xiàn)實(shí)現(xiàn)的核心是angularjs內(nèi)置的ng-class和ng-click动雹,ng-show指令。通俗來(lái)講:controller里定義了current 這條數(shù)據(jù)默認(rèn)值為1跟压,ng-click給點(diǎn)擊事件自定義函數(shù),改變current數(shù)據(jù)歼培,ng-class通過(guò)獲得current的值綁定條件震蒋,給當(dāng)前選中的索引添加current樣式,容器同樣獲得controller里的current數(shù)據(jù)通過(guò)ng-show控制顯示隱藏躲庄。

3查剖、angularjs實(shí)現(xiàn)一個(gè)稍微復(fù)雜的移動(dòng)端選項(xiàng)卡效果

html部分

<script src="http://cdn.bootcss.com/angular.js/1.3.8/angular.min.js"></script>
<script src="http://cdn.bootcss.com/angular.js/1.3.8/angular-touch.min.js"></script>
//angularjs的一個(gè)移動(dòng)端touch事件庫(kù)

<div ng-app='myApp' ng-controller="myController">
  <div class="type-tabs">
      <div ng-repeat="item in [1,2,3,4]" ng-click="changeIndex($index)">Tab{{item}}</div>
    </div>
    <div class="guid-bar">
      <div class="guid-bar-content" style="left:{{ 25*activeIndex}}%"></div>
    </div>
    <div class="tab-content" ng-swipe-right="swipeRight()" ng-swipe-left="swipeLeft()">
      <div class="tab-content-inner" style="left:{{ -100*activeIndex}}%">
        <div class="tab-content-item" ng-repeat="item in [1,2,3,4]" >
          <br /><br /><br /><br />
          <h1>Tab{{item}}
          </h1></div>
      </div>
    </div>
</div>

css部分

*{
  padding:0;
  margin:0;
  font-family:'Arial';
}
.type-tabs{
    width: 100%;
    height: 40px;
}
.type-tabs div{
    float: left;
    width: 25%;
    line-height: 40px;
    text-align: center;
  cursor:pointer;
  user-select:none;  
  -webkit-user-select:none;

}
.guid-bar{
    position: relative;
    margin-top: -3px;
}
.guid-bar-content{
    width: 25%;
    height: 3px;
    background-color: #345;
    position: absolute;
    left: 50%;
    transition:all 400ms ease;
}
.tab-content{
    width: 100%;
    height: 500px;
    background-color: #ccc;
    overflow: hidden;
}
.tab-content-inner{
    width: 400%;
    position: relative;
    transition: all 400ms;
}
.tab-content-item{
    width: 25%;
    float: left;
  text-align:center;
}

js部分

var myApp=angular.module('myApp',['ngTouch']);
myApp.controller('myController',function($scope){
  $scope.activeIndex=0;
    $scope.changeIndex=function(index){
        $scope.activeIndex=index;
    };
  $scope.swipeLeft=function(){
      $scope.activeIndex=++$scope.activeIndex;
      $scope.check();
    };
 $scope.swipeRight=function(){
      $scope.activeIndex=--$scope.activeIndex;
      $scope.check();
 };
 $scope.check=function(){
      if($scope.activeIndex>3)
        $scope.activeIndex=0;
      if($scope.activeIndex<0)
        $scope.activeIndex=3;
    }
})

當(dāng)當(dāng)當(dāng)當(dāng),效果如下:

ng-touch.png
好了噪窘,今天我們就給出這兩個(gè)例子笋庄,對(duì)angularjs了解過(guò)的童鞋,直接看代碼應(yīng)該可以很快看懂倔监。沒(méi)了解過(guò)的童鞋直砂,也能通過(guò)這兩個(gè)例子,了解到mvvm的黑魔法浩习,以及它的代碼組織結(jié)構(gòu)静暂。

4、angularjs的mvvm模式比jquery的dom操作好在哪里谱秽?

1洽蛀、從宏觀上來(lái)說(shuō),一種是操作數(shù)據(jù)處理數(shù)據(jù)疟赊,一種是操作dom和ui交互郊供。
一般網(wǎng)頁(yè)項(xiàng)目的流程可以總結(jié)為三個(gè)流程:1) 你要獲取界面上的數(shù)據(jù) 2)后臺(tái)交換數(shù)據(jù)3)獲取數(shù)據(jù)后,對(duì)界面重新進(jìn)行渲染近哟。這個(gè)過(guò)程中驮审,你和后臺(tái)數(shù)據(jù)交換怎么實(shí)現(xiàn)?jquery的ajax吧椅挣,如果數(shù)據(jù)交換的API假設(shè)20多個(gè)头岔,那么$.get或者$.ajax你要寫多少個(gè)才能全部包含進(jìn)去?而且所有API鏈接都不在一個(gè)地方鼠证,管理起來(lái)相當(dāng)麻煩峡竣。而angularjs只要配置一下route就行了。
獲取了數(shù)據(jù)后量九,你又如何管理這些數(shù)據(jù)适掰,如何把數(shù)據(jù)渲染到界面上去颂碧?
如何管理各種事件?jquery本身特性,也就是事件觸發(fā)类浪,很多時(shí)候载城,就是你在編寫 觸發(fā)事件->處理數(shù)據(jù) 的流程。很顯然费就,功能一多诉瓦,代碼就會(huì)和面條一樣,交織在一起了力细。身邊不乏兩三年的傳統(tǒng)jquery前端睬澡,事件委托、dom操作眠蚂、瀏覽器渲染過(guò)程煞聪、插件組件封裝等等都沒(méi)有去深入研究,可想而知代碼質(zhì)量有多爛逝慧。事實(shí)上jquery是一個(gè)類庫(kù)昔脯,并不是一個(gè)開(kāi)發(fā)框架,jq是對(duì)js原生api的進(jìn)一步封裝笛臣,讓你更加愉快的進(jìn)行dom操作云稚、動(dòng)畫操作以及ajax,正是因?yàn)樗^(guò)靈活捐祠,所以更容易寫出難以維護(hù)的代碼碱鳞。

2、性能方面:DOM操作慢踱蛀,DOM對(duì)象本身也是一個(gè)js對(duì)象窿给,所以嚴(yán)格來(lái)說(shuō),并不是操作這個(gè)對(duì)象慢率拒,而是說(shuō)操作了這個(gè)對(duì)象后崩泡,會(huì)觸發(fā)一些瀏覽器行為,比如布局(layout)和繪制(paint)猬膨。具體想了解的童鞋請(qǐng)點(diǎn)擊鏈接查看詳情:https://leozdgao.me/why-dom-slow/

結(jié)尾

隨著web產(chǎn)品越來(lái)越復(fù)雜角撞,分層架構(gòu)是必不可少的,因此雙向綁定作為解藥勃痴,結(jié)合很早就流行的MVC框架谒所,衍生出MVVM這神器。博主堅(jiān)信沛申,mvvm會(huì)是前端的終極解決方案劣领。由DOM操作到數(shù)據(jù)操作需要一個(gè)過(guò)程去適應(yīng),但只要結(jié)果是好的铁材,這些付出就都值得尖淘。在這個(gè)過(guò)程中奕锌,也是對(duì)你專業(yè)能力的一種提升。加油小伙伴們4迳>!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末趁桃,一起剝皮案震驚了整個(gè)濱河市辽话,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卫病,老刑警劉巖屡穗,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異忽肛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)烂斋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門屹逛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人汛骂,你說(shuō)我怎么就攤上這事罕模。” “怎么了帘瞭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵淑掌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蝶念,道長(zhǎng)抛腕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任媒殉,我火速辦了婚禮担敌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘廷蓉。我一直安慰自己全封,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布桃犬。 她就那樣靜靜地躺著刹悴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪攒暇。 梳的紋絲不亂的頭發(fā)上土匀,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音扯饶,去河邊找鬼恒削。 笑死池颈,一個(gè)胖子當(dāng)著我的面吹牛慎璧,可吹牛的內(nèi)容都是我干的盒犹。 我是一名探鬼主播姑蓝,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼撵割,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼便斥!你這毒婦竟也來(lái)了可款?” 一聲冷哼從身側(cè)響起谆甜,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤畦攘,失蹤者是張志新(化名)和其女友劉穎梦鉴,沒(méi)想到半個(gè)月后李茫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肥橙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年魄宏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片存筏。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宠互,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出椭坚,到底是詐尸還是另有隱情予跌,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布善茎,位于F島的核電站券册,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏垂涯。R本人自食惡果不足惜烁焙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耕赘。 院中可真熱鬧考阱,春花似錦、人聲如沸鞠苟。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)当娱。三九已至吃既,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跨细,已是汗流浹背鹦倚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冀惭,地道東北人震叙。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓掀鹅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親媒楼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乐尊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • AngularJS是什么?AngularJs(后面就簡(jiǎn)稱ng了)是一個(gè)用于設(shè)計(jì)動(dòng)態(tài)web應(yīng)用的結(jié)構(gòu)框架划址。首先扔嵌,它是...
    200813閱讀 1,590評(píng)論 0 3
  • AngularJS AngularJS概述 介紹 簡(jiǎn)稱:ng Angular是一個(gè)MVC框架 其他前端框架: Vu...
    我愛(ài)開(kāi)發(fā)閱讀 2,333評(píng)論 0 8
  • 個(gè)人博客搭建完成,歡迎大家來(lái)訪問(wèn)哦黎默丶lymoo的博客 博主最近了解學(xué)習(xí)了一下angularJS夺颤,記錄一下心得給...
    黎默丶lymoo閱讀 1,036評(píng)論 0 21
  • 1. 介紹 AngularJS是一款由Google公司開(kāi)發(fā)維護(hù)的前端MVC框架痢缎,其克服了HTML在構(gòu)建應(yīng)用上的諸多...
    崔皓翔閱讀 833評(píng)論 0 5
  • 什么都缺,什么都需要努力世澜,我希望愛(ài)上這種感覺(jué)独旷,而不是妥協(xié)
    糖饅頭閱讀 82評(píng)論 0 0