前端開發【第6篇:JavaScript客戶端(瀏覽器)】

Web瀏覽器中的JavaScript

客戶端JavaScript時間線javascript

一、Web瀏覽器建立Document對象,而且開始解析web頁面,解析HTML元素和它門的文本內容後添加Element對象和Text節點到文檔中。在這個階段Document.readystate屬性的值是「loading」css

二、當HTML解析器遇到沒有async和defer屬性的<script>元素時,它把這些元素添加到文檔中,而後執行內火外部腳本。這些腳本會同步執行,而且在腳本下載(若是須要)和執行時解析器會暫停,由於JavaScript是單線程的。這樣腳本就能夠用Document.write()來吧文本插入到輸入流中。解析器恢復時這些文本會成爲文檔的一部分。同步腳本常常簡單定義函數和註冊後面試用的註冊事件處理程序,但它們能夠遍歷和操做文檔書,由於它們執行時已經存在了。html

三、解析器遇到了設置了async屬性的<script>元素時,它開始下載腳本,並繼續解析文檔。腳本在它下載完成後儘快執行,可是解析器沒有停下來等它下載,異步腳本禁止使用document.write()方法。java

四、當文檔完成解析,document.readyState屬性變成「interactive」node

五、全部defer屬性的腳本,會按照它們在文檔裏的出現順序執行。異步腳本可能也會在這個時間執行,延遲腳本能訪問完成的文檔書,禁止使用document.write()jquery

六、瀏覽器在Document對象上觸發DOMContentLoaded事件,這標誌着程序執行從同步腳本執行階段轉換到異步事件驅動時間階段。可是要注意,這時可能還有異步腳本沒有執行完。程序員

七、這時,文檔已經徹底解析完成,可是瀏覽器還在等待其餘內容載入,如圖片。當全部的內容完成載入時,而且全部異步腳本載入和執行,document.readyState屬性改變爲"complete",Web瀏覽器觸發Windows對象上的load事件。web

八、今後刻起,會調用異步事件,以異步響應用戶輸入事件、網絡事件、計時器過時等面試

以上爲一條理想的時間線,可是並非全部的瀏覽器都支持並完成了所有細節可是大部分都支持ajax

JavaScript不能作什麼

一、JavaScript程序能夠打開一個新的瀏覽器窗口,可是爲了防止廣告商濫用彈出窗口,不少瀏覽器限制了這個功能,是的只有爲了響應鼠標單擊這樣的用戶觸發時間的時候才能使用它

二、JavaScript程序能夠關閉本身打開的瀏覽器窗口,可是不容許它不通過用戶確認就關閉其餘的窗口

三、HTML FileUpload元素的value屬性是隻讀的,若是能夠設置這個屬性,腳本就能設置它爲任意指望的文件名,從而致使表單上傳指定文件(好比密碼文件)的內容到服務器

四、腳本不能讀取從不一樣服務器載入的文檔內容,除非這個就是包含改腳本。這個就防止來自其餘不一樣服務器上的文檔時間監聽器,防止竊取用戶輸入,這個限制叫同源策略

 

同源策略及其規避方法

1995年,同源政策由 Netscape 公司引入瀏覽器。目前,全部瀏覽器都實行這個政策。

最初,它的含義是指,A網頁設置的 Cookie,B網頁不能打開,除非這兩個網頁"同源"。所謂"同源"指的是"三個相同"。

  • 協議相同
  • 域名相同
  • 端口相同

 舉例來講,http://www.example.com/dir/page.html這個網址,協議是http://,域名是www.example.com,端口是80(默認端口能夠省略)。它的同源狀況以下。

  • http://www.example.com/dir2/other.html:同源
  • http://example.com/dir/other.html:不一樣源(域名不一樣)
  • http://v2.www.example.com/dir/other.html:不一樣源(域名不一樣)
  • http://www.example.com:81/dir/other.html:不一樣源(端口不一樣)

同源政策的目的,是爲了保證用戶信息的安全,防止惡意的網站竊取數據。

設想這樣一種狀況:A網站是一家銀行,用戶登陸之後,又去瀏覽其餘網站。若是其餘網站能夠讀取A網站的 Cookie,會發生什麼?

很顯然,若是 Cookie 包含隱私(好比存款總額),這些信息就會泄漏。更可怕的是,Cookie 每每用來保存用戶的登陸狀態,若是用戶沒有退出登陸,其餘網站就能夠冒充用戶,隨心所欲。由於瀏覽器同時還規定,提交表單不受同源政策的限制。

因而可知,"同源政策"是必需的,不然 Cookie 能夠共享,互聯網就毫無安全可言了。

  • Cookie、LocalStorage 和 IndexDB 沒法讀取。
  • DOM 沒法得到。
  • AJAX 請求不能發送。

Cookie 是服務器寫入瀏覽器的一小段信息,只有同源的網頁才能共享。可是,兩個網頁一級域名相同,只是二級域名不一樣,瀏覽器容許經過設置document.domain共享 Cookie。

舉例來講,A網頁是http://w1.example.com/a.html,B網頁是http://w2.example.com/b.html,那麼只要設置相同的document.domain,兩個網頁就能夠共享Cookie。

 

Ajax

同源政策規定,AJAX請求只能發給同源的網址,不然就報錯。

除了架設服務器代理(瀏覽器請求同源服務器,再由後者請求外部服務),有三種方法規避這個限制。

  • JSONP
  • WebSocket
  • CORS

 

同源政策規定,AJAX請求只能發給同源的網址,不然就報錯。舉個例子:

我如今起了兩個Django: 127.0.0.1:8000   另外一個Django:127.0.0.1:8001 端口不一樣也是跨域操做

在127.0.0.1:8000 上使用Ajax訪問127.0.0.1:8001的時候就會提示報錯

        $.ajax({
            url: "http://127.0.0.1:8001/test_json",
            async : false,
            type: 'GET',
            dataType: 'json',
            success: function(data){console.log('success', data)},
            error: function (data) {console.log('error', data)}
        })

如何解決?

Web頁面上調用js文件時則不受是否跨域的影響,並且擁有」src」這個屬性的標籤都擁有跨域的能力,好比<script>、<img>、<iframe>,這時候,聰明的程序猿就想到了變通的方法,若是要進行跨域請求, 經過使用html的script標記來進行跨域請求,動態生成<script>標籤稱之爲:JSONP(JSON with Padding)

JSONP(JSONP - JSON with Padding是JSON的一種「使用模式」),利用script標籤的src屬性(瀏覽器容許script標籤跨域),經過動態建立一個script標籤,指定src屬性爲跨域的api,那麼html會把返回的字符創看成javascript代碼來進行解析,若是咱們在返回的字符串中使用自定義函數形式包裝起來,而後在html中調用自定義函數,便可拿到返回的字符串
 
客戶端:127.0.0.1:8000
    <script>
        // 設置回調函數
        var callbackHandler = function(data){
            console.log("服務端返回的數據是:", data);
        };

        function getContent(){
        // 跨域訪問的API 並指定回調函數
        var url = "http://127.0.0.1:8001/test_json?callback=callbackHandler";  //
        // 建立script標籤,並設置其屬性
        var script = document.createElement('script');
        script.setAttribute('src', url);
        // 把script標籤加入head,此時調用開始
        document.getElementsByTagName('head')[0].appendChild(script);
        }

    </script>

動態生成<script>標籤並指定回調函數,這樣就能夠跨域請求API了,這是一個歷史遺留的BUG吧算是,藉助src的跨域特性模擬請求

服務端127.0.0.1:8001

def test_jsonp(request):
    print("請求方法爲:", request.method)  # 請求方法爲:GET
    func = request.GET.get('callback')  # 獲取回調函數
    content = '%s(100000)' % (func,)  # 拼接爲執行 callbackHandler(100000)  
    """
    在這裏咱們看下咱們能夠在這裏指定返回結果:callbackHandler(100000)
    固然也能夠增長其餘的內容好比: callbackHandler({"name": "shuaige", "age": 18})
    客戶端接收到請求後調用回調函數並把咱們放進去的數據加載上,因此使用JSONP跨域也是須要協商一下才能夠
    """
    
    print("結果是:", content)  # callbackHandler(100000)
    return HttpResponse(content)  # 返回

 

梳理下步驟:

一、動態生成<script>標籤封裝src屬性,指定API和回調函數

二、服務端接收到請求後在接收的回調函數中封裝數據並返回(這裏就明確了並非你使用了jsonp的方式就可能夠了,而是須要與服務器進行協商回調函數才能夠)

三、經過回調函數和服務端封裝返回的數據執行回調函數

 

