最好的編程語言是邏輯,前端各種交互特效的實現多可以用jquery實現,特效可以紛飛,內在邏輯則基本不變。這一篇文章主要介紹jquery實現常見特效背后的邏輯。
**1.通過類名獲取元素集合**
**首先來看一個js原生代碼不支持的方法,通過類來獲取元素集合。**
~~~
document.getElementsByClassName=function(classname){
var retnode = [];
var myclass = new RegExp('\\b'+classname+'\\b');//匹配類名
var elem = this.getElementsByTagName('*');//得到所有元素
for (var j = 0; j < elem.length; j++)
{
var classes = elem[j].className;
if (myclass.test(classes)){
retnode.push(elem[j]);
}
}
return retnode;
}//通過遍歷整個文檔元素類名,返回所有指定類名的數組
~~~
**邏輯思路:**
**通過構造一個類名的正則表達式,選取所有標簽,并通過正則表達式與所有標簽類名屬性進行匹配,從而返回一個類名數組,實現通過類名得到元素集合的目標。**
**實現這個方法的同時,也給在不使用jquery的情況下,選取特定序數的元素提供了便利。**
**2.二級聯動菜單的構造**
~~~
$("#select1").change( function() { //偵測一級菜單的change事件
var id = $("#select1").val();
if(id == 1){ //通過id判斷二級菜單
$.get('index.php', null, function(data){ //get方式傳值
$("span").empty(); //清空標簽
$("span").append("<select><option>濟南</opton><option>青島 </opton><option>臨沂</opton></select>"); //填充對應的二級菜單
});
}else{
$.get('index.php', null, function(data){ //get方式傳值
$("span").empty(); //清空標簽
$("span").append("<select><option>鄭州</opton><option>安陽 </opton><option>洛陽</opton></select>"); //填充對應的二級菜單
});
}
});
~~~
**邏輯思路:**
**根據需要設置聯動菜單的元素值被改變的情況,通過ajax方法傳空值給自身頁面,追加相應的元素,在這里是二級菜單。這里用到了jquery兩個方法:change方法和empty方法。**
**change方法在選定標簽值改變時,會被觸發執行。empty方法則是將標簽中html內容清空。**
**3.鏈接樣式和鏈接內容的顯示隱藏**
~~~
$(function(){
$("li").each(function(index){ //遍歷用戶控制區域
$(this).mouseover(function(){ //獲取當前用戶選擇區域
id = setTimeout(function(){ //使用時間事件函數實現緩動效果 更好的用戶體驗
$("li.tab").removeClass('tab'); //移除默認的選項按鈕的樣式
$(this).addClass("tab"); //給當前選項按鈕添加樣式
$("div.show").removeClass('show'); //移除默認的顯示區域的樣式
$("#tab1 div:eq("+index+")").addClass('show'); //根據選中的index索引添加樣式
},300);
}).mouseout(function(){
clearTimeout(id); //用戶鼠標移除時同時移除時間事件
});
});
});//鏈接對應相應內容的隱藏和顯示
~~~
**邏輯思路:**
**這里首先用到$()在其中書寫函數,[這里](http://www.jb51.net/article/21660.htm)詳細介紹了jquery構造函數的適用范圍。通過遍歷每個導航鏈接,當鼠標移上對應元素,首先移除所有默認選項樣式,在懸浮元素加上默認選中樣式。并移除當前顯示樣式,設置默認選項對應內容樣式為顯示狀態。**
**這里的亮點在于使用了一個顯示默認樣式的緩動效果,用戶體驗更細致。**
**4.“顯示更多(more)”功能的實現**
~~~
$(function(){
var $hideObj = $('ul li:gt(5):not(:last)');//選擇index大于等于5的li元素,除去最后一個,隱藏掉
$hideObj.hide();
$('.showmore span').click(function(){
if(!$hideObj.is(":visible")){//判斷是否可見is方法
$hideObj.show();
$('.showmore span').css("background","url(./images/up.bmp) no-repeat 0 -10");//切換狀態更換圖片
}else{
$hideObj.hide();
$('.showmore span').css("background","url(./images/down.bmp) no-repeat 0 0")
;//切換狀態更換圖片
}
});
});//選擇一部分隱藏掉,再將部分判斷是否顯示,顯示或者隱藏
~~~
**邏輯思路:**
**這里首先動用了選擇器除去最后一個元素所有大于5的li元素選中。通過用戶點擊事件,判斷是否顯示或者隱藏,并聯動修改被點擊的圖標。**
**亮點在選擇器的掌控恰到好處,用jquery最基本的就要用熟選擇器,這樣會快速高效操作dom節點。這樣也就不難理解css3為什么首要改革的就是選擇器了,簡化操作流程、正則化及語義化css選擇器,使得前端工程師讀和寫代碼更便捷。**
**5.文本域“剩余字數”**
****
~~~
$(document).ready(function(){
var tarea = $("#init");//
tarea.focus(function(){
$("#numtj").fadeIn(200);
}).blur(function(){
$("#numtj").fadeOut("slow");
})//文本域獲得焦點和失去焦點剩余字數顯示或消失,用到漸入漸出
$("#init").keyup(function() {
var text=$("#init").val();
var counter=text.length;
$("#numtj var").text(110-counter);
});// 按下鍵盤則實時修改剩余字數
});
~~~
**邏輯思路:**
**邏輯非常簡單,獲得焦點剩余字數顯示,失去焦點剩余字數消失。鍵盤按起計算還剩字數。**
**這里的亮點在于使用了fadeIn和fadeOut方法實現漸入漸出更加自然,體驗更好。focus和blur事件也是針對有輸入內容的元素常需處理的事件。keyup事件則與用戶輸入內容,實時交互有關系。**
**6.鼠標移動到圖片放大**
~~~
var ShowImage = function() {
xOffset = 10;
yOffset = 30;
$("#imglist").find("img").hover(function(e) {//給圖片對象添加事件及觸發函數
$("<img id='imgshow' src='" + this.src + "' />").appendTo("body");//在body上添加圖片對象
$("#imgshow")
.css("top", (e.pageY - xOffset) + "px")//定位body顯示圖片的y坐標 鼠標位置加人為設置偏移量
.css("left", (e.pageX + yOffset) + "px")//定位body顯示圖
.fadeIn("fast");
},function() {
$("#imgshow").remove();
});
$("#imglist").find("img").mousemove(function(e) {
$("#imgshow").css("top",(e.pageY-xOffset) + "px")
.css("left", (e.pageX + yOffset) + "px");
});
};
~~~
**邏輯思路:**
**這段代碼的邏輯非常具有普遍性,e代表鼠標事件,鼠標屬性pageX和pageY代表鼠標的坐標位置。整體的思路即是通過鼠標觸發懸浮事件,顯示或者移除與鼠標位置有一個偏移的圖片,并通過設置mousemove事件來實時移動放大圖位置。**
**看了以上幾個例子我們會發現,事件和選擇器是整體交互效果核心。所以這里有必要再精通、再精通。**
**7.圖片輪播**
~~~
var t = 0;
var n = 0;
var count;//全局變量溝通函數和click事件內變量
$(document).ready(function(){
count=$("#bannerList a").length;//獲取用戶控制a標簽的總數
$("#bannerList a:not(:first-child)").hide();//除了第一個元素都隱藏
$("#banner li").click(function(){//給存放圖片的列表添加單擊事件
var i = $(this).text() - 1;//獲取Li元素內的值,即1,2,3,4
n = i;//i的值賦值給n
if (i >= count){//判斷是否大于a標簽的總數
return;
}
var $a = $("#bannerList a").filter(":visible").fadeOut(500);//顯示的都隱藏掉
$a.parent().children().eq(i).fadeIn(1000);//根據當前li元素的值顯示圖片
//$("#banner").css("background","");//顯示按鈕樣式
$(this).toggleClass("show");//當前對象刪除或者添加類show
$(this).siblings().removeAttr("class");//當前對象刪除類屬性
});
//設置定時或消除定時
t = setInterval("showTime()", 3000);//每隔三秒執行一次方法
$("#banner").hover(function(){//給按鈕添加鼠標滑過事件
clearInterval(t)},function(){//鼠標滑過停止播放
t = setInterval("showTime()", 3000);//鼠標滑出繼續播放
});
})
function showTime()
{
if(n>=(count-1)){
n=0;
}else{
n=++n;
}
$("#banner li").eq(n).trigger('click');//代碼觸發click事件
}
~~~
**邏輯思路:**
**這段圖片輪播的代碼,大體可以分為三個模塊:初始化模塊、單擊事件模塊、鼠標懸浮模塊、自動觸發模塊。初始化模塊意在初始化開始輪播圖片序數,單擊時間模塊意在確定單擊事件執行被單擊對象顯示其他對象隱藏操作,鼠標懸浮模塊意在清除或者恢復自動觸發模塊,以便執行單擊操作,自動觸發模塊用于模擬單擊事件。**
**這段代碼混亂之處在于設置的i和n都為全局變量,在函數和執行語句中游走。trigger這個事件竟然模擬了單擊事件,鼠標懸浮hover用的恰到好處,不會造成與click事件的沖突。**
**8.[選擇城市插件](http://www.xiao-a.com/index.php/archives/1113.html)**
~~~
jQuery.fn.selectCity = function(targetObj){
var _self = this;//獲取當前對象,使用此插件的選擇器內對象
var targetObj = $(targetObj);//根據參數獲取對象
this.click(function(){//當前對象觸發單擊事件
var _top=$(this).offset().top + $(this).outerHeight(true);//獲取對象相對頂部真實高度
var _left=$(this).offset().left;//獲取對象相對左側真是高度
targetObj.bgiframe();//調用插件的方法bgiframe()
targetObj.show().css({"position":"absolute","top":_top+"px" ,"left":_left+"px"});//顯示定位
});//根據被選對象的位置,將隱藏的顯示出來并設置隱藏的下方位置
targetObj.find("#selectItemClose").click(function(){
targetObj.hide();//用戶單擊關閉按鈕隱藏選擇區域
});
targetObj.find("#selectSub :checkbox").click(function(){
targetObj.find(":checkbox").attr("checked",false);//將所有的多選框設置為未被選中
$(this).attr("checked",true);
_self.val($(this).val());
targetObj.hide();//設置點擊選中,并傳遞給input對象值,隱藏選中框
});
$(document).click(function(event){
if(event.target.id!=_self.selector.substring(1)){//鼠標在頁面單擊時隱藏復選框對象
targetObj.hide();
}
});
targetObj.click(function(e){
e.stopPropagation(); //阻止事件的傳遞
});
return this;
}
~~~
**邏輯思路:**
**頁面單擊對象時,則設置需要顯示的對象到被單擊對象的下方。并設置關閉按鈕。將所有多選框設置未被選中,以選中特定欄。當鼠標單擊頁面時,需要顯示的對象消失。**
**這里比較新穎的是當鼠標不點擊顯示區域和單擊對象時的處理,才采用了一個target.id的判斷達到效果。**
**9.分頁插件**
~~~
var page_all = $('.page');//獲取所有需要分頁顯示的區域,全局變量
var user_nav = $('#page_nation');//用戶分頁操作區域,全局變量,函數內更改也會更改值
function createActionLinks(){//動態生成分頁操作區域
user_nav.append('<a href="javascript:void(0)" id="prev">上一頁</a>');
for(var i=0;i<$('.page').length;i++){//顯示區域的范圍內遍歷
user_nav.append('<a href="javascript:void(0)" class="numlink">'+(i+1)+'</a>');
}
user_nav.append('<a href="javascript:void(0)" id="next">下一頁</a>');
}
function changeAction(page,preBtn,nextBtn){//分頁實現函數
$('.page:eq('+page+')').css('display','block');//顯示當前分頁內容
$('.numlink:eq('+page+')').addClass('current');//當前頁按鈕高亮顯示
var pageSize = parseInt($('.page').length - 1);//獲取最大頁數
if(page == 0){//顯示在第一頁時
preBtn.hide();//上一頁按鈕隱藏
nextBtn.show();//下一頁按鈕顯示
}else if(page==pageSize){//顯示在最后一頁時
preBtn.show();//上一頁按鈕隱藏
nextBtn.hide();//下一頁按鈕顯示
}else{
preBtn.show();//上一頁按鈕顯示
nextBtn.show();//下一頁按鈕顯示
}
}
function hideObj(){
page_all.css('display','none');//隱藏所有分頁
$('.numlink').removeClass('current');//去除所有分頁的樣式
}
$(document).ready(function(){
$('.page:eq(0)').css('display','block');//默認顯示第一頁
createActionLinks();//初始化創建用戶操作區域
$('.numlink:eq(0)').addClass('current');//給第一個按鈕添加樣式
var nextBtn = $('#next');//獲取下一頁按鈕對象
var preBtn = $('#prev');//獲取上一頁按鈕對象
var linkAction = $('.numlink');//獲取超級鏈接對象集合
preBtn.hide();//默認顯示第一頁并隱藏上一頁操作按鈕
var page = parseInt($('.numlink').index($('.current')));//返回當前分頁值,這一句話很關鍵
//三種點擊動作
nextBtn.click(function(){//給下一頁按鈕添加單擊事件
hideObj();//隱藏全部分頁部分
changeAction(page+1,preBtn,nextBtn);//函數每執行一次page的值減1
page = parseInt($('.numlink').index($('.current')));//返回page的值
});
preBtn.click(function(){//給上一頁按鈕添加單擊事件
hideObj();//隱藏全部分頁部分
changeAction(page-1,preBtn,nextBtn);//函數每執行一次page的值加1
page = parseInt($('.numlink').index($('.current')));//返回page的值
})
linkAction.click(function(){//給分頁頁碼鏈接添加單擊事件
var that = $(this);//獲取當前對象
hideObj();//隱藏全部分頁部分
var index = that.index() - 1;//獲取當前下標值
changeAction(index,preBtn,nextBtn);//調用分頁函數
page = parseInt($('.numlink').index($('.current')));//返回page的值
})
})
~~~
**邏輯思路:**
**分頁屬于老生長談了,這里的實現主要從分頁按鈕生成模塊、切換頁面模塊、隱藏模塊、并通過ready后,初始化設置初始狀態,對相應按鈕加上交互操作即click事件,并調用切換頁面模塊實現點擊切換。類似MVC架構。**
**10.自定義插件注意要點**
~~~
(function($){
$.fn.changeTab = function(options){//插件需要附加到jquery.fn對象上
var defaults = {
FontSize:"50px",
Color:'red',
FontWeight:'bold'
}//設置默認的參數
var options = $.extend(defaults,options);//對參數更新
this.each(function(){
var lis = $(this);//保留this操作
lis.hover(function(){
$(this).css({ "fontSize": options.FontSize, "color": options.Color ,"fontWeight":options.FontWeight});
},function(){
$(this).css({ "fontSize": '', "color": '',"fontWeight":''});
})
})
}
})(jQuery)// 插件內避免使用$ ,插件應返回一個jquery對象 便于鏈式操作
$(function(){
var options={
FontSize:'16px',
Color:'blue',
FontWeight:'bold'
}//設置個性化參數
$('li').changeTab(options);//引用插件
})
~~~
**邏輯思路:**
**1.插件需要附件到jquery.fn上。**
**2.插件內返回jquery對象便于鏈式操作。**
**3.設定默認參數,并通過傳參調用extend對象對參數更新。**
**以上總結均為項目中常見特效的情形,可以看出來事件和選擇器是需要掌握扎實的,一些編程技巧也要學會。其次這篇文章可以作為一個程序庫,供使用時查看。**
- 前言
- 前端編程提高之旅(一)----插件
- 前端編程提高之旅(二)----網站常見特效的jquery實現
- 前端編程提高之旅(三)----瀏覽器兼容之IE6
- 前端編程提高之旅(四)----backbone初體驗
- 前端編程提高之旅(五)----寫給大家看的css書
- 前端編程提高之旅(六)----backbone實現todoMVC
- 前端編程提高之旅(七)----marionette實現todoMVC
- 前端編程提高之旅(八)----D3.js數據可視化data join解析
- 前端編程提高之旅(九)----延遲對象
- 前端編程提高之旅(十)----表單驗證插件與cookie插件
- 前端編程提高之旅(十一)----jquery代碼的組織
- 前端編程提高之旅(十二)----position置入值應用
- 前端編程提高之旅(十三)----jquery選擇器
- 前端編程提高之旅(十四)----jquery DOM操作
- 前端編程提高之旅(十五)----jquery事件
- 前端編程提高之旅(十六)----jquery中的動畫
- 前端編程提高之旅(十七)----jquery中表單、表格和ajax
- 前端編程提高之旅(十八)----移動端web流行交互技術方案研究