Porfessional JS(21.2-XMLHttpRequest Level 2/Progress Event/CORS)& Sharp jQuery(selectors[part])

1.The FormData Type
+①The serialization of form data is frequently needed in modern web applications,and so the XMLHttpRequest Level 2 specification introduces the FormData type.The FormData type makes it easy to both serialize existing forms and create data in the same format for easy transmission(傳輸) via XHR.

var xhr=createXHR();
xhr.onreadystatechange = function(){
    if(readyState == 4){
        if((xhr.status >= 200 && xhr.status < 300)|| xhr.status == 304){
            alert(xhr.responseText);
        }else{
            alert("Request was unsuccessful: "+ xhr.status);
        }
    }
};
xhr.open("post","postExample.php",false);//異步
var form=document.getElementById("user-info");
xhr.send(new FormData(form));

②One of the conveniences of the FormData type is that you don't need to explicitly set any request headers on the XHR object.The XHR object recognizes the passed-in data types as an instance of FormData and configures(配置) the headers appropriately.

③The FormData type is supported in Firefox 4+,Safari 5+,Chrome,and WebKit for Andriod 3+.

2.Timeouts
+①In IE 8,the XHR object was augmented(增加) to include a timeout property that indicates the number of milliseconds the request should wait for a response before aborting(中止).When the timeout property is set to a number and the response is not received within the number of the milliseconds,a timeout event is fired and the ontimeout event handler is called.This functionality was later added into the XMLHttpRequest Level 2 specification(規範).

var xhr=createXHR();
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        /*
        當調用ontimeout事件處理事件,此時readyState可能已經改變爲4了,這意味着
        會調用onreadystatechange事件處理程序。可是,如果在超時終止請求之後再訪
        問status屬性,就會導致錯誤。因此將檢查status屬性的語句封裝在try-catch語
        句中
        */
        try{
            if((xhr.status >=200 && xhr.status < 300)||xhr.status ==304 ){
                alert(xhr.responseText);
            }else{
                alert("Request was unsuccessful: " +xhr.status);
            }
        }catch(ex){
            //assume handled by ontimeout
        }
    }
};
xhr.open("get","timeout.php",true);//同步
//如果請求在1秒內沒有返回,就會自動終止
xhr.timeout=1000;//set timeout for 1 second (IE 8+ only)
//請求終止時,會調用ontimeout事件處理程序
xhr.ontimeout = function(){
    alert("Request did not return in a second");
};
xhr.send(null);

3.The overrideMimeType() Method
①Firefox first introduced(推行) overrideMimeType() as a way to override the MIME type of an XHR response.This was later added to XMLHttpRequest Level 2.Since the returned MIME type for a response determines how the response is handled by the XHR object,having a way to override the type returned by the server is a useful addition.

+②Consider the case where the server sends a MIME type if a text/plain(純文本) that actually contains XML.This would result in the response XML property being null even though that data is actually XML.By calling overrideMimeType(),you can ensure the response is treated as XML instead of plain text.

/*
1.這個例子強迫XHR對象將相應當做XML而非純文本來處理。
2.調用overrideMimeType()必須在send()方法之前,才能保證重寫相應的MIME類型。
*/
var xhr = createXHR();
xhr.open("get","text.php",true);//異步,第三參數表示:是否採用異步方式
xhr.overrideMimeType("text/xml");
xhr.send(null);

③The overrideMimeType() method is supported in Firefox,Safari 4+,Opera 10.5+,and Chrome.

4.Progress Events
①The Progress Events specification is a W3C Working Draft defining events for client-server communication.These events were first targeted at XHR explicitly but have now also made their way into other similar APIs.There are six progress events:
1)loadstart—Fires when the first byte of the response has been received.
2)progress—Fires repeatedly as a response is being received.
3)error—Fires when there was an error attempting the request.
4)abort—Fires when the connecttion was terminated(終止) by calling abort().
5)load—Fires when the response has been fully received.
6)loadend—Fires when the communication is complete and after error,abort,or load.

②Each request begins with the loadstart event being fried;followed by one or more progress events;then one of error,abort, or load;finally ending with loadend.

③The first five events are supposed in Firefox 3.5+,Safari 4+,Chrome,Safari for iOS,and WebKit for Android.Opera,as of version 11,and IE 8+ support only the load.No browser currently support the loadend event.

+④As long as a response is received from the server,ragardless of the status,the load event will fire.This means you must check the status property to determine if the appropriate data is avialable.This load event is supported by Firefox,Opera,Chrome and Safari.

