jQuery 入門詳解(二)

7. jQuery 裏的事件機制

javascriptHTML之間的交互是經過用戶和瀏覽器操做頁面時引起的事件來處理的。 jQuery不只提供了更加優雅的事件處理語法,並且極大地加強了事件處理能力。

7.1 加載 DOM

前面章節咱們已經對比了 window.onload()$(document).ready()兩種方法的區別。兩種都是入口函數,只不過前者是 js中的然後者是 jQ中的。而且領着之間仍是有區別的:

一、執行時機:javascript

window.onload()方法是等到頁面中全部元素加載完畢以後,才執行,即javascript此時才能夠訪問網頁中的任何元素。而jQuery使用$(document).ready()方法,能夠在DOM載入就緒時就對其進行操縱並調用執行它所綁定的函數。也就是說在jQ中,不須要等待全部圖片加載完再執行。php

可是就會有個問題,當獲取圖片寬高的時候,可能獲取不到。不過jQ中單獨提出了一個頁面加載的方法——load()方法,若是這個處理函數綁定給window對象則會在全部內容加載完畢以後觸發。css

$(window).load(function(){
   // 執行代碼 
});

上面的代碼,等同於js中的:html

window.onload = function(){
    // 執行代碼
}

二、屢次使用:java

javascript中入口函數只能寫一次,若是寫多個,下面會將上面的覆蓋掉:jquery

window.onload = function(){
    alert(123);
}

window.onload = function(){
    alert(456);             // 頁面只會彈出 456
}

jQuery中,入口函數能夠寫屢次,不會出現覆蓋的狀況:ajax

$(document).ready(function(){
   alert(123);          // 123               
});

$(document).ready(function(){
   alert(456);          // 456              
});

三、簡寫方式:
javascript中沒有簡寫方式,可是在jQ中有簡寫方式:json

// 1-原始版寫法
$(document).ready(function(){
   // 執行代碼 
});

// 2-簡化寫法,document能夠省略
$().ready(function(){
   // 執行代碼 
});

// 3-簡化寫法
$(function(){
    // 執行代碼
});

7.2 事件綁定

一、什麼是事件綁定segmentfault

在文檔裝載完成以後,若是打算爲元素綁定事件來完成某些操做,則可使用 bind()方法, bind()方法的調用格式爲:
bind(type [, data] ,fn);

bind()方法有三個參數:設計模式

  • type:事件類型,類型包括:blur,focus,load,resize,scroll,unload,click,dbclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error等。
  • [,data]:可選參數,做爲event.data屬性值傳遞給事件對象的額外數據對象。
  • fn:用來綁定的處理函數。

示例代碼: [ 38-jq事件機制-事件綁定.html ]

<!-- html 部分 -->
<h2>什麼是相對論?</h2>
<div class="hide">
    <p>相對論是關於時空和引力的基本理論,主要由阿爾伯特·愛因斯坦創立,依據研究的對象不一樣分爲狹義相對論和廣義相對論。相對論的基本假設是相對性原理,即物理定律與參照系的選擇無關。</p>
    <p>狹義相對論和廣義相對的區別是,前者討論的是勻速直線運動的參照系(慣性參照系)之間的物理定律,後者則推廣到具備加速度的參照系中(非慣性系),並在等效原理的假設下,普遍應用於引力場中。相對論極大地改變了人類對宇宙和天然的「常識性」觀念,提出了「同時的相對性」、「四維時空」、「彎曲時空」等全新的概念。它發展了牛頓力學,推進物理學發展到一個新的高度。</p>
    <p>狹義相對性原理是相對論的兩個基本假定,在目前實驗的觀測下,物體的運動與相對論是吻合很好的,因此目前廣泛認爲相對論是正確的理論。</p>
</div>

<!-- js 部分 -->
<script>
    $(function() {
        // 綁定點擊事件
        $('h2').bind('click', function() {
            // 選擇器$(this).next() 屢次出現,能夠用一個變量接收 儲存起來
            var $content = $(this).next();
            // is 方法 能夠對元素的狀態進行判斷
            if ($content.is(":visible")) {
                $content.hide();
            } else {
                $content.show();
            }
        });
    });
</script>

效果圖:

image

注意:

  • is()方法,能夠用來判斷一個元素是否包含某一屬性。
  • 當一個選擇器屢次出現的時候,能夠用一個變量將它緩存起來。

二、簡寫綁定事件

jQuery提供了一套簡寫的方法,簡寫的方法和 bind()的使用方法相似,實現效果也相同,可是能夠減小代碼量:
$(function(){
    $('h2').click(function(){
       // 執行代碼 
    });
});

7.3 合成事件

jQuery 有兩個合成事件: hover()方法和 toggle()方法(這裏的 toggle跟另外一個方法 toggle不是一個方法,這裏的 toggle方法由於重名的緣由,已經在 jQ1.8版本之後棄用了)。

一、hover()方法:

hover(enter,leaver); // enter 和 leaver 是兩個函數

hover()方法用於模擬光標懸停事件。當光標移動到元素上的時候會觸發第一個函數(enter),當光標離開元素的時候會觸發第二個函數(leaver)。

示例代碼: [ 39-jq事件機制-合成事件hover.html ]

$(function() {
    // hover 方法
    $('h2').hover(enter, leaver);
    var $content = $('h2').next();

    // 鼠標進入的時候觸發的函數
    function enter() {
        $content.show();
    }

    // 鼠標離開時觸發的函數
    function leaver() {
        $content.hide();
    }
});

二、toggle()方法:此方法自1.8版本之後,已棄用

toggle(fn1,fn2,...fnN);

toggle()方法,模擬的是鼠標單擊事件,當點擊第一次的時候,觸發對應的第一個函數(fn1),當點擊第二次的時候,觸發對應的第二個函數(fn2),一直到最後一個函數的時候,再點擊就會循環到第一個函數,就這樣一直循環切換。

另一個 toggle() 方法,是切換元素的可見狀態,若是元素是可見的,事件觸發以後,就會切換成不可見。

$('h2').click(function(){
    $(this).next().toggle(); // 若是元素一開始是隱藏的,點擊以後就會切換成顯示。
});

7.4 事件冒泡

在前面 特效篇裏面,咱們已經介紹了什麼是 事件冒泡,這裏再也不累贅,簡單來講,就是一個元素包含另外一個元素,兩個元素同時綁定了點擊事件,當我點擊裏面元素的時候,會同時觸發兩個事件函數,這就是事件冒泡。

具體產生的原理,和解決辦法請點擊這個連接,這裏會有處理兼容性的詳細步驟。

示例代碼: [ 40-jq事件機制-事件冒泡.html ]

<!-- html 部分 -->
<div class="box">
    <p>提示信息</p>
    <div class="box1">
        <p>提示信息</p>
        <div class="box2">
            <p>提示信息</p>
        </div>
    </div>
</div>

<!-- js 部分 -->
<script>
    $(function() {
        $('.box').click(function() {
            $(this).children('p').text(".box被觸發了");
        });
        $('.box1').click(function() {
            $(this).children('p').text(".box1被觸發了");
        });
        $('.box2').click(function() {
            $(this).children('p').text(".box2被觸發了");
        });
    });
</script>

效果圖:

image

咱們能夠看到,明明點擊的是最裏面的盒子,可是三個點擊事件都同時觸發了。

一、事件對象:

因爲在 IE-DOM和標準 DOM實現事件對象的方法各不相同,因此須要處理兼容性。在 jQuery中,已經將咱們封裝好了。 直接在觸發事件函數裏面傳一個參數:
$('element').bind('click',function(event){
    // 執行代碼
});

二、阻止事件冒泡:

阻止事件的方法存也在兼容性,一樣的 jQ中已經封裝好,直接使用 stopPropagation()方法來阻止事件冒泡。

示例代碼: [ 41-jq事件機制-阻止事件冒泡.html ]

