選項(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;
};
});
最后效果如下圖所示:
通過(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),效果如下:
好了噪窘,今天我們就給出這兩個(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迳>!