var xhr=createXHR();
xhr.onload = function(){
    if((xhr.status >=200 && xhr.status <300) ||xhr.status ==304){
        alert(xhr.responseText);
    }else{
        alert("Request was unsuccessful: " + xhr.status);
    }
};
xhr.open("get","altevents.php",true);//異步
xhr.send(null);

+⑤Another XHR innovation from Mozilla is the progress event,which fires periodically as the browser receives new data.The onprogress event listener receives an event obejct whose target is the XHR object and contains three aditional properties:lengthComputable,a Boolean indicating if progress information is available;position,which is the number of bytes that have already been received;and totalSize,which is the total number of the expected by bytes as defined by the ContentLength response header.With that information,you can provided a progress indicator to the user.

var xhr=createXHR();
xhr.onload = function(event){
    if((xhr.status >=200 && xhr.status <300) || xhr.status ==304){
        alert(xhr.responseText);
    }else{
        alert("Request was unsuccessful: " +xhr.status);
    }
};
xhr.onprogress = function(event){
    var divStatus =document.getElementById("status");
    if(event.lengthComputable){   //a Boolean indicating if progress information is available
        divStatus.innerHTML = "Received " +event.position +" of " +event.totalSize +
        " bytes.";
    }
};
xhr.open("get","altevents.php",true);//異步
xhr.send(null);

5.Cross-Origin Resource Sharing(跨域源資源共享)
①One of the major limitations of Ajax communication via XHR is the cross-origin security policy(跨域安全策略).By default,XHR objects can access resources only on the domain from which the containing web page originates.This security feature prevents some malicious(惡意的) behavior.However,the need for legitimate(合理的) cross-origin access was great enough for solutions to begin appearing in browsers.

+②Cross-Origin Resource Sharing(CORS) is a W3C Working Draft that defines how the browser and server must communicate when accessing sources across origins.The basic idea behind CORS is to use custom HTTP headers to allow both the browser and the server to know enough about each other to determine if the request or response should succeed or fail.

Origin: http://www.baidu.com
Access-Control-Allow-Origin: http://www.baidu.com

6.CORS in IE
①Microsoft introduced the XDomainRequest(XDR) type in IE 8.This object works in a manner similar to XHR but in a way that is safe and secure for cross-domain communication.The XDR object implements part of the CORS specification.Here are some of the ways that XDR differs from XHR:
1)Cookies are neither sent with requests nor received with reponses.
2)There is no access to set requests headers other than Content-Type.
3)There is no access to response headers.
4)Only GET and POST requests are supported.

②XDR object usage looks very similar to XHR object use.You create a new instance of XDomainRequest,call the open() method,and then call the send() method.Unlike the open() method on XHR obejcts,the one on XDR objects accepts only two arguments:the request type and the URL.

+③All XDR requests are executed asynchronously,and there is no way to create a synchronous request.When a request has returned,a load event fires and the responseText property is filled with the response.

var xdr = new XDomainRequest();
xdr.onload = function(){
    alert(xdr.responseText);
};
xdr.open("get","http://www.somewhere-else.com/page/");
xdr.send(null);

+④When the response is received,you have access to only the raw text(原始文本–row行) of the response;there is no way to determine the status code of the response.The load event is fired for all valid repsonses and an error event is fires for all failures,including the lack of an Access-Control-Allow-Origin header on the response.Unfortunately,you receive no additional information about the error that occurred,so just knowing that the requet was unsuccessful must be enough.To detect an error,assign an onerrror event handler.

var xdr = new XDomainRequest();
xdr.onload =function(){
    alert(xdr.responseText);
};
xdr.onerror =function(){
    alert("An error occurred.")
};
xdr.open("get","http://www.somewhere-else.com/page/");
xdr.send(null);

⑤Because there are so many ways an XDR request can fail,you should always use an onerror event handler to capture the occurrence(這種存在-即XDR請求失敗);otherwise it will fail silently.

+⑥Also similar to XHR,the XDR objects supports the timeout property and the ontimeout event handler.

xdr.abort();//中止請求

var xdr = new XDOmainRequest();
xdr.onload = function(){
    alert(xdr.responseText);
};
xdr.onerror =function(){
    alert("An error occurred.")
};
xdr.timeout =1000; //運行1秒後超時
xdr.ontimeout =function(){  //隨即調用ontimeout事件處理程序
    alert("Request took too long.");
};
xdr.open("get","http://www.somewhere-else.com/page/");
xdr.send(null);

+⑦To allow for POST requests,the XDR object exposes(提供) a contentType property that can be used to indicate the format of the posted data.