$(function() {
    $('.box').click(function(e) {                   // 事件對象
        $(this).children('p').text(".box被觸發了");
        e.stopPropagation();                        // 阻止事件冒泡
    });
    $('.box1').click(function(e) {
        $(this).children('p').text(".box1被觸發了");
        e.stopPropagation();

    });
    $('.box2').click(function(e) {
        $(this).children('p').text(".box2被觸發了");
        e.stopPropagation();
    });
});

效果圖:

image

三、阻止默認行爲:

網頁中有不少元素都有默認行爲,例如,單擊超連接後會跳轉、單擊提交按鈕後表單會提交,有時候咱們須要阻止元素的默認行爲。

jQ中提供了一個方法來阻止元素的默認行爲:preventDefault

不加阻止默認行爲時的效果:

image

示例代碼: [ 42-jq事件機制-阻止默認行爲.html ]

<!-- html 部分 -->
<form action="test.html">
    <label for="username">用戶名</label><input type="text" id="username" placeholder="請輸入用戶名">
    <br>
    <input type="submit" value="提交" id="sub">
</form>
<div id="msg"></div>

<!-- js 部分 -->
<script>
    $(function() {
        $('#sub').click(function(e) {           // 事件對象
            var $username = $('#username').val();
            if ($username == "") {
                $('#msg').html('<p>文本框的值不能爲空</p>');
                e.preventDefault();         // 阻止默認行爲
            }
        });
    });
</script>

效果圖:

image

四、return false:

若是想要同時對事件中止冒泡和阻止默認行爲,能夠有一種默認的簡寫方式: return false

五、事件捕獲:

jQ中不支持事件捕獲,若是想要事件捕獲的話,請參考原生的 js

7.5 事件對象的屬性

一、event.type:

該方法能夠獲取到事件的類型。
$("a").click(function(event){
    console.log(event.type);    // 打印a標籤點擊以後的事件類型  打印 ==> click
    return false;           // 阻止a標籤默認跳轉事件
});

二、event.stopPropagation()方法:

上面已經提過了,該方法是阻止事件冒泡。

三、event.preventDefault()方法:

上面已經提過了,該方法是阻止事件默認行爲。

四、event.target:

該方法的做用是獲取到觸發事件的元素。
$("a").click(function(event){
    console.log(event.target);    // 打印 ==> a
    return false;                 // 阻止a標籤默認跳轉事件
});

五、event.pageX 和 event.pageY:

該方法的做用,是分別獲取到光標相對於頁面的 x座標和 y座標,若是頁面上有滾動條的話,還要加上滾動條的寬度和高度。

六、event.which

該方法的做用是在鼠標單擊事件中獲取到鼠標的左、中、右鍵;在鍵盤事件中獲取鍵盤的按鍵。

好比獲取鼠標的按鍵:

$("a").mousedown(function(event){
    console.log(event.which);     // 鼠標左鍵==> 1 鼠標中鍵==> 2 鼠標右鍵==> 3 
    return false;                 // 阻止a標籤默認跳轉事件
});

好比獲取鍵盤的按鍵:

$("input[text]").keyup(function(event){
    console.log(event.which);     // 對應按下的鍵盤碼
});

七、event.metaKey:

該方法是針對不一樣瀏覽器,獲取到 <ctrl>按鍵。

7.6 移除事件

當咱們想要移除一個事件的時候,可使用 unbind()方法。
unbind([type].[data]);

第一個參數是事件類型,第二個參數是將要移除的函數:

  • 若是沒有參數,直接刪除全部的綁定的事件;
  • 若是提供了事件類型做爲參數,那隻刪除該類型的綁定事件;
  • 若是把在綁定時傳遞的處理函數做爲第二個參數,則只有這個特定的事件處理函數會被刪除。

示例代碼: [ 43-jq事件機制-移除事件.html ]

<!-- html 部分 -->
<button id="btn1">點擊彈出alert</button>
<br>
<button id="btn2">點擊移除上一個btn點擊事件</button>

<!-- js 部分 -->
<script>
    $(function() {
        // 點擊第一個按鈕 彈出信息
        $('#btn1').click(function() {
            alert('我是btn1');
        });
        // 點擊第二個按鈕移除第一個按鈕的點擊事件
        $('#btn2').click(function() {
            $('#btn1').unbind('click');
        });
    });
</script>

效果圖:

image

7.7 模擬操做

什麼是模擬操做呢?咱們能夠看到前面的單擊事件,都須要手動去觸發,模擬操做就是能夠自動觸發 click,而不須要用戶主動點擊。
<!-- html 部分 -->
<button id="btn">點擊彈出信息</button>

<!-- js 部分 -->
<script>
    $(function() {
        $('#btn').click(function() {
            alert("呵呵");
        });
        // $('#btn').click();
        $('#btn').trigger('click');
    });
</script>

一進入頁面就會自動彈出「呵呵」,其中 $('#btn').click();,也能夠達到一樣的效果。

trigger()方法觸發事件後,會執行瀏覽器默認操做:

$('input').trigger('focus');

上面的代碼不只會觸發元素綁定的focus事件,也會使input元素自己獲得焦點(這就是瀏覽器的默認操做)。

triggerHandler()方法:

若是你只想觸發綁定的 focus事件,而不想執行瀏覽器默認操做,可使用t riggerHandler()方法。
$('input').triggerHandler('focus');

7.8 事件委託

事件委託,首先按字面的意思就能看出來,是將事件交由別人來執行,再聯想到事件冒泡,是否是想到了?對,就是將子元素的事件經過冒泡的形式交由父元素來執行。

舉個例子:

假如想要給多個li都註冊點擊事件,只須要給li循環遍歷,再添加點擊事件,這種方法當然簡單,可是假若有100個、1000li的時候,這裏的DOM操無形之中就繁瑣了。而且當咱們動態添加li元素的時候,這些li是沒有點擊事件的。可是這些只要講點擊事件交給父元素來執行,就能實現了。

一、on + 註冊事件:

除了 bind方法綁定事件以外,在 jQuery1.7版本以後,新添了一種方法: on()方法用來綁定事件, off()方法用來解除綁定事件。 on()方法既能夠註冊事件,還能夠註冊委託事件。
$(element).on(type,[selector],fn);

參數詳解:

  • type:字符串,事件類型,如:clickmouseover...;
  • selector:可選,字符串,用於過濾出被選中的元素中能觸發事件的後代元素。若是選擇器是 null 或者忽略了該選擇器,那麼被選中的元素老是能觸發事件;
  • fn:事件被觸發執行的函數。

示例代碼:

<!-- html 部分 -->
<div>
  <p>111111</p>
  <p>111111</p>
  <p>111111</p>
  <p>111111</p>
  <i>123456</i>
</div>

<!-- js 部分 -->
<script>
$(function () {
    // 這個是p本身註冊的事件(簡單事件)
    $("p").on("click", function() {
        alert("p的點擊事件");
    });
    
    //給div本身執行的
    $("div").on("click", function() {
        alert("div的點擊事件");
    });

    //給div裏面的p執行 委託事件
    $("div").on("click", "p", function() {
        alert("div裏面的p的點擊事件");
    });
});
</script>

效果圖:

image

第二個參數其實就至關於一個過濾器的做用,給div裏面的p註冊委託事件。在執行順序上,會先執行元素本身的事件,再去執行綁定的事件,最後執行父元素的事件。

當第二個參數傳進去的時候,就想當於給過濾的元素註冊委託事件

二、delegate 註冊委託事件:

delegate只能註冊委託事件。
$(fatheElement).delegate(selector,type,fn);

參數詳解:

  • fatheElement:父元素;
  • selector:可選,字符串,用於過濾出被選中的元素中能觸發事件的後代元素。若是選擇器是 null 或者忽略了該選擇器,那麼被選中的元素老是能觸發事件;
  • type:事件類型;
  • fn:事件被觸發執行的函數。

7.9 其餘用法

一、綁定多個事件類型:

$('div').bind('mouseover mouseout',function(){
   $(this).toggleClass("over");  // 當鼠標進入的時候,該元素的class屬性切換爲over 鼠標離開時class切換爲先前的值
});