jQuery已經幫咱們封裝好了的jsonp,Server端不變來看如何使用jQuery發送jsonp請求
    <script>
        // 設置回調函數
        var callbackHandler = function(data){
            console.log("服務端返回的數據是:", data);
        };

        function getContent(){
            $.ajax({
                url: "http://127.0.0.1:8001/test_json",
                type: 'GET',
                dataType: 'jsonp',  // 數據格式爲jsonp
                jsonp: 'callback',  // 發送給服務端的回調函數變量名
                jsonpCallback: 'callbackHandler'  // 發送給服務端的回調函樹的函數名稱
                // jsonp: 'callback', jsonpCallback: 'callbackHandler' 相似 {"callback": "callbackHandler"}
            })
        }

    </script>

 

WebSocket  和 CORS 後續補充

Windows對象

先看看整個瀏覽器架構是什麼樣的,瀏覽器實現了JavaScript的規範能夠解析JavaScript並經過JavaScript進行管理  好奇發展的話:能夠看  http://www.cnblogs.com/luotianshuai/p/7504347.html

windows對象包含文檔對象:Document 它主要處理頁面    其餘的windows大可能是對瀏覽器級別的操做,能夠先這麼理解,在瀏覽器大戰期間國際組織對各大瀏覽器共有的操做標準document頁面操做進行了標準化:DOM 它是一個標準

知道它們之間的關係後繼續看windows吧

計時器

setTimeout()和setInterval()能夠用來註冊在指定的時間以後單詞或重複調用的函數,雖然他是windows對象的方法可是不會對窗口作什麼事情。

setTimeout()方法用來實現一個函數在指定的毫秒數以後運行

setInterval()和steTimeout同樣,只不過這個函數會在指定的毫秒數的間隔裏重複調用

/*
function invoke(f, start, interval, end) {
    if (!start) start = 0;
    if (arguments.length <= 2){
        setTimeout(f, start)
    } else{
      setTimeout(repeat, start);  // 在若干毫秒後調用repeat
      function repeat() {
          let h = setInterval(f, interval);  //循環調用f()  間隔interval秒調用一次f
          // 在end毫秒後中止調用,前提是end定義了
          if (end) setTimeout(function () { clearInterval(h);}, end)
      }
    }
}
function sayHello() {
    console.log("Hello World")
}

invoke(sayHello, 10000, 66, 100);

*/
function sayHello() {
    console.log("Hello World")
}

function clearIntervalFunc(obj) {
    clearInterval(obj)
}

setTimeout(sayHello, 1000); // 在第10秒後調用一次sayHello函數
let sayHelloObject =  setInterval(sayHello, 1000); // 每隔10秒調用一次sayHello 函數
setTimeout(clearIntervalFunc,  10000, sayHelloObject);  // 10秒以後清掉函數

瀏覽器定位和導航

window對象的location屬性引用的是Location對象,Document的location屬性也是引用的Location對象。它表示該窗口顯示文檔的URL,並定義了方法來使窗口載入新文檔。

Location對象的href屬性返回的是當前URL的字符串

window.location.href
"https://www.sogou.com/web?query=%E6%94%AF%E4%BB%98%E5%AE%9D&_asf=www.sogou.…505872944052%2C1505872944707&sugsuv=1497014300786074&sugtime=1505872945685"

Location對象的其餘屬性:protocal, host, hostname, port, pathname 和search,分別表示URL的各個部分,它們稱之爲"URL分解" 屬性

在這些屬性中:hash和search屬性比較有趣,hash返回片斷標識符若是有的話(片斷標識符也就是錨點),search就是URL問號部分來看

window.location.search
"?query=%E5%B8%85%E5%93%A5&ie=utf8&_ast=1505873792&_asf=null&w=01029901&p=40040100&dp=1&cid=&cid=&s_from=result_up&sut=3003&sst..........300786074&sugtime=1505873945616"

 

解析URL參數實例

function urlArgs() {
    let args = {};  // 建立一個對象
    let query = location.search.substring(1);  // 查找查詢次並去掉第一個"?"問號
    let pairs = query.split('&');  // 經過&分割爲一個數組
    for (let i =0; i < pairs.length; i++ ){  // 循環
        let pos = pairs[i].indexOf('=');  // 找到每一個數組元素字符串=的下標
        if (pos === -1) continue;
        let name = pairs[i].substring(0, pos);  // 若是能找到=那就分割name爲小標0到=值
        let value = pairs[i].substring(pos+1);  // 取出後面的值
        value = decodeURIComponent(value);  // 對value進行解碼
        args[name] = value;  // 存儲爲屬性
    }
    return args
}

載入新文檔

Location對象的assign()方法可使窗口載入並顯示你指定的URL中的文檔,replace()方法也相似可是他會刪除歷史記錄(意思就是你不能用返回鍵返回上一次訪問的歷史網頁)

location = "http://www.sogou.com";  // 跳轉到搜狗
locaiton = "page2.html";  //跳轉到這個頁面
location = "#top";  // 跳轉到文檔頂部

瀏覽歷史

Windows對象的history對象引用的是該窗口的History對象,history的back()和forward()方法與瀏覽器的後退和前進同樣 NICE,還有一個方法go接收一個正負數,來進行前進和後退

window.history.go(-3);  // 後退3個歷史記錄
window.history.back();  // 後退一個歷史記錄 
window.history.forward();  // 前進一個歷史記錄

瀏覽器和屏幕信息

window對象的Navigator屬性引用包含了瀏覽器廠商和版本信息的Navigator對象,Navigator對象的命名是爲了記念Netscape以後的Navigator瀏覽器

window.navigator.appName  // Web瀏覽器全稱微軟的是Microsoft Internet Explorer,其餘廠商了爲了兼容現存的瀏覽器嗅探通常都是Netscape
"Netscape"

window.navigator.appVersion  // 查看瀏覽器版本
"5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"

window.navigator.userAgent  // 瀏覽器在它的USER-AGENT http頭部中發送的字符串
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"

/* 
userAgent 包含appVersion中全部的內容,並也可能包含其餘細節,由於信息比較全,瀏覽器嗅探代碼一般用它來嗅探
*/

window.navigator.platform  //瀏覽器運行在哪一個系統上
"Win32"


window.navigator.onLine  // 表示瀏覽器是否聯網 0 0 
true

screen對象屬性引用的是Screen對象。它提供有關窗口顯示的大小和可用的顏色數量信息。屬性width和height指定的是以 項數爲單位的窗口大小。屬性availwidth和availheight指定的是實際可用的顯示大小

screen屬性和引用screen都是非標準實現的能夠經過其判斷是否在小屏幕上運行

對話框

windows對象提供了3個方法alert() 向用戶提示一條消息等待用戶關閉對話框  / confirm()也是顯示一條消息,要求用戶點擊「肯定」或「取消」按鈕並返回一個布爾值

prompt()一樣也是顯示一條消息,等待用戶輸入字符串並返回字符串,還有一個showModalDialog()有用的嗎?

做爲Windows對象屬性的文檔元素

若是在HTML文檔中用id屬性來爲元素命名,而且若是Window對象沒有此名字的屬性,Window對象會賦予一個屬性,他的名字是id屬性的值,而他們的值指向表示文檔元素的HTMLElement對象

舉個例子來講若是文檔包含<button id="okay">元素,能夠經過全局變量okay來引用此元素。可是若是window已經有了這個屬性就不能夠了,元素id做爲全局變量的隱式應用是Web瀏覽器演化過程當中遺留的怪癖。他主要是出於與已有Web頁面向後兼容考慮的,因此不建議使用這種方法,推薦用document.getElementByID()來顯示查找元素,後面會學到更簡單的jQuery,來獲取元素

多窗口和窗體

Window對象的open()方法能夠打開一個新的瀏覽器窗口(或標籤頁,這一般和瀏覽器配置選項有關),它有4個可選的參數

第一個參數:是顯示文檔的URL若是爲空打開一個空白頁URL about: blank

第二個參數:窗口的名字

第三個參數:窗口屬性參數  window.open("http://sogou.com", "搜狗", "width=400,height=400,status=yes,resizabel=yes")

第四個參數:通常與第二參數同時使用,若是窗口已經存在仍是新窗口

 

關閉也很簡單window.close

腳本化文檔

客戶端JavaScript的存在使靜態HTML頁面文檔變成了交互式的WEB應用。腳本化WEB頁面內容是JavaScript核心目標

腳本化可使 宿主 程序具備 腳本 所描述的能力,好比流行在 DHTML 頁面中的 JavaScript 技術,JavaScript 可讓本來是靜態的 HTML 代碼的頁面「活」起來,具備動畫,局部刷新等更高級的功能。應用程序通常是以二進制的形式發佈的,用戶很難根據本身的需求對其進行定製,固然,修改配置文件是一種方式,可是不夠靈活。而腳本化則是經過用戶本身設計腳本(程序代碼 ),而後將其 注入 到應用中,使得應用的行爲獲得改變。

window包含一個document屬性應用了Document對象,Document對象表示窗口內容 它是一個瀏覽器對外提供的一個巨大的操做文檔內容的API,叫作文檔對象模型(Document Object Model, DOM)它表明操做文檔的內容

選取文檔元素

經過id獲取元素