var xdr = new XDomainRequest();
xdr.onload = function(){
    alert(xhr.responseText);
};
xdr.onerror = function(){
    alert("An error occurred.");
};
xdr.open("post","http://www.somewhere-else.com/page/");
xdr.contentType="application/x-www-form-urlencoded";
xdr.send("name1=value1&name2=value2");
//This property is only access to header information through the XDR object.

7.CORS in Other Browsers
+①Firefox 3.5+,Safari 4,Chrome,Safari for iOS,and WebKit for Andriod all support CORS natively through the XMLHttpRequest object.When attempting to open a resource on a different origin,this behavior automatically gets triggered(觸發) without any extra code.To make a request to a resource on another domain,the standard XHR object is used with an absolute URL specified in open().

var xhr = createXHR();
xhr.onreadystatechange = function(){
    if(xhr.readyState ==4){
        if((xhr.status >= 200 && xhr.status <300) || xhr.status ==304){
            alert(xhr.responseText);
        }else{
            alert("Request was unsuccessful: " +xhr.status);
        }
    }
};
xhr.open("get","http://www.somewhere-else.com/page/",true);//異步
xhr.send(null);

②Unlike the XDR object in IE,the cross-domain XHR object allows access to the status and statusText properties and allow synchronous requests.There are some additional limitations on a cross-domain XHR object that are necessary for security purposes:
1)Custom headers cannot be set using setRequestHeader().
2)Cookies are neither sent nor received.
3)The getAllRequestHeaders() method always return an empty string.

③Since the same interface is used for both same- and cross-domain requests,it's best to always use a relative URL when accessing a local resource,and an absolute URL when accessing a remote resource.This disambiguates(消除歧義) the use case and can prevent problems such as limiting access to header and/or cookie information for local resources.

8.解決jQuery和其他庫的衝突
+①在其他庫和jQuery庫都被加載完畢後,可以在任何時候調用jQuery.noConflict()函數來將變量$的控制權移交給其他JS庫。

jQuery.noConflict();//將變量$的控制權移交給prototype.js(假設有這個庫)
$("pp").style.display = "none";//使用prototype.js隱藏元素
jQuery(function(){   //使用jQuery,就不能再用$了
    jQuery("p").click(function(){
        alert(jQuery(this).text());
    })
})

+②確保jQuery和其他庫不衝突,又可以使用一種快捷方式。

var $j = jQuery.noConflict();
$("pp").style.display = "none";//使用prototype.js隱藏元素
$j(function(){   //使用jQuery,利用自定義快捷方式-----$j
    $j("p").click(function(){
        alert($j(this).text());
    })
})

+③想像原來一樣使用$,又不想造成衝突。

jQuery.noConflict();
$("pp").style.display = "none";//使用prototype
jQuery(function($){            //使用jQuery設定頁面加載時執行的函數
    $("p").click(function(){   //在函數內部繼續使用$()方法
        alert($(this).text());
    })
})


jQuery.noConflict();
$("pp").style.display = "none";     //使用prototype
(function($){                       //定義匿名函數並設置形參爲$
    $(function(){                   //匿名函數內部的$均爲jQuery
        $("p").click(function(){    
            alert($(this).text());
        });
    });
})(jQuery);                         //執行匿名函數且傳遞實參jQuery

④如果jQuery庫在其他庫之前就導入了,那麼可以直接使用"jQuery"。同時,可以使用$()方法作爲其他庫的快捷方式。並且無需調用jQuery.noConflict()函數。

9.jQuery選擇器的優勢
①寫法簡單—$("#ID")—–document.getElementById("ID")

②支持CSS1到CSS3(part)選擇器,1.1.3.1版後,jQuery廢棄了不常用的XPath選擇器,但引用相關插件後,仍支持該選擇器。

+③完善的處理機制
https://segmentfault.com/q/1010000000761781

<div>test</div>
<script type="text/javascript">
    //瀏覽器報錯,因爲網頁中沒有id爲"tt"的元素
    document.getElementById('tt').style.color='red';
</script>

//改進
<div>test</div>
<script type="text/javascript">
    if(document.getElementById('tt')){
        document.getElementById('tt').style.color='red';
    }
</script>

//使用jQuery
<div>test</div>
<script type="text/javascript">
    $("#tt").css("color"."red");  //無需判斷$("#tt")是否存在
</script>

//使用jQuery檢查網頁上是否存在某個元素
if($("#tt")){       //× 因爲$("#tt")獲得的永遠是對象
    //do something
}