二、添加事件的命名空間:

$('div').bind('click.plugin',function(){
   alert(123); 
});

$('div').bind('mouseover.plugin',function(){
   alert(456); 
});

$('div').bind('dbclick',function(){
   alert(666); 
});

$('button').click(function(){
    $('div').unbind('.plugin'); 
});

其中.plugin就是命名空間,當點擊button按鈕的時候,就刪除了事件的命名空間.plugin,此時對應的事件也會被移除。

相同的事件,不一樣的命名空間:

$('div').bind('click.plugin',function(){
   alert(456); 
});

$('div').bind('click',function(){
   alert(666); 
});

$('button').click(function(){
    $('div').trigger('click!');  // 注意後面的感嘆號
});

當點擊div的時候,會同時觸發click.pluginclick事件,若是點擊button只會觸發click事件,而不會觸發click.plugin事件。trigger('click!'),後面感嘆號表示的是匹配全部不在命名空間中的click方法。

8. jQuery 動畫

相對於原生 jsjQuery中的動畫更加的方便,更加的強大。

8.1 show()方法 和 hide()方法

當一個元素調用 show()方法的時候,會將該元素的 display設置爲 block,當調用 hide()方法的時候,會將該元素的 display設置爲 none
$('h2').bind('mouseover',function(){
    $(this).next().show();  // 鼠標進入的時候 h2 下一個兄弟元素顯示
}).bind('mouseout',function(){
    $(this).next().hide();  // 鼠標離開的時候 h2 下一個兄弟元素隱藏
})

此時尚未動畫的效果,下面給他們加上動畫效果

下面的代碼表示的是,元素在600ms內顯示出來:

$('element').show(600);

下面的代碼表示的是,元素在300ms內隱藏起來:

$('element').hide(300);

示例代碼: [ 45-jq動畫-show&hide.html ]

<!-- 樣式部分 -->
<style>
    * {
        margin: 0;
        padding: 0;
    }
    h4 {
        width: 300px;
        height: 30px;
        background: sandybrown;
        line-height: 30px;
        text-align: center;
    }
    div {
        width: 260px;
        height: 160;
        background: antiquewhite;
        padding: 20px;
        display: none;
    }
</style>

<!-- html 部分 -->
<h4>鼠標通過&離開</h4>
<div>
    <p>相對論是關於時空和引力的基本理論,主要由阿爾伯特·愛因斯坦創立,依據研究的對象不一樣分爲狹義相對論和廣義相對論。相對論的基本假設是相對性原理,即物理定律與參照系的選擇無關。</p>
</div>

<!-- js 部分 -->
<script>
    $(function() {
        $('h4').bind('mouseover', function() {
            $(this).next().show(600);
        }).bind('mouseout', function() {
            $(this).next().hide(300);
        });
    });
</script>

效果圖:

image

咱們能夠看到,無論是show仍是hide的時候,元素的不透明度都是在慢慢增長或者減少的。

8.2 fadeIn()方法 和 fadeOut()方法

showhide方法不一樣的是, fadeInfadeOut方法只改變元素的不透明度,不會去改變寬高。

下面的代碼表示的是元素淡入的效果,其中也能夠傳時間:

$('element').fadeIn();

下面的代碼表示的是元素淡出的效果:

$('element').fadeOut();

示例代碼: [ 46-jq動畫-fadeIn&fadeOut.html ]

$(function() {
    $('h4').bind('mouseover', function() {
        $(this).next().fadeIn();
    }).bind('mouseout', function() {
        $(this).next().fadeOut();
    });
});

效果圖:

image

8.3 slideUp()方法 和 slideDown()方法

slideUp()方法和 slideDown()方法只會改變元素的高度,若是一個元素的 display屬性值爲 「none」,調用 slideDown()方法的時候元素由上至下延伸顯示。 slideUp()正好相反,元素將由下到上縮短隱藏。

示例代碼: [ 47-jq動畫-slideDown&slideUp.html ]

$(function() {
    $('h4').bind('mouseover', function() {
        $(this).next().slideDown();
    }).bind('mouseout', function() {
        $(this).next().slideUp();
    });
});

效果圖:

image

8.4 自定義動畫方法 animate()

前面幾種類型動畫,比較單一,不少時候不能知足於用戶的需求,可是在 jQ中還有一個自定義動畫 animate,很是強大。
animate(params,speed,easing,callback);

參數說明以下:

  • params:一個包含樣式和值的對象,好比{p1:"val1",p2:"val2",...}
  • speed:動畫執行速度(可選),默認400
  • easing:表示過分使用哪一種緩動函數(默認swingjQ內部還支持一個linear)
  • callback:在動畫執行完以後,執行的函數(可選)。

一、簡單的動畫:

<!-- 樣式部分 -->
<style>
    #box {
        position: relative;
        width: 150px;
        height: 150px;
        background: aquamarine;
    }
</style>

<!-- html 部分 -->
<div id="box"></div>

<!-- js 部分 -->
<script>
    $(function() {
        // box兩秒內向右移動600px
        $('#box').animate({left: '600px'}, 2000);
    });
</script>

效果圖:

image

二、累加、累減動畫:

經過累加一個值讓元素從當前位置,累加到900的位置
$('#box2').animate({
    left: '+=900' // 在當前位置累加到 900
}, 1000);

三、多重動畫:

同時執行多個動畫

$('#box3').click(function() {
    $(this).animate({
        left: '300',
        height: '200px',
        width: '200px',
        top: '200px'
    }, 2000);
});

效果圖:

image

咱們能夠看到全部的變化都是同時進行的。

按順序執行多個動畫

$('#box4').click(function() {
    $(this).animate({
        left: '400px',
        height: '150px',
        opacity: '1'
    }, 3000).animate({
        top: '150px',
        width: '150px'
    }, 3000).fadeOut('slow');
});

效果圖:

image

四、延遲動畫:

在動畫執行中若是想要對某一段動畫進行延遲操做,可使用 delay()方法。
$('#box5').click(function() {
    $(this).animate({
        left: '400px',
        height: '150px',
        opacity: '1'
    }, 3000)
    .delay(1000)
    .animate({
        top: '150px',
        width: '150px'
    }, 3000).fadeOut('slow');
});

效果圖:

image

五、動畫隊列:

一組元素上的效果:

  • 當在一個animate()方法中應用多個屬性時,動畫是同時發生的;
  • 當以鏈式的寫法應用到動畫方法時,動畫是按照順序發生的。

多組元素上的動畫:

  • 默認狀況下,幾組動畫是同時發生的;
  • 當以回調形式應用動畫方式時,動畫按照回調順序發生的。

六、中止動畫:

若是須要在某處中止動畫須要使用 stop()方法。
stop([clearQueue],[gotoEnd]);

兩個參數都是可選的,都爲布爾值,clearQueue表示是否要清空未執行完的動畫隊列。gotoEnd表示的是直接將正在執行的動畫跳轉到末狀態。直接使用stop()方法,則會當即中止當前正在執行的動畫。

不明白的小夥伴,參考8.6小節,第二個案例 《動畫下拉菜單欄》

8.5 其餘動畫方法

一、toggle()方法:

toggle()方法能夠切換元素的可見狀態,若是元素是可見的,則切換爲隱藏。若是元素是隱藏的,則切換爲可見。
$('#btn1').click(function() {
    $(this).next().toggle();
});

效果圖:

image

只要循環點擊h4,它的下一個兄弟元素就會循環切換。

二、slideToggle()方法:

經過高度變化來切換匹配元素的可見性。
$('#btn2').click(function() {
    $(this).next().slideToggle();
});

效果圖:

image

三、fadeTo()方法:

fadeTo()方法能夠將不透明度設置到指定的值。
$('#btn3').click(function() {
    $(this).next().fadeTo(600, 0.5);  // 600表示的是執行時間 0.5 表示目標值
});

效果圖:

image

四、fadeToggle()方法:

fadeToggle()方法能夠切換不透明度。
$('#btn4').click(function() {
    $(this).next().fadeToggle();
});