// 經過id獲取元素
let selection =document.getElementById("selection");
// 經過元素name屬性獲取元素
let radibuttons = document.getElementsByName("favorite_color");
// 經過標籤獲取元素
let spans = document.getElementsByTagName("span");  // 返回的是一個NodeList對象
// 經過Css 類 class獲取
let log = document.getElementsByClassName("log");  // 獲取包含log CSS類的元素
let fatal = document.getElementsByClassName("fatal error");  // 獲取fatal Css類中包含子類error的元素

做爲節點樹的文檔

Document對象、它的Element對象和文檔中表示文本的Text對象都是Node對象。Node定義了一下重要屬性:

  • parentNode:該節點的父節點,或者針對相似Document對象應該是null,由於它沒有父節點
  • childNodes:只讀的類數組對象(NodeList對象),它是該節點的子節點的實時表示
  • firstChild、lastChild: 該節點的子節點中的第一個和最後一個元素,若是該節點沒有子節點則爲null
  • nextsibling、previoursSibling該節點的兄弟節點中的前一個和下一個
  • nodeType:該節點類型9表明Document節點,1表明Element節點,3表明Text節點,8表明Coment節點11表明DocumentFragment節點
  • nodeValue:Text節點或Comment節點的文本內容
  • nodeName:元素的標籤名,以大寫形式表示

 屬性

每一個元素都是一個Node節點這個搞明白以後在就是,每一個元素的屬性經過結構化文檔以後每一個元素都是一個JavaScript對象裏面的Css和src都是對象的一個屬性key=value的值而已,搞明白這個旅順先後就會通透多了

獲取元素後在獲取屬性

let image = document.images[0];  // 獲取第一個元素
let widt = parseInt(image.getAttribute("width"));  // 從元素對象中獲取屬性
image.setAttribute("class", "shuaige");  // 在元素對象中添加屬性

既然是對象固然也能夠經過對象的方式獲取

document.body.attributes[0]  // <body>元素的第一個屬性
document.body.attributes.bgcolor  // <body> 元素的bgcolor屬性
document.body.attributes['ONLOAD']  // <body>元素的onload屬性

文本

let fristH1 = document.getElementsByTagName("h1")[0];  // 獲取第一個H1標籤
let fristChildH1 = fristH1.children[0];  // 獲取H1標籤的第一個元素
/*
fristChildH1.textContent  // 輸出他的內容
<a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/luotianshuai/">Mr.心絃</a>
*/

建立刪除節點

建立node經過

let s = document.createElement("script");  // 建立一個<script>元素
s.src = "http://sogou.com";   // 設置它的src屬性值
// 而後經過append添加元素或者插入元素

建立文本node節點經過  document.createTextNode("<h1>帥哥</h1>")

 

fristClass1.appendChild(document.createTextNode("<h1>帥哥</h1>"))

 

添加元素

// 獲取第一個應用了 class = day的元素
let fristDiv = document.getElementsByClassName("day")[0];
// 建立一個元素
let shuai = document.createElement("h1");
shuai.textContent= '大帥哥';
// 添加元素經過appendChild
fristDiv.appendChild(shuai);

// ------------------------------------------------------------------------------

let fristDiv = document.getElementsByClassName("day")[0];
let shuai = document.createElement("h1");
shuai.textContent= '大帥哥';


fristDiv.insertBefore(shuai, null) // 它接收兩個參數第一個參數是待被插入的node節點,若是第二個參數爲null,則相似appendChild

// 若是指定了第二個參數(爲node對象)則會在它前面插入
fristDivChild = fristDiv.children[0];

// 插在第一個元素前面
fristDiv.insertBefore(shuai, fristDivChild); 

注:這裏若是將要被添加的元素已經存在了,就相似於remove操做,且若是被添加的元素在將要被添加的元素位置已經存在那麼就會從新添加一次覆蓋原有的,這裏是對象相同,若是對象不相同不會覆蓋

刪除和替換節點

fristDiv.remove();  // 刪除本身的node對象
fristDiv.appendChild(shuai);  // 刪除本身的兒子對象

// --------------------------------------------------------------------
// 獲取第一個div元素
let fristDiv = document.getElementsByClassName("day")[0];
// 獲取第一孩子元素
fristDivChild = fristDiv.children[0]
// 建立一個新node對象,也就是元素
createH1 = document.createElement("h1");
// 給node對象添加textContent屬性和值
createH1.textContent = '大帥哥';  

// 替換
fristDiv.replaceChild(createH1, fristDivChild);  // 接收兩個參數第一個參數是新元素,第二個元素是要被替換的元素

文檔滾動條和窗口

把窗口比做一個X,Y軸的座標來體現

獲取其滾動條位置:

X軸爲從左到右的軸值,Y軸爲從上到下的軸值

window.pageXOffset
0
window.pageYOffset
0

查詢窗口尺寸

window.innerHeight;
426
window.innerWidth
1920
window.innerHeight;
581

獲取某個元素的座標值

tag.getBoundingClientRect();
ClientRect {top: 86, right: 503.03125, bottom: 127, left: 438.03125, width: 65…}  // 上下左右,這個對比值是離windows窗口的上下左右值

滾動

scrollby()   scroll()   scrollTo()  就是根據上面的座標進行滾動,咱們能夠接收一個函數

腳本化CSS和腳本化文檔相似

JavaScript事件

客戶端JavaScript程序採用了異步事件驅動編程模型。在這種程序設計風格下,當文檔、瀏覽器、元素或與之相關的對象發生某些有趣的事情時,Web瀏覽器就會產生事件(event)

事件自己不是一個不須要定義的技術名詞,且不是JavaScript對象,不會出如今程序源碼中,固然,會有一些事件相關的對象出如今源碼中

事件類型(event type):是一個用來講明發生了什麼類型事件的字符串。 好比「mousemove」 表示用戶移動鼠標

事件目標(event target):是發生的事件閾值相關的對象。  當事件發生時咱們好比致命類型和目標   ,例如window 上的load事件或<button>元素的Click事件。

事件處理程序(event handler)或事件監聽程序(event listener)是處理貨響應時間函數。應用程序經過致命時間類型和時間目標,在Web瀏覽器中註冊它們的時間處理程序函數

事件對象(evnet object):是與特定時間相關且包含有關該事件詳細信息的對象。時間對象做爲參數傳遞給時間處理程序。全部事件對象都有用來指定時間類型的type屬性和指定時間目標的target屬性。

事件傳播(event propagation):是瀏覽器決定那個對象觸發其時間處理程序的過程。

接下來看看下面事件

  • 文檔加載和準備就緒事件
  • 鼠標事件
  • 鼠標滾輪事件
  • 鍵盤事件
  • 文本輸入事件

事件類型

事件類型能夠分紅如下幾類,瞭解這些分類有助於理解和組織長長的事件列表

依賴於設備的輸入事件

有些事件和特定輸入輸出設備直接相關,好比鼠標和鍵盤包括:

"mousedown"、"mousemove"、"mouseup"、"keydown"、"keypress"和"keyup"這同樣傳統的事件類型,也包括像"touchmove"和"geturechange"這樣新的觸摸事件類型

獨立於設備的輸入事件

有寫輸入事件沒有直接指定相關的特定輸入設備。例如,click事件表示激活了連接、按鈕或其餘文檔元素,這一般是經過鼠標單擊事件,但也能經過鍵盤或觸摸板事件。

用戶界面事件

用戶頁面事件是比較高級的事件,一般出如今定義Web應用用戶界面的HTML表單元素上。包括文本輸入域獲取鍵盤焦點的focus事件、用戶改變表單元素顯示值的change事件和用戶點擊表單的「提交」按鈕的submit事件

狀態變化事件

有寫事件不是由用戶活動而是由網絡或瀏覽器活動出發,用來表示某種聲明週期或相關狀態的變化。當文檔徹底加載時,在Window對象上會發生load事件,這多是這類事件最經常使用的

特定API事件

HTML5及相關規範定義了大量的Web API都有本身的事件類型。拖放API定義了諸如「dragstart」、「dragenter」、「dragover」和「drop」事件,應用程序向自定義拖放源(drag source)或拖放目標(drop target)就必須處理這些相關事件。HTML5的<video>和<audio>元素定義了一長串想"wating"、"playing"、"seeking" 和「volumecacheng」等相關事件

計時器和錯誤處理程序

計時器(timer)和錯誤處理程序(error handler)

傳統事件類型

表單事件

表單在瀏覽器早期的時候對<form>表單支持算是最好的,當提交表單和重置表單的時候分別會觸發submit和reset事件。包括用戶在點擊複選框會觸發click事件輸入文字會觸發input事件等

window事件

window事件是指事件的發生與瀏覽器自己而非窗口顯示的任何特定文檔內容先關。可是,這些事件中有一些會和文檔元素上發生的事件同名

load事件:是這些事件中最重要的,當文檔和其餘全部外部資源(好比圖片)徹底加載並顯示給用戶時就會觸發