//√
if($("#tt").length>0){
    //do something
}
/*
1.jQuery(selector)返回的不是單純的節點,而是在節點外又加了一層自己的包裝,
包裝後的[0]位置,放的纔是所要的節點---船上拉的都是集裝箱。
2.var jQuery = function(selector,context){
    return new jQuery.fn.init(selector,context);
};
3.console.info($("#tt"));
//jQuery.fn.init{}
△__proto__:Object(0)
*/
if($("#tt")[0]){
    //do something
}

+10.傳統的JS方式。

//1.給網頁中的所有<p>元素添加onclick事件。
//找到要的東西,收集起來---多個相同性質的東西就需要遍歷,根據需要的標準進行篩選----輸出想要的東西
<p>test1</p>
<p>test2</p>
<script type="text/javascript">
var items=document.getElementsByTagName('p');
var i,len;
for(i=0,len=items.length;i<len;i++){
    items[i].οnclick=function(){
        //do something
    }
}
</script>


//2.使一個特性的表格隔行變色
<table id='yyc'>
    <tbody>
        <tr><td>第一行</td><td>第一行</td></tr>
        <tr><td>第二行</td><td>第二行</td></tr>
        <tr><td>第三行</td><td>第三行</td></tr>
        <tr><td>第四行</td><td>第四行</td></tr>
        <tr><td>第五行</td><td>第五行</td></tr>
        <tr><td>第六行</td><td>第六行</td></tr>
    </tbody>
</table>
<script type="text/javascript">
    var item = document.getElementById('yyc');
    var tbody = item.getElementsByTagName('tbody')[0];//getElementsByTagName()的結果是一個數組
    var trs = tbody.getElementsByTagName('tr');
    var i,len;
    for(i=0,len=trs.length;i<len;i++){
        if(i % 2 ==0){   //偶數行
            trs[i].style.backgroundColor='orange';//不是background-color **等號不是冒號
        }
    }
</script>


//3.對多選框進行操作,輸出選中的多選框的個數
<input type="checkbox" name="check" value='1' checked='checked'>
<input type="checkbox" name="check" value='2' >
<input type="checkbox" name="check" value='3' checked='checked'>
<input type="button" value='選中的個數' id='btn'>
<script type="text/javascript">
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        var items =document.getElementsByName('check') //*** important
        var arrays = new Array();
        for(var i=0;i<items.length;i++){
            if(items[i].checked){
                arrays.push(items[i].value);
            }
        }
        alert("The number you have chosen is " + arrays.length);
    }
</script>

@@+11.兩個有意思的層次選擇器

<!doctype html>
<html>
<head>
    <title>ContextMenu Event Example</title>
    <meta charset='utf-8'>
    <link rel="stylesheet" type="text/css" href="">
    <style type="text/css">
        div,span{
            width: 140px;
            height: 140px;
            margin: 5px;
            background: #aaa;
            border:solid 2px teal;
            float:left;
            font-size: 17px;
            font-family: helvetica;
        }
        div.mini{
            width: 55px;
            height: 55px;
            background-color: #aaa;
            font-size: 12px;
        }
        div.hide{
            display: none;
        }
    </style>
</head>
<body>
    <div id='one' class='one'>
        #one,class(one)
        <div class='mini'>class(mini)</div>
    </div>

    <div id='two' class='one' title='test'>
        #two,class(one),title(tet)
        <div class='mini' title='other'>class(mini),title(other)</div>
        <div class='mini' title='test'>class(mini),title(test)</div>
    </div>

    <div class='one'>
        <div class='mini'>class(mini)</div>
        <div class='mini'>class(mini)</div>
        <div class='mini'>class(mini)</div>
        <div class='mini'></div>
    </div>

    <div class='one'>
        <div class='mini'>class(mini)</div>
        <div class='mini'>class(mini)</div>
        <div class='mini'>class(mini)</div>
        <div class='mini' title='tesst'>class(mini),title(tesst)</div>
    </div>

    <div style='display:none;' class='one'>
        style(display:none)
    </div>

    <div class='hide'>
        class(hide)
    </div>

    <div>
        包含input的type爲"hidden"的div <input type="hidden" size='8'>
    </div>

    <span id='mover'>正在執行動畫的span元素</span>

    <script type="text/javascript" src='fun.js'></script>
    <script type="text/javascript" src='jquery.js'></script>
    <script type="text/javascript">
        //$(".one + div")
        $(".one").next("div").css('background-color','#afb');
    </script>
</body>
</html>



<script type="text/javascript">
    //$("#two ~ div")
    $("#two").nextAll("div").css('background-color','#afb');
</script>

這裏寫圖片描述

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章