效果圖:

image

8.6 jQuery 動畫案例

下面經過幾個簡單的例子,鞏固一下 jQuery動畫的知識。

一、呼吸燈版輪播圖:

在實現原理上,與前面特效篇的是不一樣的,這裏改變的是圖片的不透明度 opacity,而且不須要讓全部 li左浮動, ul也不須要設置一個很寬的寬度。在 jQ中操做更加的簡單。

樣式上:

  • 大盒子相對定位,圖片的li絕對定位,讓全部的圖片疊加在一塊兒;
  • 給全部的圖片li設置隱藏屬性,第一張圖片須要顯示;

js上:

  • 定義一個index用來記錄當前點擊的張數;
  • 當點擊右箭頭的時候,讓對應的圖片lifadeIn,其他的兄弟元素fadeOut,同時讓對應的小圓點添加current類,其他的兄弟元素移除這個類;
  • 點擊左箭頭只需將index--,再進行判斷一下,其餘的與點擊右箭頭原理是同樣的。

示例代碼: [ 50-jq動畫-案例-呼吸燈版輪播圖.html ]

<!-- 樣式部分 -->
<style>
    * {
        margin: 0;
        padding: 0;
        list-style: none;
    }
    
    #slide {
        width: 560px;
        height: 315px;
        margin: 100px auto;
        position: relative;
    }
    
    #slide ul li {
        position: absolute;
        display: none;
    }
    
    #slide ul li:first-child {
        display: block;
    }
    
    #slide ul img {
        display: block;
    }
    
    #slide #arrow {
        display: none;
    }
    
    #slide:hover #arrow {
        display: block;
    }
    
    #slide #arrow #leftArr,
    #slide #arrow #rightArr {
        width: 30px;
        height: 60px;
        background-color: rgba(0, 0, 0, 0.3);
        position: absolute;
        top: 50%;
        margin-top: -30px;
        text-decoration: none;
        color: #fff;
        text-align: center;
        font: 700 24px/60px "宋體";
    }
    
    #slide #arrow #leftArr {
        left: 0;
    }
    
    #slide #arrow #rightArr {
        right: 0;
    }
    
    #slide #arrow #leftArr:hover,
    #slide #arrow #rightArr:hover {
        background-color: rgba(0, 0, 0, 0.5);
    }
    
    #slide ol {
        width: 100px;
        height: 14px;
        background-color: rgba(255, 255, 255, 0.6);
        position: absolute;
        bottom: 14px;
        left: 50%;
        margin-left: -50px;
        border-radius: 7px;
    }
    
    #slide ol li {
        width: 10px;
        height: 10px;
        float: left;
        background-color: #fff;
        border-radius: 50%;
        margin-top: 2px;
        margin-left: 8.5px;
        cursor: pointer;
    }
    
    #slide ol li.current {
        background-color: #DF654A;
    }
</style>

<!-- html 部分 -->
<div id="slide">
    <ul>
        <li>
            <a href="#"><img src="../image/輪播圖/1.jpg" alt=""></a>
        </li>
        <li>
            <a href="#"><img src="../image/輪播圖/2.jpg" alt=""></a>
        </li>
        <li>
            <a href="#"><img src="../image/輪播圖/3.jpg" alt=""></a>
        </li>
        <li>
            <a href="#"><img src="../image/輪播圖/4.jpg" alt=""></a>
        </li>
        <li>
            <a href="#"><img src="../image/輪播圖/5.jpg" alt=""></a>
        </li>
    </ul>

    <div id="arrow">
        <a href="javascript:void(0);" id="leftArr">&lt;</a>
        <a href="javascript:void(0);" id="rightArr">&gt;</a>
    </div>

    <ol id="circleOl">
        <li class="current"></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ol>
</div>

<!-- js 部分 -->
<script>
    $(function() {
        // 定義一個變量,監測張數
        var index = 0;
        var $li = $('#slide ul li');
        // 1- 右箭頭功能
        $('#rightArr').click(function() {
            index++;
            if (index == $li.length) {
                index = 0;
            }
            // 讓第 index 個 li fadeIn,其餘全部的兄弟元素 fadeOut
            $li.eq(index).fadeIn(1000).siblings().fadeOut(1000);
            // 控制小圓點,當前index的小圓點添加 current 類 其他的兄弟元素移除這個類
            $('#circleOl li').eq(index).addClass('current').siblings().removeClass('current');
        });
        // 2- 左箭頭功能
        $('#leftArr').click(function() {
            index--;
            if (index == -1) {
                index = $li.length - 1;
            }
            // 讓第 index 個 li fadeIn,其餘全部的兄弟元素 fadeOut
            $li.eq(index).fadeIn(1000).siblings().fadeOut(1000);
            // 控制小圓點,當前index的小圓點添加 current 類 其他的兄弟元素移除這個類
            $('#circleOl li').eq(index).addClass('current').siblings().removeClass('current');
        });
    });
</script>

效果圖:

image

二、動畫下拉菜單欄:

動畫下拉菜單欄,主要實現原理仍是運用 jQ裏面的兩個動畫 slideDownslideUp,而且配合 stop方法

先看一下,若是不加stop()方法,會是一個什麼效果:

image

咱們能夠看到一個效果,當光標移到第一個「一級菜單」的時候,觸發動畫效果,可是動畫效果還沒結束,我就將光標移進了第二個菜單,觸發第二個菜單下拉效果。因此致使了動畫效果與光標不一致,此時只須要在光標移入、移出以前加上stop()方法,就能解決這個問題。

stop()方法會結束當前正在進行的動畫效果,並當即執行隊列中的下一個動畫。

示例代碼: [ 51-jq動畫-案例-動畫下拉菜單.html ]

<!-- html 部分 -->
<div class="wrap">
    <ul>
        <li>
            <a href="javascript:void(0);">一級菜單1</a>
            <ul class="ul">
                <li><a href="javascript:void(0);">二級菜單11</a></li>
                <li><a href="javascript:void(0);">二級菜單12</a></li>
                <li><a href="javascript:void(0);">二級菜單13</a></li>
            </ul>
        </li>
        <li>
            <a href="javascript:void(0);">一級菜單2</a>
            <ul>
                <li><a href="javascript:void(0);">二級菜單21</a></li>
                <li><a href="javascript:void(0);">二級菜單22</a></li>
                <li><a href="javascript:void(0);">二級菜單23</a></li>
            </ul>
        </li>
        <li>
            <a href="javascript:void(0);">一級菜單3</a>
            <ul>
                <li><a href="javascript:void(0);">二級菜單31</a></li>
                <li><a href="javascript:void(0);">二級菜單32</a></li>
                <li><a href="javascript:void(0);">二級菜單33</a></li>
            </ul>
        </li>
    </ul>
</div>

<!-- js 部分 -->
<script>
    $(function() {
        // 1- 給當前 菜單欄註冊鼠標進入事件
        $('.wrap>ul>li').mouseenter(function() {
            // 進入的時候,讓下面的ul slideDown動畫顯示,顯示以前要加上stop方法
            $(this).children('ul').stop().slideDown();
        });
        // 2- 給當前 菜單欄註冊鼠標離開事件
        $('.wrap>ul>li').mouseleave(function() {
            // 離開的時候,讓下面的ul slideUp動畫顯示,顯示以前要加上stop方法
            $(this).children('ul').stop().slideUp()
        });
    });
</script>

效果圖:

image

三、手風琴:

實現原理:

  • 給外部大盒子設置一個與圖片大小一致的寬高,而且設置相對定位
  • 仍是採用ul,li結構,li設置寬高,與圖片大小一致,設置絕對定
  • 動態的給li添加背景圖片,由於li絕對定位的緣由,此時全部的li都疊在一塊兒
  • 動態的給每一個li設置left值(left*i),這時候li就會依次排開
  • 大盒子還要設置一個overflow-hidden屬性,將多餘的隱藏掉
  • 給每一個li註冊鼠標鼠標通過事件,而後根據下面推算出的規律(當前鼠標通過的索引index,他以前包括他本身的left值都是,設定的最小值乘以對應的索引。而他後面的會將設定的最小值乘以對應的索引後再加上450,這裏的450不是一個固定值,根據規律找出來的)進行判斷,設置各自的left值;
  • 鼠標離開的時候再讓全部的盒子恢復到一開始的位置,每一個li顯示等分的寬度