unload事件:和load相對,當用戶離開當前文檔轉向其餘文檔時會觸發它,unload事件處理程序能夠用於保存用戶的狀態,但他不能用於取消用戶轉向其餘地方

beforunload事件:的處理程序返回字符串,那麼在新頁面加載錢,字符串會展現給用戶對話框上用戶就有機會取消跳轉

<img>元素這樣的單個文檔元素也能爲load和error事件註冊處理程序

鼠標事件、鍵盤事件這倆事件很經常使用

鼠標事件由於太頻繁,因此必定不要用它處理密集運算,鍵盤和鼠標都有一個up和down的事件活用

註冊事件處理程序

註冊事件處理程序最簡單的方式就是經過設置事件目標的屬性爲所需事件處理程序的函數,按照約定,事件處理程序屬性的名字有「on」後面跟着事件名組成:onclick、onchange、onload、onmouseover等,注意這些屬性名是區分大消息的因此都是消息

// 設置window對象的unload屬性爲一個函數
// 該函數是事件處理程序:當文檔加載完畢時調用它
window.onload = function () {
    // 查找一個<form>元素
    let elt = document.getElementById("shipping_address");
    // 註冊事件處理程序函數
    // 在表單提交前調用它
    elt.onsubmit = function () {return console.log(this);}
};

設置HTML標籤屬性爲事件處理程序

<button onclick="alert('thank you');">點擊這裏</button>

有不少事件咱們可使用

屬性
此事件何時發生(何時被觸發
onabort     圖象的加載被中斷
onblur     元素失去焦點
onchange    區域的內容被修改
onclick 當用戶點擊某個對象時調用的事件句柄(比點擊input標籤時執行上面的代碼例子)
ondblclick 當用戶雙擊某個對象時調用的事件句柄
onerror   在加載文檔或圖像時發生錯誤
onfocus 元素得到焦點
onkeydown 某個鍵盤按鍵被按下
onkeypress 某個鍵盤按鍵被按下並鬆開
onkeyup 某個鍵盤被鬆開
onload 一張頁面或一副圖片完成加載
onmousedown 鼠標按鈕被按下 
onmousemove 鼠標移動過來後
onmouseout 鼠標從某個元素移開
onmouseover 鼠標移動到某個元素之上
onmouseup 鼠標按鍵被鬆開
onreset   重置按鈕被點擊
onresize  窗口或框架被從新調整大小
onselect  文本被選中
onsubmit  確認按鈕被點擊
onunload  用戶退出頁面

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

當指定了一串JavaScript代碼做爲HTML事件處理程序屬性的值時,瀏覽器會把代碼串傳喚爲相似下面的函數中

function (event) {
    with (document){
        with (this.form || {}){
            with (this){
                /* 這裏是編碼*/
            }
        }
    }
};

 

1)簡要說明  
       with 語句能夠方便地用來引用某個特定對象中已有的屬性,可是不能用來給對象添加屬性。要給對象建立新的屬性,必須明確地引用該對象。  

2)語法格式  
with(object instance)  
{  
        //代碼塊  
}  
       有時候,我在一個程序代碼中,屢次須要使用某對象的屬性或方法,照之前的寫法,都是經過:對象.屬性或者對象.方法這樣的方式來分別得到該對象的屬性和方法,着實有點麻煩,學習了with語句後,能夠經過相似以下的方式來實現:  
with(objInstance)  
{  
       var str = 屬性1;  
.....  
} 去除了屢次寫對象名的麻煩。  

addEventListener()

任何能稱爲事件目標的對象-這些對象包括window對象、document對象和全部文檔元素,都定義了一個名叫addEVentListener()方法,這個方法接收三個參數:

第一個參數是:何時觸發也就是事件名稱好比:click   它不該該用戶設置事件處理程序屬性的前綴"on"

第二個參數是:觸發事件以後對應的處理函數

第三個參數是:布爾值true/false 若是爲True的狀況下不予其餘事件並行,若是爲false的時候就能夠與其餘並行

這裏能夠經過addEventListener()註冊多個相同事件,可是若是參數相同的話只調用一次

相對應addEventListener()的是removeEventListener()方法,它一樣有三個參數,從對象中刪除事件處理程序函數而非添加,它經常使用於臨時註冊事件處理程序,而後不久後就刪除它

document.removeEventListener("mousemove", handleMouseMove, true);

事件調用順序

經過設置對象屬性或HTML屬性註冊的處理程序一直優先調用

經過addEventListener()註冊的處理程序按照他們註冊順序調用

經過attachEvent()註冊的處理程序可能按照任何順序調用,因此代碼不該該以來與調用順序

事件冒泡和綁定

    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>


/*
冒泡:
    看上面的ul元素,若是我想給每一個li添加事件怎麼辦?好比添加click事件
    每一個都加上?
    這個冒泡的做用就體現出來了,我在ul里加上一個事件,若是是冒泡規則的話,當咱們點擊li的時候就會往父級元素找事件
    若是父級Ul存在一個事件$ul.click(){}  這裏默認第一個參數爲event事件的.target屬性找到其子元素也就是li
    咱們就能夠經過這個進行操做了

    冒泡能夠說是從內到外

綁定也是同理從外到內
*/

jQuery

jQuery4種不一樣的調用方式

1. 傳遞css選擇器給$(),選擇器
$("div>p")
第二個參數,元素起始點

2. 傳遞HTML文本字符串給$(),將建立好的HTML元素封裝到jQuery對象
$("<image/>")
第二個參數,給元素屬性賦值
var img = $("<img/>",                            //建立一個image元素
                        {src:url,                            //定義元素屬性
                        css:{borderwidth:5},
                        click:check)
                        });

3. Element、Document、window對象給$(),一些特定的DOM元素,如經常使用的DOM對象:document、location、form
$(document).find("div>p").html()); 

4. 傳入一個函數給$()
$(function(){
});
複雜版:
$(document).ready(function(){
});
特殊用法:
jQuery.noConflict();        //還原$()爲初始值
jQuery(function($){            //讓$()成爲jQuery的局部別名
});

jQuery術語

jQuery函數:

jQuery函數就是jQuery或$()的值,該函數能夠用來建立jQuery對象,用來註冊DOM就緒時須要調用的處理陳故鄉,還用作jQuery命令空間,一般用$()來引用。他能夠用來作命名空間,所以jQuery函數也能夠稱之爲「全局jQuery對象」,但不要和「jQuery對象」混淆

jQuery對象:

jQuery對象是由jQuery函數返回的對象。一個jQuery對象表示一組文檔元素,也叫做「jQuery結果」、「jQuery集」或「包裝集」

選中元素:

傳遞給jQuery的選擇器

jQuery方法:

jQuery方法是由jQuery函數返回的jQuery對象的方法。jQuery類庫作重要的部分就是它定義的這些強大的方法。

jQuery的getter和setter

一、jQuery使用同一個方法既當getter用有來作setter用,而不是定義一對方法。若是傳入一個新值給該方法,則它設置此值;若是沒指定值嗎,則返回當前值

二、用做setter時,這些方法會給jQuery對象中的每個元素設置值,而後返回jQuery對象以方便鏈式調用。

三、用做getter時,這些方法只會查詢元素集中的第一個元素,返回單個值,getter不會返回調用自身的jQuery對象,所以他只能出如今鏈式調用的末尾

四、用做setter時,這些方法常常接受對象參數,在這種狀況下,該對象的每個屬性都指定一個須要設置的名/值對

五、用做setter時,這些方法常常接受函數參數,在這種狀況下,會調用該函數來計算須要設置的值。調用該函數時的this值是對應的元素,第一個參數是鈣元素的索引值,當前置則做爲第二個參數傳入

獲取和設置HTML屬性

    <script>
        $("form").attr("action");  // 獲取第一個form元素的action屬性
        $("#icon").attr("src", "icon.gif");  // 設置src屬性
        $("#banner").attr({  // 一次性設置4個屬性
            src:"icon.gif",
            alt:"advertisement",
            width:720, height:64
        });
        $("a").attr("target", "_blank");  // 使全部的連接在新窗口中打開
        $("a").attr("target", function () {
            // 使用setter時this值是對應的元素
            if (this.host === location.host){return "_self"
            }else{
                return "_blank"
            }
        });
        $("a").remove("target");  // 刪除元素的target屬性
    </script>

獲取或設置css屬性 

    <script>
        $("h1").css("font-weight");  // 獲取第一個<h1>元素的字體屬性
        $("h1").css("fontWeight");  // 也能夠採用駝峯式建議使用-
        $("h1").css("font");  // 錯誤不能夠獲取符合樣式
        $("h1").css("font-variant", "smallcaps");  // 將樣式設置在全部<h1>元素上
        $("div .note").css("border", "solid black 2px");  // 設置符合樣式是OK的
        $("h1").css({backgroundColor: "black", padding: "10px 2px 4px 20px"});  // 一次性設置多個樣式,且可使用駝峯式
        // 讓全部標籤<h1>的字體增大25%
        $("h1").css("font-size", function (i, curval) {
            // 這裏i是數組對象的下標值, curval 是當前對象的font-size的值
            return Math.round(1.25 * parseInt(curval))
        })
    </script>