大盒子沒有overflow-hidden的時候:

image

畫個圖,理解一下:

image

找規律:

結合上面的圖片,咱們能夠找到一個規律
  • 當鼠標在第1個li上的時候,li下標index爲0:

    • index:0 left:0
    • index:1 left:500px
    • index:2 left:550px
    • index:3 left:600px
    • index:4 left:650px
  • 當鼠標在第2個li上的時候,li下標index爲1:

    • index:0 left:0
    • index:1 left:50px
    • index:2 left:550px
    • index:3 left:600px
    • index:4 left:650px
  • 當鼠標在第3個li上的時候,li下標index爲2:

    • index:0 left:0
    • index:1 left:50px
    • index:2 left:100px
    • index:3 left:600px
    • index:4 left:650px

看出規律了嗎?

  • 當對應li的下標<=鼠標懸停的的下標上的時候left值 是50*i
  • 當對應li的下標>鼠標懸停的的下標上的時候left值 是50*i + ,450(450不是固定的值,是通過計算出來的)

示例代碼: [ 52-jq動畫-案例-手風琴.html ]

<!-- 樣式部分 -->
<style>
    * {
        margin: 0;
        padding: 0;
        list-style: none;
    }
    
    #box {
        width: 700px;
        height: 440px;
        margin: 100px auto;
        position: relative;
        overflow: hidden;
        box-sizing: border-box;
        border-radius: 30px;
    }
    
    li {
        width: 700px;
        height: 440px;
        position: absolute;
    }
</style>

<!-- html 部分 -->
<div id="box">
    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>

<!-- js 部分 -->
<script>
    $(function() {
        var $li = $('#box li');
        // 給全部的 li 設置背景圖
        for (var i = 0; i < $li.length; i++) {
            // 這裏加上eq的目的是,隱式迭代添加的圖片只會是第一張
            $li.eq(i)
                .css({
                    "backgroundImage": "url(../image/手風琴/" + (i + 1) + ".png)",
                    "left": 140 * i
                });
            // 鼠標進入的時候
            $li.mouseenter(function() {
                for (var i = 0; i < $li.length; i++) {
                    // 判斷i小於等於當前索引的時候,讓以前的left值都是50*i的
                    if (i <= $(this).index()) {
                        $li.eq(i).stop().animate({
                            left: 50 * i
                        })
                    } else {
                        // 其他的li的left值應該加上450
                        $li.eq(i).stop().animate({
                            left: 50 * i + 450
                        });
                    }
                }
            });
            // 鼠標離開的時候 讓每個li 的left  恢復到 140*i
            $li.mouseleave(function() {
                for (var i = 0; i < $li.length; i++) {
                    $li.eq(i).stop().animate({
                        left: 140 * i
                    });
                }
            });
        }
    });
</script>

效果圖:

image

四、彈幕效果:

  • 獲取輸入框的的 value 值;並生成 span 標籤
  • span 標籤添加到 頁面中,隨機顏色 隨機高度 span動畫從右向左
  • 到達最左邊的時候刪除 span 標籤(不刪除會隨着輸入的內容愈來愈多影響性能)

示例代碼: [ 53-jq動畫-案例-彈幕效果.html ]

<!-- html 部分 -->
<div id="page">
    <div id="import">
        <div id="content">
            <p class="title">吐槽</p>
            <input type="text" name="" id="text" placeholder="發送彈幕,與小夥伴一塊兒互動!">
            <button id="btn">發射</button>
        </div>
    </div>
</div>

<!-- js 部分 -->
<script>
    $(function() {
        // 定義一個顏色數組
        var colorArr = ['#FF895D', '#78BBE6', '#FF4273', '#00BBF0', '#7C73E6', '#EE2B47', '#F60C86', '#9870FC', '#F96D00', '#303481'];

        $('#btn').click(function() {
            // 獲取到輸入框的內容
            var content = $('#text').val();
            $("#text").val("");

            // 獲取隨機顏色和高度
            var randomColor = parseInt(Math.random() * colorArr.length);
            var randomTop = parseInt(Math.random() * 301);
            // 獲取屏幕的可視寬度
            var clientWidth = $(window).width();
            // 根據屏幕的寬度計算出彈幕的速度(1300px的時候8秒執行完)
            var time = (8000 / 1300) * clientWidth;
            // 建立span標籤 判斷當輸入爲空的時候不觸發
            if (content != "" && content.trim()) {
                $('<span></span>').text(content)
                    // 設置span的顏色 與 top值left值 
                    .css({
                        "color": colorArr[randomColor],
                        "left": clientWidth,
                        "top": randomTop
                    })
                    // 將建立的span添加到頁面中
                    .appendTo("#page")
                    // 執行動畫 left目標值-300px,執行時間time 過渡效果linear(勻速) 回調函數內將到達終點的span移除掉
                    .animate({left: -300}, time, "linear", function() {
                        $(this).remove();
                    })
            }
        });
        // 對整個頁面註冊鍵盤按下事件
        $(document).keydown(function(e) {
            // 當按下的鍵爲回車鍵時,執行上面的點擊事件
            if (e.keyCode == 13) {
                $("#btn").click();
            }
        })
    });
</script>

效果圖:

image

9. jQuery 裏的 Ajax 操做

Ajax全稱「 Asynchronous JavaScript and XML」(異步的 JavaScriptXML)。它的出現揭開了無刷新更新頁面的新時代。具體的實現方式以及 Ajax的優缺點,在前面的一篇文章[《js 進階知識-Ajax篇》]()已經講得很詳細了,不明白的小夥伴,能夠先去學習下原生 js是如何實現 Ajax的。

jQueryAjax操做進行了封裝,在jQuery$.ajax()方法屬於最底層的方法,第2層是load()$.get()$.post()方法,第3層就是$.getScript()$.getJSON()方法。

9.1 load()方法

一、載入HTML文檔

load()方法是 jQuery中最爲簡單和經常使用的 Ajax方法,能載入遠程 HTML代碼並插入 DOM中。它的結構爲:
load(url[,data][,callback]);

參數詳解:

參數名稱 類型 說明
url String 請求HTML頁面的URL地址
data(可選) Object 發送至服務器的key/value數據
callback(可選) Function 請求完成時的回調函數,不管請求成功仍是失敗

示例代碼:

首先新建一個data.html的文件,裏面模擬的是請求的數據:

<div class="comment">
    <h4>張三:</h4>
    <p class="para">哈哈哈,真有趣</p>
</div>
<div class="comment">
    <h4>李四:</h4>
    <p class="para">頂樓上</p>
</div>
<div class="comment">
    <h4>王五:</h4>
    <p class="para">66666</p>
</div>

再建立一個主頁面,index.html

<!-- 樣式部分 -->
<style>
    .send {
        margin-bottom: 10px;
    }
    
    .comment {
        width: 300px;
        padding: 10px 0px 10px 10px;
        background: rgba(156, 250, 220, 0.5);
        border: 1px dashed #f45;
        margin-bottom: 10px;
    }
</style>

<!-- html 部分 -->
<input type="button" class="send" value="Ajax請求">
<div class="comment">已有評論:</div>
<div class="resText"></div>

<!-- js部分 -->
<script>
    $(function() {
        // 點擊按鈕,使用load方法請求data頁面
        $(".send").click(function() {
            // 請求的頁面追加到類名爲resText的div中
            $(".resText").load("data.html");
        });
    });
</script>

效果圖:

image

上面的例子能夠看出來,開發人員只須要使用jQuery選擇器爲HTML片斷指定目標位置,而後將要加載的文件URL做爲參數傳遞給load()方法便可。咱們能夠發現本來的data頁面是沒有爲類comment設置樣式的,可是主頁面加載後一樣的樣式名會當即應用到新加載的內容上。