獲取和設置css類

    <script>
        // 添加
        $("h1").addClass("hilite");  // 給全部的h1元素添加一個類
        $("h1+p").addClass("hilite first");  // 給<h1>後面的<p>添加兩個類
        $("section").addClass(function(n){  // 傳遞一個函數用來給匹配的每個元素添加自定義類
            return "section" + n ;
        });
        // 刪除
        $("p").removeClass("hilite");  // 從全部的<p>元素中刪除一個類
        $("p").removeClass("hilite first");  // 從全部的<p>元素中刪除2個類
        $("section").removeClass(function(n){  // 傳遞一個函數用來給匹配的每個元素刪除自定義類
            return "section" + n ;
        });

        // 切換css類
        $("#box").toggleClass("box2");  // 切換CSS類若是不存在則添加
        $("#box").toggleClass(function (n) {  // 切換用函數計算出來的類
            return "big bold h1-" +n ;
        });
        $("box").toggleClass("hilite", true);  // 相似於addClass
        $("box").toggleClass("hilite", false);  // 相似於removeClass

        // 檢測css類
        $("box").hasClass("first");  // 是否全部box元素都有改類
        $("box").is("first");  // 功能和上線相似
        $("box").is("first secede");  // is()比hasClass()更靈活
    </script>

在寫一個更換clss的小例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        .box1 {
            background-color: red;
            height: 100px;

        }
        .box2 {
            background-color: blueviolet;
            height: 1000px;
        }
    </style>
</head>
<body>
    <div id="box">
        shuaige
    </div>
    <script type="text/javascript" src="jquery-2.1.4.min.js"></script>
    <script type="text/javascript">
        $(function () {
            let boxObject = $("#box");
            boxObject.addClass("box1")
        });

        $("#box").bind("click", function () {
            // 轉換類,好玩
            $(this).toggleClass("box2")
        })
    </script>
</body>
</html>

設置和獲取元素內容

text和html方法用來獲取和設置元素的文本內容或HTML內容。

當不帶任何參數的時候:text()方法將獲取全部匹配的文本內容,html()方法將獲取全部匹配的第一個元素的HTML內容

 和其餘setter方法同樣,咱們還能夠傳入函數

        $("h1").text(function (n, current) {  // 給每個標題添加章節號
            // n 爲當前數組元素的下標    current爲當前元素的text內容
            return n + current
        });

        $("h1").html(function (n, current) {  // 給每個標題添加章節號
            // n 爲當前數組元素的下標    current爲當前元素的text內容
            return n + current
        })

獲取和設置元素的位置高度

使用offset()方法能夠獲取或設置元素的位置。該方法相對文檔來計算位置的值,返回一個對象,帶有left和top屬性,用來表示X和Y座標。若是傳入帶有這些屬性的對象給該方法,它會給元素設置指定的位置。在有必要時,會設置CSS的position屬性來使得元素可定位

修改文檔結構

HTML文檔表示爲一顆節點樹,而不是一個字符串的線性順序,所以插入、刪除、替換操做不會像操做字符串和數組一鍵更簡單

插入和替換元素

根據調用的方法不一樣,會在選中元素的(裏面、前面、後面)插入內容。若是帶插入的內容已經存在文檔的元素,會從當前位置移走它。若是他須要插入屢次,在必要時恢復至鈣元素

<script>
        $("#log").append("<br/>" + message);  // 在#log元素的內部尾部增長新內容
        $("h1").prepend("shuai");   // 在每一個<h1>的元素的內部的起始處添加章節標識
        $("h1").before("<hr/>");  // 在每一個<h1>的前面添加水平線
        $("h1").after("<hr/>");  // 在每一個<h1>後面添加水平線
        $("hr").replaceWith("<br/>");  // 替換<hr/>元素爲<br/>元素
        // 將h2替換爲h1,保持內容不變
        $("h2").each(function () {
            let h2 = $(this); // this表明循環的當前對象
            h2.replaceWith("<h1>" + h2.html() + "</h1>");
        });
        // 這是給每一個<h1>的開頭添加文章標識的另外一種方法
        $("h1").map(function () { return this.firstChild;}).before("帥")

    </script>

複製元素

    <script>
        // 經過方法clone來複制元素
        // 添加一個以"linklist" id的div
        $(document.body).append("<div id='linklist'<h1>list of Links</h1></div>");
        // 建文檔中的全部連接賦值並插入新的div中
        $("a").clone().appendTo("#linklist");
        // 在每個連接後面插入<br/>元素,使其以獨立行顯示
        $("#linklist > a").after("<br/>")
        /*
        clone()不會賦值事件處理程序和與元素相關的其餘數據,若是想複製這些數據,須要傳入true參數
         */
    </script>

包裝元素

插入HTML文檔的另外一種類型涉及在一個或多個元素中包裝新元素,jQuery定義了3個包裝函數:

  • wrap()包裝每個選中元素
  • wrapInner()包裝每個選中元素的內容
  • wrappAll()則將選中的元素做爲一組來包裝

這些方法一般傳入一個新建立的包裝元素或用來建立新包裝元素的HTML字符串,固然字符串中能夠包含多嵌套元素,若是傳入的函數給這些方法,它會在每一個元素的上下穩重調用一次,this一樣指向鈣元素。

<script>
        // 用<i>元素包裝全部的<h1>元素
        $("h1").wrap(document.createElement("i"));  // 產生<i><h1>...</h1></i>
        // 包裝全部<h1>元素的內容,是用字符串穿參更簡單
        $("h1").wrapInner("<i/>");  // 產生<h1><i>....</i></h1>
        // 將第一個段落包裝在一個錨點的div裏
        $("body>p:first").wrap("<a name='lead'><div class='first'></div></a>");
        // 將其餘段落包裝在另外一個div裏
        $("body>p:not(:first)").wrapAll("<div class='rest'></div>");

    </script>

刪除元素

empty()會刪除每一個選中元素的子節點,但不會修改元素自身,對比而言remove()方法會從文檔中溢出選中元素(以及全部元素內容),unwrap()方法能夠用來實現元素移除,其方法是wrap的反操做

jQuery事件

簡單的事件註冊方法

事件列表
屬性
此事件何時發生(何時被觸發
onabort     圖象的加載被中斷
onblur     元素失去焦點
onchange    區域的內容被修改
onclick 當用戶點擊某個對象時調用的事件句柄(比點擊input標籤時執行上面的代碼例子)
ondblclick 當用戶雙擊某個對象時調用的事件句柄
onerror   在加載文檔或圖像時發生錯誤
onfocus 元素得到焦點
onkeydown 某個鍵盤按鍵被按下
onkeypress 某個鍵盤按鍵被按下並鬆開
onkeyup 某個鍵盤被鬆開
onload 一張頁面或一副圖片完成加載
onmousedown 鼠標按鈕被按下 
onmousemove 鼠標移動過來後
onmouseout 鼠標從某個元素移開
onmouseover 鼠標移動到某個元素之上
onmouseup 鼠標按鍵被鬆開
onreset   重置按鈕被點擊
onresize  窗口或框架被從新調整大小
onselect  文本被選中
onsubmit  確認按鈕被點擊
onunload  用戶退出頁面

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

一、focus和blur事件不支持冒泡,可是focusin和focusout事件支持

二、相反的mouseover和mouseout事件支持冒泡,但這常常不方便,由於很難知道鼠標是從本身感興趣的元素移開了,仍是從改元素的子孫元素移開了,mouseenter和mouseleave是非冒泡事件,這能夠解決上面的問題

三、resize和unload事件類型只在Window對象中觸發,若是想要給這兩個事件類型註冊處理程序,應該在$(window)上調用他們

四、toggle()該方法將事件處理程序函數綁定到單擊事件,能夠指定兩個或多個處理程序函數,當點擊事件發生時,jQuery每次會調用一個處理程序函數。例如,若是調用toggle(f,g,h),第一次單擊事件觸發時,會調用函數f(),第二次g(),第三次h()

五、能夠經過HTML字符串給$()方法來建立該字符串所描述的元素,還能夠傳入一個對象(當作第二個參數),該對象由屬性組成。若是第二個參數屬性中有如上列舉的註冊事件方法相同,該屬性值會被當作處理程序函數,並註冊爲命名事件類型處理程序

        $("<img/>", {
            src: image_url,
            alt: image_description,
            className: "translucent_image",
            click: function () {
                $(this).css("opacity", "50%");               
            }
        })

jQuery事件處理程序

上面的例子中事件處理程序函數當作是不帶參數及不返回值的,先這樣很正常。單jQuery調用每個事件處理程序時的確傳入了一個或多個參數,而且對處理程序的返回值進行了處理。

須要知道的最重要的意見事情是,每一個事件處理程序都傳入了一個jQuery事件對象做爲第一個參數。

一般,調用事件處理程序時只帶有事件對象這個惟一參數。若是用trigger()顯示觸發事件,能夠傳入額外的參數數組。這樣作 時,這些參數會在第一個事件對象參數以後傳遞給事件處理程序

無論他們如何註冊的,jQuery事件處理程序函數的返回值始終有意義,當事件處理程序返回一個值時(飛undefind值)jQuery會將該值存儲在Event對象的result屬性中,該屬性值能夠被後續調用的事件處理程序訪問

jQuery事件對象

jQuery經過定義本身的Event對象來隱藏瀏覽器之間的實現差別,當一個jQuery事件處理程序被調用是,總會傳入一個jQuery事件對象做爲其第一個參數。jQuery事件對象主要以W3C標準爲基準,同事它也實現了一些實際的事件標準。jQuery會將一下全部字段從原聲的Event對象中複製到jQuery Event對象上

altKey        ctrlKey        newValue        screenX
attrChange    currentTarget  offsetX         screenY
attrName      detail         offsetX         shiftKey
bubbles       eventPhase     originalTarget  srcElement
button        fromElement    pageX           target
cancelable    keyCode        pageY           toElement
charCode      layerX         prevValue       view
clientX       layerY         relatedNode     wheelDelta
clientY       metaKey        relatedTarget   whic

除了這些屬性,Event對象還定義瞭如下方法

preventDefault()            isDefaultPrevented()
stopPropagation()           isPropagationStoppend()
stopImmediatePropagation()  isImmediatePropagationStopped()

事件處理程序高級註冊-3.0中被刪除推薦使用 on

jQuery定義了至關多的簡單的方法來註冊事件處理程序。全部這些方法都是簡單的調用單一的,接下來看下更復雜的bind()事件類型綁定處理程序

該處理程序會綁定到jQuery對象中的每個元素上。直接bind()可讓咱們使用事件註冊的高級特性,這些特性在較簡單的方法上是不可用的。

在最賤形式下,bind()須要一個事件類型字符串做爲其第一個參數,以及一個事件處理程序做爲其第二個參數。

$('p').click(f)
//等價於
$('p').bind('click', f)

調用bind()時還能夠帶有三個參數。在這種形勢下,事件類型是第一個參數,處理程序函數是第三個參數

bind()還有其餘高級特性。若是第一個參數是由空額分割的事件類型列表,則處理程序函數回味每個命令的事件類型註冊

$('a').hover(f)
// 等同於
$('a').bind('mouseenter mouseleave', f)

bind()的另外一個重要特性是容許爲註冊的事件處理程序制定命名空間,這使得能夠定義處理程序,能方便後續觸發或寫在特定命令空間下的處理程序。處理程序的命名空間對於開發可服用jQuery代碼的類庫或模塊的程序員來講特別有用。事件命名空間相似的CSS的類選擇器

// 做爲mouseover處理程序在命名空間"myMod"中把f綁定到全部元素
$('a').bind('mouseover.myMod', f)
// 甚至還能夠給處理程序分配多個命名空間,在命名空間"myMod"和"yourMod"中做爲mouseout處理程序綁定f
$('a').bind('mouseout.myMod.yourMod', f)

bind()的最後一個特性是,第一個參數能夠是對象

// 調用$('a').hover(f, g)等價於
$('a').bind({mouseenter:f, mouseleave:g})

註銷事件處理程序

用bind()註冊事件處理程序後,能夠用unbind()來註銷它

<script>
        $('*').unbind();  // 從全部元素中溢出全部jQuery事件處理程序
        $('a').unbind("mouseover mouseout");  // 從全部a元素中取消綁定全部mouseover和mouseout處理程序

        // 取消bind在"myMod"命名空間下的全部mouseover和mouseout處理程序
        $('a').unbind("mouseover.myMod mouseout.myMod");

        // 若是想當心的取消本身綁定的事件處理程序,但沒有使用命名空間,必須保留事件處理程序函數的一個引用
        // 並使用unbind()帶兩個參數的版本
        $('#mybutton').unbind('click', myClickHandler);

    </script>

觸發事件

當用戶使用鼠標、鍵盤或觸發其餘事件類型是,註冊的事件處理程序就會自動調用。然而,若是能手動觸發事件,有時會頗有用。手動觸發事件最簡單的方式是不帶參數調用事件註冊的簡單方法好比(click()或mouseover()),與不少jQuery方法能夠用時作getter和setter同樣,這些事件方法在帶有一個參數時會註冊事件處理程序,不帶參數調用時 則會觸發事件處理程序

$('#my_form').submit();

submit()方法本身合成了一個Event對象,並觸發了給submit事件註冊的全部事件處理程序。

就如jQuery定義了一個通用的bind()方法同樣,jQuery也定義了一個更通用的trigger()方法。一般,trigger()時會傳入事件類型字符串做爲第一個參數,trigger()會在jQuery對象中的全部元素上觸發爲該類型事件註冊的全部處理程序

$("#my_form").trigger("submit");  // 等價於上線的submit()

若是傳入的是一個普通的對象 ,會建立新的jQuery Event對象

$('#button1').trigger({type: 'click', synthetic: true})

若是傳入第二個參數,trigger()傳出的第二個參數會成爲每一個觸發事件處理程序的第二個參數,若是傳入數組做爲第二個參數,數組的每一項會做爲獨立參數傳遞給觸發的處理程序

        $('#button1').trigger("click", true);  // 傳入單一額外參數
        $('#button1').trigger("click", [x, y, z]);  // 傳入三個額外參數

第二個參數在自定義事件中很是有用

實時事件-推薦使用on

bind()方法綁定事件處理程序到指定的文檔,可是對於動態生成的怎麼辦?jQuery使用「實時事件」來解決這個問題,須要使用delegate()和undelegate()方法來替代bind()和unbind()。一般在$(document)上調用delegate()並傳入一個jQuery選擇器字符串、一個jQuery事件類型字符串以及一個jQuery事件處理程序函數。

// 給按標籤bind一個事件和處理程序函數
$(document).delegate('a', 'mouseover', linkHandler)

很是贊不須要在生成標籤的時候在指定一個onclick事件了,就能夠動態的進行bind了

        // 靜態連接的靜態事件處理程序
        $('a').bind("mouseover", linkHandler);
        // 文檔中動態更新的部分使用實時事件處理程序
        $(".dynamic").delegate("a", "mouseover", linkHandler)

動畫效果

經過CSS來產生視覺效果,例如除了讓一個元素消失,還能夠在半秒的時間內逐步減小opacity屬性的值,使其快速淡出,而不是瞬間小時。這些視覺效果能給用戶帶來更愉悅的體驗,jQuery使其是嫌棄來更簡單

jQuery定義了fadeIn()和fadeOut()等簡單的方法來實現常見視覺效果。除了簡單動畫方法,jQuery還定義了一個animate()方法,用來實現更復雜的自定義動畫。

每段動畫都有時長,用來指定動畫效果持續多長事件。可使用毫秒數值或字符串指定時長。字符串「fast」表示200ms。字符串「slow」表示600ms。若是指定的字符串時長jQuery沒法識別, 則採用默認時長400

ms。能夠給jQuery.fx.speeds添加新的字符串到數值映射關係來定義新的時長名字:

jQuery.fx.speeds["medium-fast"] = 300;
jQuery.fx.speeds["medium-slow"] = 500;

jQuery動畫方法常用動畫時長來做爲可選的第一個參數。若是省略時長參數,一般會獲得默認的值400ms

        $("#message").fadeIn();        // 使用淡入效果顯示元素,持續400ms
        $("#message").fadeOut("fast"); // 使用淡出效果隱藏元素

禁用動畫

動畫不少網站上已經爲了標配,可是,並非全部的用戶都喜歡;有寫用戶以爲動畫分散注注意力,有寫則感受動畫操做不便。殘障用戶可能會發現動畫妨礙閱讀,老舊設備用戶則會感受動畫耗費不少CPU時間。jQuery能夠很是簡單的全局禁用全部動畫;簡單的設置jQuery.fx.off爲true就好。該設置會將每段動畫的時長變成0ms,這樣動畫看起來就像沒有動畫效果的馬上切換了。

        // 全局禁用動畫效果,當頁面設計者在頁面加入帶有"stopmoving"類用戶點擊就能夠禁用動畫
        $(".stopmoving").click(function () { jQuery.fx.off = true})

jQuery動畫是異步的。調用fadeIn()等動畫方法時,它會馬上返回,動畫則在「後臺執行」。因爲動畫方法會在動畫完成前返回,所以能夠向不少jQuery動畫傳入第二個參數(可選),它是一個函數,會在動畫完成後調用。該函數在調用時不會傳入任何參數,this值就是發生動畫的文檔元素。

        // 用淡入效果快速顯示元素,動畫完成時,在元素裏顯示一些文字
        $("#message").fadeIn("fast", function () { $(this).text("Hello World")})

給動畫方法傳入回調函數,能夠在結束時執行操做。不過,若是隻是想順序執行多段動畫的話,回調方式是沒有必要的。jQuery動畫默認是隊列化的。若是一個元素已經在動畫過程當中,在調用一個動畫方法時,新動畫不會馬上執行,而是會延遲到當前動畫結束後才執行。例如可讓一個元素持久顯示前 ,先閃爍一陣

$("#blinker").fadeIn(100).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn();

jQuery動畫方法能夠接受可選的時長和回調參數。還能夠傳入一個對象來調用動畫方法,該對象的屬性指定動畫選項;

        // 將時長和回調參數做爲對象屬性而不是參數傳入
        $("#message").fadeIn({
            duration: "fast",
            complete: function () { $(this).text("Hello World")}
        })

 使用通用的animate()方法時,常常傳入選項對象做爲參數,其實,這也能夠用於更簡單動畫方法。使用選項對象能夠設置更高級選項,好比控制動畫的隊列和歡動

簡單動畫

jQuery定義了9個簡單的動畫方法用來隱藏和顯示元素。根據事先的動畫類型,他們能夠分爲三組

fadeIn()、fadeOut()、fadeTo()

這是最簡單的動畫:fadeIn()和fadeOut()簡單的改變了CSS的opacity屬性來顯示或隱藏元素。二者均可以接受可選的時長和回調參數。fadeTo()稍有不一樣: 它須要傳入一個opacity目標值,fadeTo()會將元素的當前opacity值變化到目標值。fadeTo()會將元素的當前opacity之變化到目標值。

show()、hide()、toggle()

上面的fadeOut()方法可讓元素不可見,但依舊保留了元素在文檔佈局中的展位。hide()方法則會將元素從佈局中溢出,hide()在將元素的opacity減小到0時,同時它還會將元素的寬度和高度收縮到0,show()則會作反向操做

toggle()能夠改變在上面調用它的元素的可視狀態:若是隱藏則調用show(),若是現實,則調用hide()。與show()和hide()同樣,必須傳入時長或選項對象給toggle()來產生動畫效果。給toggle()傳入true和不帶參數調用show()是同樣的,傳入了false則不帶參數調用hide()是同樣的,若是傳入兩個或多個函數參數給toggle()他會註冊爲事件處理程序

slideDown()、slideUp()、slideToggle()

slideUp()會隱藏jQuery對象中的元素,方式是將其高度動態變化到0,而後設置Css的display屬性爲"node"。slideDown()執行反向操做,來使得隱藏的元素再次課件。slideToggle()使用向上滑動或想下滑動動畫來切換元素的可見性。

        // 用淡出效果將全部的圖像隱藏,而後顯示他們,接着向上滑動,再向下滑動
        $("img").fadeOut().show(300).slideUp().slideToggle();

自定義動畫

與簡單的動畫方法實現的效果相比,使用animate()方法能夠實現更多通用動畫效果。傳給animate()方法的第一個參數指定動畫內容,剩餘參數指定如何指定動畫,第一個參數是必須的:它必須是一個對象,該對象的屬性指定要變化的CSS屬性和它們的目標值。animate()方法會將每一個元素的這些CSS屬性從初始值變化到指定的目標值,例如slideUp()效果能夠用

        // 將全部的圖片的高度縮小到0
        $("img").animate({height: 0})

第二個參數是可選的,能夠傳入一個選項對象給animate()方法

        $("#sprite").animate({
            opacity: .25,             // 將不透明度調整爲0.25
            fontSize: 10              // 將字體大小變化到10像素
        },{
            duration: 500,            // 動畫持續半秒
            complete: function () {  // 在動畫完成時調用該函數
                this.text("Goodbye") // 改變元素的文本
            }
        })

動畫屬性對象

第一個參數必須是對象,該對象的屬性名必須是CSS屬性名

        $("p").animate({
            "margin-left": "+=.5in",// 增長段落縮進  這裏JavaScript不識別以-分割的須要加引號或經過駝峯式也能夠marginLeft
            opacity: "-=.1"          // 同事減小不透明度
        })

動畫選項對象

animate()方法的第二個參數是可選的,該選項對象用來指定動畫如何執行。有兩個最重要的選項咱們已經接觸過。duration屬性指定動畫持續的毫秒事件,該屬性的值還能夠是"fast"、「slow」或任何在jQuery.fx.speeds定義的名稱

贏一個是complete屬性:它指明在動畫完成時的回調函數。和complete屬性相似,step屬性指定在動畫每一步或每一幀調用的回調函數。在回調函數中,this指向在連續變化的元素,第一個參數則是正在變化的屬性的當前值。

在選項對象中,queue屬性指定動畫是否須要隊列化---是否須要等到全部還沒有發生的動畫完成後執行該動畫。默認狀況下,全部動畫都是隊列化的。將queue屬性設置爲false能夠取消隊列化。非隊列化的動畫會馬上執行。隨後隊列化的動畫不會等待非隊列化執行完後才執行

$("img").fadeIn(500).animate({width: "+=100"}, {queue: false, duration: 1000}).fadeOut(500);

上面的fadeIn()和fadeOut()效果是隊列化的,但animate()的調用(在1000毫秒內連續改變width屬性)是非隊列化的。這段width動畫和fadeIn()效果的開始時間相同。fadeOut()效果會在fadeIn()效果完成時馬上開始,他不會等到width動畫完成。

jQuery中的Ajax

load()方法

load()是全部的jQuery工具中最簡單的:向它傳入一個URL,他會異步加載該URL的內容,而後將內容插入每個選中元素中,替換掉已經存在的內容:

        // 每隔60秒加載並顯示公告
        setInterval(function () {$("#box").load("2-2.html")}, 6000)

若是想加載片斷的話,若是想加載文檔選中部分空格必須加上

$('#temp').load("wheather_report.html #temperature")

load()方法還能夠接受兩個可選參數。第一個可選參數表示的數據能夠追加到URL後面,或者與請求一塊兒發送。若是傳入的是字符串,則會追加到URL後面,一般load()方法發送HTTP GET請求,可是若是傳入數據對象,則它會發送POST請求。

$("#box").load("us_wather_report.html", {zipcode: 20134, units: "f"})
    <script>
        let box = $("#box");
        // bind click事件
        let buttonLoad = $("#btn-load");
        buttonLoad.on("click", function () {
            console.log("發送Ajex Load 請求");
            box.load("http://127.0.0.1:8000/load_api/", { sayHello: "shuaige", age: 10})
        })

    </script>

若是發送的是對象,那麼就是POST請求

load()方法的另外一個可選參數是回調函數

當Ajax請求成功或未成功,以及(當請求成功時)URL加載完畢並插入選中元素時,會調用改回調函數。若是沒有指定任何數據,回調函數能夠做爲第二個參數傳入,不然,他必須是第三個參數

jQuery對象的每個元素上都會調用回調函數,而且每次調用都會傳入三個參數:被夾在的URL的完整文本內容、狀態碼字符串,以及用來加載該URL的XMLHttpRequest對象。其中,狀態參數是jQuery的狀態碼,不是HTTP的狀態碼,其值相似「success」, 「error」和「timeout」的字符串

可選的 callback 參數規定當 load() 方法完成後所要容許的回調函數。回調函數能夠設置不一樣的參數:

  • responseTxt - 包含調用成功時的結果內容
  • statusTXT - 包含調用的狀態
  • xhr - 包含 XMLHttpRequest 對象

下面的例子會在 load() 方法完成後顯示一個提示框。若是 load() 方法已成功,則顯示「外部內容加載成功!」,而若是失敗,則顯示錯誤消息:

$("button").click(function(){
  $("#div1").load("demo_test.txt",function(responseTxt,statusTxt,xhr){
    if(statusTxt=="success")
      alert("外部內容加載成功!");
    if(statusTxt=="error")
      alert("Error: "+xhr.status+": "+xhr.statusText);
  });
});
jQuery的Ajax狀態碼
jQuery的全部Ajax工具,包括load()方法,會調用回調函數來提供請求成功或失敗的異步消息。這些回調函數的第二個參數是一個字符串,能夠取如下值
"success":
    表示請求成功完成
"notmodified":
    該狀態碼錶示請求已正常完成,但服務器返回的響應內容是HTTP 304 "Not Modified", 表示請求的URL內容和上次請求的內容相同,沒有變化。只有在選項中設置ifModified爲true時,改狀態嗎纔會出現. 
jQuery1.4認爲 "notmodified"狀態碼是成功的,可是以前的版本會將其當成錯誤 "error": 表示請求沒有成功完成,緣由是HTTP錯誤。更多細節,能夠檢查傳入參數每個回調函數中的XMLHttpRequest對象中的HTTP狀態碼來獲取 "timeout": 若是Ajax請求沒有在選定的超時事件內完成,會調用錯誤回調,並傳入該狀態碼。默認狀況下jQuery的Ajax請求沒有超時限定,只有指定了timeout選項時才能看到該狀態碼 "parsererror": 該狀態碼錶示HTTP請求已完成,但jQuery沒法按照指望的方式解析。例如,若是服務器返回的是不符合格式的XML文檔或者不符合格式的JSON文本時,就會出現改狀態碼

jQuery.get()和jQuery.post()

jQuery.get()使用HTTP GET請求來實現,jQuery.post()使用HTTP POST請求,其餘二者則都是同樣的,與jQuery.getJSON()同樣,這兩個方法也接受相同的三個參數:

  • 必須的URL
  • 可選的字符串或對象
  • 可選但實際總會使用的回調函數:能夠傳三個參數(responseTxt,statusTxt,xhr) ====== (內容, Ajax狀態, XMLTttpRequest對象)

jQuery的Ajax數據類型

text  
    將服務器的響應做爲純文本返回不作任何處理
html 
    和text相似:響應是純文本。load()方法使用該類型,將返回的文本插入到文檔中
xml
    請求的URL被認爲指向XML格式的數據,jQuery使用SMLHttpRequest對象的responseXML屬性來替代responseText屬性。傳給回調函數的值是一個表示該XML文檔的Document對象,而不是保存文檔文本的字符串
script
    請求的URL被認爲指向JavaScript文件,返回的文本在傳入回調函數前,會當作腳本執行.jQuery.getScript()使用該類型。當類型是"script"時,jQuery可使用<script>元素來替代XMLHttpRequest對象,
所以能夠處理跨域請求。 json 請求的URL被認爲指向JSON數據的數據文件。會使用jQuery.parseJSON()來解析返回的內容,的到的JSON對象後傳入回調函數。jQuery.getJSON()使用該模型。若是類型是
"json"同事URL或數據字符串含有"=?",
該類型會轉換成jsonp jsonp 請求的URL被認爲指向服務器腳本,改腳本支持JSONP協議,能夠將JSON格式的數據做爲參數傳遞給客戶端指定的函數,在該類型下,傳遞給回調函數的是解析好的對象,因爲JSONP請求能夠經過
<script>元素實現,
所以該類型能夠用來作跨域請求。

jQuery.ajax()函數

jQuery的全部Ajax工具最後都會調用jQuery.ajax()--這是整個類庫中最複雜的函數。jQuery.ajax()僅接受一個參數:一個選項對象,該對象的屬性指定Ajax請求如何執行的不少細節

例如:jQuery.getScript(url, callback) 與下面的jQuery.ajax()的調用等價

            $.ajax(  // ajax只接受一個參數選項對象
                {
                    type: "GET",                   // HTTP請求方法
                    url:url,                      // 要獲取數據的URL
                    data: null,                  // 不給url添加任何數據
                    dataType: "script",          // 一旦獲取到數據,馬上當作腳本執行
                    success: function () {},    // 完成時調用該函數
                }
            )

jQuery.get()和jQuery.post()也接受上面的5個基本選項。然而,若是直接調用jQuery.ajax()的話,它能夠支持更多其餘選項。

jQuery.ajaxSetup()傳入一個選項對象來設置任意選項的默認值

            // 設置ajax默認參數
            $.ajaxSetup(
                {
                    timeout: 2000,  // 在2秒後取消全部Ajax請求
                    cache: false    // 經過給URL添加時間戳來禁用瀏覽器緩存
                }

運行上面代碼後,指定timeout和cache選項會在全部未指定這兩個選項值的Ajax請求中使用(包括jQuery.get()和load()方法等高級工具)

jQuery.ajax()選項

type
    指定HTTP的請求方法。默認"GET"。另外一個經常使用值是"POST"。能夠指定其餘HTTP請求方法
好比"DELETE" 或 "PUSH",但不是全部的瀏覽器都支持它

url
    要獲取URL。對於GET請求,data選項會添加到該URL後。對於JSONP請求,當cache選項爲false時
jQuery能夠添加參數到URL

data
    添加到URL中(對GET請求)或在請求的內容體中(對於POST請求)發送的數據。這能夠是字符串對象。
一般會把對象轉化爲字符串

dataType
    指定響應數據的指望類型,以及jQuery處理該數據的方式。合法值是"text"、"html"、"script""json"、"jsonp"和"xml"

contentYpe
    指定請求的HTTP Content-Type頭。默認是"application/x-www-form-urlencode",這是HTML表單和
絕大部分服務器腳本使用的正常值。若是將type選項設置爲"POST",想要發送純文本或XML文檔做爲請求體時
須要設置改選項

timeout
    超時事件,單位是毫秒。若是設置了該選項,當請求沒有在指定超時時間內完成時,請求會取消同時取消
error回調,回調中的狀態碼爲"timeout"。默認超時時間是0,表示除非請求完成,不然永遠不會取消。

cache
    對於GET請求,若是該選項設置爲fales,jQuery會添加一個"_="參數到URL中,或者替換已經存在的同名參數
改參數的值是當前時間(毫秒格式)。這能夠禁用基於瀏覽器的緩存,由於每次請求的URL都不同。

ifModified
    當該選項設置爲true時,jQuery會爲請求的每個URL記錄Last-Modified和If-None-Match響應頭的值
並會在接下來的請求中爲相同的URL設置這些頭部信息。這可使得,若是上次請求的URL內容沒有改變,
則服務器會發送HTTP 304 "Not Modified" 響應。默認狀況下,該選項未設置,jQuery不會設置或記錄這些信息

global
    該選項指定jQuery是否應該觸發上面描述的Ajax請求過程當中的事件。默認值是true ,設置該選項爲false會
禁用Ajax相關的全部事件。

jQuery.ajax()回調

在Ajax請求的不一樣階段調用的函數。success選項這是傳入給jQuery.getJSON()等方法的回調函數,注意jQuery也會將Ajax請求過程消息當作事件發送(除非設置了global選項爲false)

context
    該選項指定回調函數在調用時的上下文對象---this。該選項沒有默認值,若是不設置,this會
指向選項對象。設置context選項也會影響Ajax事件觸發的方式。若是設置該選項,值應該爲
Window、Document或觸發事件所在的Element

beforeSend
    該選項指定Ajax請求發送到服務器以前激活的回調函數,第一個參數是XMLHttpRequest對象,
第二個參數是該請求對象的選項對象。beforeSend回調是的程序有機會在XMLHttpRequest對象上
自定義HTTP頭部。若是該回調函數返回false,Ajax請求會取消。

success
    該選項定義Ajax請求陳工完成時調用的回調函數。第一個參數是服務器發送的數據;第二個
參數是jQuery狀態碼;第三個參數是用來發送該請求的XMLHttpReques對象。

error
    該選項指定Ajax請求不成功時調用的回調函數。參數與sucess相似

complete
    該選項指定Ajax請求完成時激活的回調函數。每個Ajax請求或者成功時調用success回調,
或者失敗時調用error。在調用success或error後,jQuery會調用complete回調。穿個complete
回調的第一個參數是XMLHttpRequest對象,第二個參數則是狀態碼

不經常使用的選項和鉤子

async
    腳本化的HTTP請求自己就是異步的。而後,XMLHttpRequest對象提供了一個選項,能夠用來阻塞當前進程
,直到收到響應。若是想開啓這一阻塞行爲,能夠設置該選項爲false

dataFilter
    該選項制定一個函數,用來過略或預處理服務器返回的數據。第一個參數是從服務器返回的原始數據
(字符串或XML請求返回的Docuemnt對象),第二個參數是dataType選項的值,若是指定改函數,則它必返回
一個值,改值會用來替換掉服務器的響應。注意dataFilter()函數會在JSON解析和腳本執行前執行,跨域的
不會調用dataFilter()

jsonp
    當設置dataType選項爲"jsonp"時,url或data選項一般會包含一個相似"jsonp=?"的參數,若是沒有找到
相似的參數時,會使用默認值"callback"

jsonpCallback
    對於dataType爲"jsonp"的請求,jQuery必須將URL中的"?"替換成包裝函數名,服務器會將數據傳遞給
該包裝函數。一般jQuery會根據當前事件生成一個惟一的函數名。若是想用本身的函數來替代jQuery生成的,
則能夠設置該選項。可是,一旦這樣作了,會組織jQuery在觸發正常事件調用success或complete回調

processData
    當設置了data選項爲對象時,jQuery一般會將 該對象轉換成字符串

scriptCharset
    對於跨域的"script"和"jsonp"請求,會使用<script>元素,該選項來指定<script>元素的charset屬性值
該選線個對於正常基於XMLHttpRequest請求的不會有任何做用

username,password
    若是請求須要密碼驗證,請使用這兩個選項來驗證

xhr
    該選項指定一個工廠函數,用來獲取XMLHttpRequest對象。
相關文章
相關標籤/搜索