二、篩選載入的HTML文檔

上面的案例咱們能夠看到,點擊以後 data.html裏面的整個內容都被加載進來了。若是須要加載 data.html頁面裏的某些元素的時候該怎麼辦呢?咱們可使用 load()方法的URL參數來達到目的。只須要指定選擇符就 ok了。

示例代碼:

// 選擇加載data.html頁面中class爲「para」的內容,注意中間有一個空格
$(".resText").load("data.html .para");

效果圖:

image

咱們能夠看到,只有類名是「para」的被加載了。

三、傳遞方式:

load()方法的傳遞方式根據參數 data來自動指定。若是沒有參數傳遞,則採用 GET方式傳遞;反之則會自動轉換爲 POST方式:
// 1- 無data參數傳遞的時候,則是GET方式
$('.resText').load("data.php",function(){});

// 2- 有data參數傳遞的時候,則是POST方式
$('.resText').load("data.php",{name:"Levi",age:"18"},function(){});

四、回調函數:

回調函數是在頁面加載完成以後執行的操做,該函數有三個參數,分別是請求返回的內容、請求狀態、 XMLHttpRequest對象:
$('.resText').load("data.php",function(responseText,textStatus,XMLHttpRequest){
    // responseText : 請求返回的內容
    // textStatus:請求狀態:success、error、notmodified、timeout 4種
    // XMLHttpRequest :XMLHttpRequest對象
});

load()方法中,不管Ajax請求是否成功,只要當請求完成以後,回調函數都會執行。

9.2 $.get()方法和$.post()方法

load()方法一般是用來從 WEB服務器上獲取靜態的數據的,若是須要向服務器傳遞參數的話,可使用 $.get()方法和 $.post()方法還有後面的 $.ajax方法。

一、$.get()方法

$.get()方法使用 GET方式來進行異步請求:
$.get(url [,data] [,callback] [,type]);

參數詳解:

參數名稱 類型 說明
url String 請求HTML頁面的URL地址
data(可選) Object 發送至服務器的key/value數據,會做爲字符串憑接在url的後面
callback(可選) Function 請求完成時的回調函數(只有當Response的返回狀態是success的時候,才調用該函數)
type (可選) String 服務器返回內容的格式,包括xml、html、script、json、text、_default

回調函數:

$.get()方法的回調函數只有兩個參數:
$.get("get.php",{useraname: "Levi",age:18},function(data,textStatus){
    // data 返回的內容,能夠是XML文檔、JSON文件、HTML片斷等的
    // textStatus 請求狀態:success、error、notmodified、timeout 4種。
})

data參數表明請求返回的內容,textStatus參數表明請求回來的狀態,注意:只有當數據成功返回success後才被調用。

二、$.post()方法

它與 $.get()方法的結構和使用方式都相同,不過他們之間仍有如下區別:
  • get請求會將參數跟在URL的後面進行傳遞,而post請求則是做爲HTTP消息的實體內容發送給Web服務器;
  • get對傳輸的數據大小有限制(一般不大於2KB),而使用post方式傳遞數據量要比get方式大得多;
  • get方式請求的數據會被瀏覽器緩存起來,所以能夠經過瀏覽器的歷史記錄中讀到這些數據,存在安全性問題。

9.3 $.ajax()方法

$.ajax()方式經常使用參數解析:
方法 做用
url 請求的地址
type 請求的方式
dataType 告訴jQuery,須要按照什麼格式對服務器返回的數據進行解析,默認json
data 數據
success 請求成功的回調函數
error 請求失敗的回調函數
beforeSend 請求發送以前調用的函數
complete 不論請求是成功仍是失敗的,只要請求完成就會調用
timeout 設置請求超時時間

示例代碼:

$.ajax({
    // 請求的地址
    url: "04-data.php",
    // 請求的方式
    type: "get",
    // 告訴jQuery,須要按照什麼格式對服務器返回的數據進行解析,默認json
    dataType: "json",
    // 數據
    data: {
        msg: "我是來請求數據的"
    },
    // 請求成功的回調函數
    success: function(data) {
        console.log(data);
    },
    // 請求失敗的回調函數
    error: function() {
        console.log("失敗了");
    },
    // 請求發送以前調用的函數
    beforeSend: function() {
        console.log("請求發送以前調用的函數");
        // 若是返回一個false,那麼就會阻止整個請求的發送
        // return false;
        // 用法:能夠用做表單驗證,當表單內容符合規範的時候發送ajax請求,當不符合的時候就不發送ajax請求
    },
    // 不論請求是成功仍是失敗的,只要請求完成就會調用
    complete: function() {
        console.log("請求完成了");
    },
    // 設置請求超時時間(單位:ms),超過這個時間後,就不會請求了
    timeout:2000
});

9.3 jQuery中的serialize和serializeArray方法

一、jQuery中的serialize方法:

serialize方法會將表單中全部的內容拼接成 key=value&key=value這樣的字符串。

經過這種方式就不要再去手動獲取表單中的內容的

<form id="form">
    <input type="text" name="username">
    <input type="text" name="pwd">
    <input type="text" name="phonenumber">
    <input type="text" name="email">

    <button id="btn">獲取數據</button>
</form>

<script src="jquery.min.js"></script>
<script>
    $(function() {
        $('#btn').click = function() {
            var dataStr = $('#form').serialize();
            $.ajax({
                url: "json.php",
                //data這個參數能夠接收對象,也能夠接受 key=value&key=value的這種字符串
                data: dataStr,
                type: "post"
            });
        }
    });
</script>

二、jQuery中的serializeArray方法:

上面的方法咱們能夠看到,獲取整個數據的時候,是很簡單,可是想要進行校驗的話就很難,由於上面的方法獲取的是一個字符串,不能進行校驗,因此此時咱們須要另一個方法, jQuery中的 serializeArray方法。
<form id="form">
    <input type="text" name="username">
    <input type="text" name="pwd">
    <input type="text" name="phonenumber">
    <input type="text" name="email">

    <button id="btn">獲取數據</button>
</form>

<script src="jquery.min.js"></script>
<script>
    $(function() {
        $('#btn').click = function() {
            // 獲取到的數組拼接成字符串
            var dataArr = $('#form').serializeArray();
            $.ajax({
                url: "json.php",
                data: dataArr,
                type: "post"
            });
        }
    });
</script>

示例代碼:ajax模擬表單校驗及註冊

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>sing in page</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background-color: #F7F7F7;
        }
        
        ul {
            margin: 0;
            padding: 50px;
            list-style: none;
        }
        
        .register {
            width: 800px;
            margin: 50px auto;
            background-color: #FFF;
            border: 1px solid #CCC;
            border-radius: 5px;
        }
        
        li {
            display: flex;
            margin: 20px 0;
        }
        
        label,
        input {
            display: block;
            float: left;
            height: 46px;
            font-size: 24px;
            box-sizing: border-box;
            color: #333;
        }
        
        label {
            width: 200px;
            line-height: 46px;
            margin-right: 30px;
            text-align: right;
        }
        
        input {
            width: 320px;
            padding: 8px;
            line-height: 1;
            outline: none;
            position: relative;
        }
        
        input.code {
            width: 120px;
        }
        
        input.verify {
            width: 190px;
            margin-left: 10px;
        }
        
        input.disabled {
            background-color: #CCC !important;
        }
        
        input[type=button] {
            border: none;
            color: #FFF;
            background-color: #E64145;
            border-radius: 4px;
            cursor: pointer;
        }
        
        .error {
            color: red;
            margin-left: 10px;
            font-size: 12px;
            line-height: 46px;
        }
        
        .tips {
            position: fixed;
            top: 0;
            width: 100%;
            height: 40px;
            text-align: center;
        }
        
        .tips p {
            min-width: 300px;
            max-width: 400px;
            line-height: 40px;
            margin: 0 auto;
            color: #FFF;
            display: none;
            background-color: #C91623;
        }
    </style>
</head>

<body>
    <div class="register">
        <form id="ajaxForm">
            <ul>
                <li>
                    <label for="name">用戶名</label>
                    <input type="text" name="name" class="name" id="name">
                    <span class="error"></span>
                </li>
                <li>
                    <label for="pass">請設置密碼</label>
                    <input type="password" name="pass" class="pass" id="pass">
                </li>
                <li>
                    <label for="repass">請確認密碼</label>
                    <input type="password" name="repass" class="repass" id="repass">
                </li>
                <li>
                    <label for="mobile">驗證手機</label>
                    <input type="text" name="mobile" class="mobile" id="mobile">
                </li>
                <li>
                    <label for="code">短信驗證碼</label>
                    <input type="text" name="code" class="code" id="code">
                    <input type="button" value="獲取驗證碼" class="verify">
                </li>
                <li>
                    <label for="submit"></label>
                    <input type="button" class="submit" value="當即註冊" id="submit">
                </li>
            </ul>
        </form>
    </div>
    <div class="tips">
        <p>用戶名不能爲空</p>
    </div>

    <script src="../05-Form-Validation/js/jquery.min.js"></script>
    <script>
        /*
         * 1.獲取短信驗證碼
         * 1.1 當沒有輸入手機號的時候  提示請輸入手機號
         * 1.2 手機號格式不正確        提示請輸入正確的手機號
         * 1.3 調獲取短信驗證碼接口
         * 1.4 顯示正在發送中  不能再次發送(防止重複提交)
         * 1.5 當接口成功  按照後臺的計時時間  進行倒計時
         * 1.6 當接口失敗  提示短信接口繁忙 恢復按鈕
         * 1.7 倒計時完成以後  恢復按鈕
         * */

        /*
         * 2.註冊
         * 2.1 當沒有輸入用戶名的時候  提示請輸入用戶名
         * 2.2 調註冊接口
         * 2.3 顯示正在提交 不能再次發送(防止重複提交)
         * 2.4 當接口成功
         *     狀態碼 10000 成功
         *     狀態碼 10001 失敗 提示用戶  用戶名已註冊  表單後
         *     狀態碼 10002 失敗 沒輸用戶  請輸入用戶名
         *     恢復按鈕
         * 2.5 當接口失敗  恢復按鈕
         * */
        $(function() {
            /* 警告顯示提示 */
            var showTip = function(tip) {
                $(".tips p").html(tip).fadeIn(500).delay(1000).fadeOut(500);
            };

            /* 1.獲取短信驗證碼 */
            $(".verify").on("click", function() {
                /* 當前按鈕指定變量 */
                var $btn = $(this);
                /* 判斷當前按鈕是否有disabled屬性,有的話說明已經被點擊了,就不讓再點擊了 */
                if ($btn.hasClass('disabled')) {
                    return false;
                }

                /* 獲取手機號 */
                var mobile = $.trim($('#mobile').val());
                /* 判斷是否輸入內容,沒有的話提示信息 */
                if (!mobile) {
                    showTip('請輸入手機號');
                    return false;
                }
                /* 判斷手機格式 不正確的話提示信息 */
                var regPhone = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/;
                if (!regPhone.test(mobile)) {
                    showTip('請輸入正確的手機號');
                    return false;
                }
                /* 調取短信驗證碼接口 */
                $.ajax({
                    url: 'registerCode.php',
                    type: 'post',
                    dataType: 'json',
                    data: {
                        mobile: mobile
                    },
                    success: function(data) {
                        if (data.code == 10000) {
                            /* 給發送成功的按鈕添加一個倒計時 */
                            var time = parseInt(data.result.time);
                            var timer = setInterval(function() {
                                time--;
                                $btn.val(time + '秒後再次獲取');
                                /* 倒計時完成以後  恢復按鈕*/
                                if (time <= 0) {
                                    $btn.val('獲取驗證碼').removeClass('disabled');
                                    clearInterval(timer);
                                }
                            }, 1000);
                        } else {
                            /* 邏輯上的失敗 */
                            $btn.val('獲取驗證碼').removeClass('disabled');
                        }
                    },
                    error: function() {
                        /* 當接口失敗,提示短信接口繁忙 */
                        showTip('短信接口繁忙');
                        $btn.val('獲取驗證碼').removeClass('disabled');
                    },
                    beforeSend: function() {
                        /* 點擊以後,顯示正在發送 */
                        $btn.val('正在發送...').addClass('disabled');
                    }
                });
                $btn.addClass('disabled');
            });
            /* 2.註冊功能的實現 */
            $('.submit').on('click', function() {
                /* 當前點擊的按鈕 */
                var $btn = $(this);
                /* 正在請求當中 不能再次點擊 */
                if ($btn.hasClass('disabled')) {
                    return false;
                }
                var username = $("#name").val().trim();
                var password = $("#pass").val().trim();
                var repeatPassword = $("#repass").val().trim();
                var code = $("#code").val().trim();
                var phoneNum = $("#mobile").val().trim();

                /* 調註冊接口 */
                $.ajax({
                    type: 'post',
                    url: 'register.php',
                    data: {
                        name: username,
                        pass: password,
                        repass: repeatPassword,
                        code: code,
                        mobile: phoneNum
                    },
                    dataType: 'json',
                    // beforeSend: function() {
                    //     /* 顯示正在提交 不能再次發送(防止重複提交)*/
                    //     $btn.val('正在提交...').addClass('disabled');
                    // },
                    success: function(data) {
                        /* 當接口成功 */
                        /* 狀態碼 10000 成功 */
                        if (data.code == 10000) {
                            /* 提示+跳轉登陸頁 */
                            showTip('恭喜' + data.result.name + '註冊成功,3後秒自動前往登陸頁');
                            setTimeout(function() {
                                location.href = 'http://www.baidu.com/';
                            }, 3000);
                        } else if (data.code == 10001) {
                            /* 輸入框提示 */
                            $('.error').html('用戶名已註冊');
                            /* 恢復按鈕 */
                            $btn.val('當即註冊').removeClass('disabled');
                        } else if (data.code == 10002) {
                            showTip('請輸入用戶名');
                            /* 恢復按鈕 */
                            $btn.val('當即註冊').removeClass('disabled');
                        }
                    },
                    error: function() {
                        showTip('系統繁忙!');
                        $btn.val('當即註冊').removeClass('disabled');
                    }
                })
            });
        });
    </script>
</body>

</html>

效果圖:

image

10. jQuery 插件的使用

插件: pluginjQuery不可能包含全部的功能,因此就出現了成百上千的插件,幫助咱們擴展 jQuery的功能。

最新最全的插件能夠參考jQuery官方網站的插件版塊

10.1 顏色插件-jQuery.color.js

animate不支持顏色的漸變,可是使用了 jquery.color.js後,就能夠支持顏色的漸變了。

使用步驟:

  • 先引入jQuery,再引入jquery.color.js
  • 使用插件
<!-- 引入js -->
<script src="../js/jquery-3.2.1.min.js"></script>
<script src="../js/plugins/jquery.color.js"></script>

<!-- 樣式部分 -->
<style>
    .box {
        width: 300px;
        height: 300px;
        background: aquamarine;
    }
</style>

<!-- html 部分 -->
<input type="button" id="btn" value="點擊過渡">
<div class="box"></div>

<!-- js 部分 -->
<script>
    $(function() {
        $('#btn').click(function() {
            $('.box').animate({
                backgroundColor: "#f45f45"
            }, 1000);
        });
    });
</script>

10.2 懶加載插件- jquery.lazyload.js

什麼是懶加載?

懶加載也就是延遲加載。當訪問一個頁面的時候,先把 img元素或是其餘元素的背景圖片路徑替換成一張大小爲 1*1px圖片的路徑(這樣就只需請求一次,俗稱佔位圖),只有當圖片出如今瀏覽器的可視區域內時,才設置圖片正真的路徑,讓圖片顯示出來。這就是圖片懶加載。

爲何要使用懶加載?

不少頁面,內容很豐富,頁面很長,圖片較多。好比說各類商城頁面。這些頁面圖片數量多,並且比較大,少說百來K,多則上兆。要是頁面載入就一次性加載完畢。估計你們都會等到黃花變成黃花菜了。

懶加載的原理是什麼?

頁面中的 img元素,若是沒有 src屬性,瀏覽器就不會發出請求去下載圖片,只有經過 javascript設置了圖片路徑,瀏覽器纔會發送請求。

懶加載的原理就是先在頁面中把全部的圖片統一使用一張佔位圖進行佔位,把正真的路徑存在元素的「data-url」(這個名字起個本身認識好記的就行)屬性裏,要用的時候就取出來,再設置;

懶加載的實現步驟?

首先,不要將圖片地址放到 src屬性中,而是放到其它屬性( data-url)中。

頁面加載完成後,根據scrollTop判斷圖片是否在用戶的視野內,若是在,則將data-url屬性中的值取出存放到src屬性中。

在滾動事件中重複判斷圖片是否進入視野,若是進入,則將data-url屬性中的值取出存放到src屬性中。

插件使用:

  • 首先,這裏圖片的自定義屬性就要用data-original
  • jQ中找到圖片元素,給它加上一個lazyload()函數。
<!-- 樣式部分 -->
<style>
    center {
        margin-top: 1200px;
    }
    
    div {
        margin-bottom: 10px;
    }
    
    img {
        width: 500px;
        height: 350px;
    }
</style>

<!-- html 部分 -->
<center id="box">
    <div><img src="" data-original="http://ww1.sinaimg.cn/large/9c47d583gy1fjgqik3k1kj211y0lcdji.jpg" alt="當你看不見圖片的時候,你纔會看到這裏的字"></div>
</center>

<!-- js 部分 -->
<script>
    $(function() {
        //使用插件
        $("img").lazyload();
    });
</script>

10.3 jQuery UI 插件

jQuery UI 是一個創建在 jQuery JavaScript 庫上的小部件和交互庫,您可使用它建立高度交互的 Web 應用程序。

下載地址:點擊這裏跳轉到官網下載

10.4 jQuery自定義插件

雖然網上的插件有不少,可是可能不是咱們徹底想要的,其中可能還穿插着其餘的功能,因此咱們也能夠本身封裝一個 jQuery插件,

有三種方式爲全部jQuery對象添加方法,在建立一個jQuery插件的時候,咱們只須要將添加的方法保存爲一個js文件,再去引用它便可。

一、$.prototype方法添加

$.prototype.setStyle = function(){

};

二、$.fn.setStyle方法添加

$.fn.setStyle = function(){

        };

三、$.fn.extend({})方法添加

// extend能夠新增多個方法
$.fn.extend({
    setStyle:function(){

    },
    setPosition:function(){
        
    }
});

示例代碼:

經過上面三種方法的任何一種,爲 jQuery添加一個插件 setStyle

建立插件jquery.setStyle.js

// 給jQuery裏面添加一個setStyle方法
// (function(){})()的做用是函數自調用,避免全局污染。是一種設計模式:沙箱模式
(function(){
    $.fn.setStyle = function(){
        this.css({
            width:400,
            height:400,
            backgroundColor:"pink"
        });
        return this;
    }

})()

使用插件:

<div id="box"></div>

<script src="jquery.min.js"></script>
<script src="jquery.setStyle.js"></script>
<script>
    // 彈出123
    $("#box").setStyle();
</script>

沙箱模式(function(){})()的做用是函數自調用,避免全局污染。是一種設計模式:沙箱模式

10.5 jQuery自定義插件-瀑布流插件

jQuery封裝一個瀑布流插件,前面特效篇已經講過了瀑布流的原理,不明白的小夥伴,建議先去看看原生實現的原理( 《原生js實現瀑布流效果》),再來學習 jQuery封裝。

主頁面部分:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>瀑布流</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            font-family: "Microsoft Yahei";
            background: #f5f5f5;
        }
        .box {
            width: 1200px;
            margin: 0 auto;
            padding-top: 40px
        }
        .box > .items {
            position: relative;
        }
        .box > .items > .item {
            width: 220px;
            box-shadow: 2px 2px 2px #999;
            position: absolute;
        }
        .box > .items > .item > p {
            margin: 0;
            padding: 10px;
            background: #fff;
        }
        .box > .items > .item > img {
            width: 100%;
            display: block
        }
        .box > .btn {
            width: 280px;
            height: 40px;
            margin: 30px auto;
            text-align: center;
            line-height: 40px;
            background-color: #CCC;
            border-radius: 6px;
            font-size: 24px;
            cursor: pointer;
        }
        .box > .loading {
            background-color: transparent;
        }
        
    </style>
</head>

<body>
    <div class="box">
        <div class="items">
            <div class="item">
                <img src="image/001.jpg" alt="">
                <p>雲想衣裳花想容,春風拂檻露華濃。若非羣玉山頭見,會向瑤臺月下逢。</p>
            </div>
                    .
                    .
                    .
            <div class="item">
                <img src="image/030.jpg" alt="">
                <p>雲想衣裳花想容,春風拂檻露華濃。若非羣玉山頭見,會向瑤臺月下逢。</p>
            </div>

        </div>
        <div class="btn">正在加載...</div>
    </div>

    <script src="jquery.min.js"></script>
    <script src="jquery.waterfull.js"></script>
    <script>
        // 必定要寫在入口函數內,保證圖片加載完在計算高度
        window.onload = function(){
            $(".items").waterfull();
        }
    </script>
</body>

</html>

封裝插件jquery.waterfull.js:

(function(){
    $.fn.waterfull = function(){
        // 1-肯定要排多少列
        var columns = 5;

        // 2-獲取每個元素的寬度
        // this指的是當前調用的對象items 要獲取的是item的寬度
        var width = this.children().width();

        // 3-計算間隔 gap:左右間隔 gap_t:上下間隔
        var gap = (this.width() - width * columns) / (columns - 1);
        var gap_t = 10;
        // 4-聲明一個數組,用來存放全部item的高度值
        var heightArr = [];
        
        // 5-遍歷全部item
        this.children().each(function(index,ele){
            // 5-1 排列第一行
            // 判斷當前遍歷的item索引小於列數的時候,說明是第一行
            if(index < columns){
                // 將ele對象轉化成DOM對象,再設置它的top 和 left
                $(ele).css({
                    top:0,
                    left:index * (width +gap)
                });
                // 5-2 將第一行每個item的高度存到數組中
                heightArr.push($(ele).height());
            }else{
                // 5-3 計算heightArr數組裏面的最小值,並記錄下最小值的列數即索引
                var minHeight = heightArr[0];
                var minIndex = 0;
                $.each(heightArr,function(index,value){
                    if(minHeight > value){
                        minHeight = value;
                        minIndex = index;
                    }
                });

                // 5-5 當剩下的item排在最小列下面的時候,要在數組中,跟新這個最小列的高度
                heightArr[minIndex] += $(ele).height() + gap_t;
 
                // 5-4 排列剩下的行數,下面的item放到上一行最小高度的下面,依次列推
                // 設定定位的top值, 10 是上下的間距
                var top = minHeight + gap_t;
                // 設定定位的left值,即高度最小列的索引乘以item的寬度加上間隙
                var left = minIndex * (width + gap);
                $(ele).css({
                    top: top,
                    left: left
                });
            }
            
            // 6-設置加載按鈕的位置,只須要將items設置一個高度便可
            // 加載按鈕的位置應該在heightArr數組裏最大高度值的哪個item的下面
            var maxHeight = heightArr[0];
            $.each(heightArr,function(index,value){
                maxHeight = maxHeight > value ? maxHeight : value;
            });
            // 設置items的高度 this指的是每個item
            $(this).parent().height(maxHeight);
        })
    }
})()

上一篇:jQuery 入門詳解(一)

相關文章
相關標籤/搜索