>  기사  >  웹 프론트엔드  >  jQuery1.9.1 소스코드 분석 시리즈 (16) ajax ajax Framework_jquery

jQuery1.9.1 소스코드 분석 시리즈 (16) ajax ajax Framework_jquery

WBOY
WBOY원래의
2016-05-16 15:27:31888검색

AJAX 소개

AJAX는 전체 페이지를 다시 로드하지 않고도 웹페이지의 일부를 업데이트할 수 있는 기술입니다.

꼭 갖춰야 할 기본지식

학습을 계속하기 전에 다음 지식에 대한 기본적인 이해가 필요합니다.

HTML/XHTML
CSS
자바스크립트/DOM

이러한 프로젝트를 먼저 알아보고 싶다면 당사 홈페이지의 튜토리얼을 방문하세요.

AJAX란 무엇인가요?

AJAX = 비동기 JavaScript 및 XML.

AJAX는 빠르고 동적인 웹페이지를 만드는 기술입니다.

AJAX를 사용하면 백그라운드에서 서버와 소량의 데이터를 교환하여 웹페이지를 비동기적으로 업데이트할 수 있습니다. 이는 전체 페이지를 다시 로드하지 않고도 웹페이지의 일부를 업데이트할 수 있음을 의미합니다.

AJAX를 사용하지 않는 기존 웹페이지의 경우 콘텐츠를 업데이트해야 하면 전체 웹페이지를 다시 로드해야 합니다.

AJAX를 활용한 적용사례는 Sina Weibo, Google Maps, Kaixin.com 등 다양합니다.

Google 추천

2005년 Google은 Google Suggest를 통해 AJAX를 유명하게 만들었습니다.

Google Suggest는 AJAX를 사용하여 매우 동적인 웹 인터페이스를 만듭니다. Google 검색창에 키워드를 입력하면 JavaScript가 해당 문자를 서버로 보내고 서버는 검색 제안 목록을 반환합니다.

오늘부터 AJAX 사용을 시작하세요

AJAX는 기존 표준을 기반으로 합니다. 이러한 표준은 수년 동안 대부분의 개발자가 사용해 왔습니다.

Ajax 프레임워크이므로 jQuery의 Ajax 처리 아이디어에 대해 이야기해보겠습니다.

현재 브라우저는 ajax를 지원하지만 다른 브라우저에서는 이를 다르게 사용할 수 있습니다(IE에서는 새로운 window.ActiveXObject("Microsoft.XMLHTTP")를 사용하고 표준 브라우저는 새로운 window.XMLHttpRequest()를 사용합니다). 이 아이디어를 따른다면 jQajax만 호환되면 될 것 같은데요?

아니요, 기본 Ajax에는 크고 작은 단점이 있습니다. 교차 도메인을 지원하지 않습니다(동일 출처 전략은 Baidu 자체에서 오랫동안 사용되어 왔습니다). 그러면 jQajax는 이 영역에 처리 기능을 추가했습니다. jQajax는 도메인 간 문제를 어떻게 해결합니까?

 f2e9319f9e2612a8a57a649bb03d8216

사진을 얻을 수 있습니다. 당연히 사진의 경로가 서버와 동일한 도메인에 있지 않습니다. src 속성이 있는 모든 태그가 동일한 원본 정책의 영향을 받지 않는지 확인할 수 있습니다. 따라서 jQuery는 이 속성을 사용하고 스크립트 태그의 src를 사용하여 도메인 간 요청에 대한 경로를 요청합니다.

그런 다음 jQuery는 Ajax 이벤트를 모니터링하는 세 가지 방법을 추가합니다.

1. 글로벌 이벤트: $(document).on('ajaxStart',func);

2.ajax 설정 콜백 항목: $.ajax({url: "php.html", 완전한: func });

3. 지연된 바인딩 방법: $.ajax(…).done(func);

기본적으로 이것이 jQajax가 하는 일입니다.

Ajax 프레임워크의 핵심으로 들어가기 전에 먼저 양식을 직렬화하고 제출하기 위해 jQuery에서 준비한 여러 기능을 분석해 보겠습니다.

a. 양식 직렬화

소위 양식 직렬화는 제출해야 하는 내용을 "key=value&key=value..." 형식의 문자열로 구성하는 것입니다.

직렬화에는 세 가지 기능이 사용됩니다.

jQuery.fn. serialize()(직렬화 함수, 양식에 제출해야 하는 데이터를 필터링하고 "key=value&key=value..." 형식의 직렬화된 문자열로 반환합니다.)

jQuery.fn. serializeArray()(양식에 제출해야 하는 데이터를 필터링하고 키/값 쌍의 객체 배열 형식으로 반환, [{name:'key',value:'select1 반환) '},{ 이름:'selectM',값:'selectM1'}, {이름:'selectM',값:'selectM2'}, { 이름:'key2',값:0}…])

jQuery.param(serializeArray, traditional)(키/값 쌍의 객체 배열을 "key=value&key=value..." 문자열로 직렬화합니다).

Serialize는 jQuery.param( this.serializeArray() )을 직접 호출할 수 있습니다.

serializeArray의 소스 코드는 다음과 같습니다. 세 가지 주요 단계가 있습니다: 양식 요소 추출, 제출 조건을 충족하는 양식 요소 필터링, 키/값 쌍의 객체 배열로 결합

serializeArray: function() {
  //将form中的表单相关的元素取出来组成数组
  return this.map(function(){
    //表单节点有elements这个特征
    var elements = jQuery.prop( this, "elements" );
    return elements ? jQuery.makeArray( elements ) : this;
  })
  //过滤出为需要提交的表单元素(有name名称、非disabled元素、非提交按钮等元素、checkbox/radio的checked的元素)
  .filter(function(){
    var type = this.type;
    //使用.is(":disabled")过滤掉不可用的表单元素
    return this.name && !jQuery( this ).is( ":disabled" ) &&
    rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
    ( this.checked || !manipulation_rcheckableType.test( type ) );
  })
  //将表单提交元素组成name和value的对象数组
  .map(function( i, elem ){
    var val = jQuery( this ).val();
    return val == null ?
    null :
    jQuery.isArray( val ) ?
    jQuery.map( val, function( val ){
      return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
    }) :
    { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  }).get();
} 

jQuery의 필터링 결과는 일반 양식 제출 결과와 일치합니다. //제출해야 하는 양식 요소를 필터링합니다(이름, 비활성화되지 않은 요소, 제출되지 않은 버튼 및 기타 요소, 확인됨). 체크박스/라디오 요소) )

param 함수의 소스 코드는 다음과 같습니다. 두 가지 주요 프로세스가 있습니다. 키/값을 URI 구성 요소로 인코딩합니다(키와 값에 특수 기호가 나타나지 않도록 보장, 즉 "="의 정확성 보장). 분리), "&"를 사용하여 연결하고 공백 문자를 " "

으로 바꿉니다.
jQuery.param = function( a, traditional ) {
  var prefix,
  s = [],
  add = function( key, value ) {
      //如果value是函数,执行他得到真正的value
      value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
      //把key和value作为URI组件编码,保证key和value不会出现特殊符号,即保证了“=”分割的正确性
      s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
    };
  ...
  //传入的是数组,假设他是一个form表单键值对数组
  if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
    //序列化表单元素
    jQuery.each( a, function() {
      add( this.name, this.value );
    });
  } else {
    ...
  }
  //返回序列化结果,注意:空白符被替换成了"+"
  return s.join( "&" ).replace( r20, "+" );
}; 

  其中encodeURIComponent详细点击查看

b. ajax的事件监听

  给ajax绑定事件有三种方式

  1.全局事件:$(document).on(‘ajaxStart',func);

  2.ajax设置回调项:$.ajax({url: "php.html", complete: func }); 

  3.deferred绑定方式:$.ajax(…).done(func);

  接下来我们一一讲解他们的实现。

全局事件(ajaxStart/ajaxStop/ajaxComplete/ajaxError/ajaxSuccess/ajaxSend)

  使用.on事件绑定这种通用方式我们毫无疑问是可以绑定ajax监听事件,除此之外还可以直接使用$(…).ajaxStart(func)来绑定事件。他们的实现也是用.on来绑定。

jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
    jQuery.fn[ type ] = function( fn ){
      return this.on( type, fn );
    };
}); 

  触发事件比较简单,在进行ajax处理过程中在合适的时机直接使用jQuery.event.trigger直接触发。以ajaxStart为例

   //如果此时没有正在执行的请求,则触发ajaxStart事件
      if ( fireGlobals && jQuery.active++ === 0 ) {
        jQuery.event.trigger("ajaxStart");
      }  

ajax设置回调项(beforeSend/complete/success/error)

  触发设置回调项分两种:beforeSend直接在适当的时机调用。源码

//调用beforeSend回调,如果回调返回失败或abort则返回中止
if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
        //中止如果没有准备好
        return jqXHR.abort();
      } 
  complete/success/error则利用Deferred的特性将回调添加到延时队列,等待延时状态处理。源码
//创建最终选项对象
s = jQuery.ajaxSetup( {}, options )
...
deferred = jQuery.Deferred(),
completeDeferred = jQuery.Callbacks("once memory"),
...
//添加延时事件
deferred.promise( jqXHR ).complete = completeDeferred.add;
jqXHR.success = jqXHR.done;
jqXHR.error = jqXHR.fail;
//安装回调到deferreds上
for ( i in { success: 1, error: 1, complete: 1 } ) {
jqXHR[ i ]( s[ i ] );
}
//在ajax请求完成的处理函数中执行completeDeferred的延时列表
function done(){
...
//执行Complete处理
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
...
} 

deferred方式绑定回调

  Deferred方式绑定事件就不用特别说明了,因为ajax本身就是一个延时对象。直接使用$.ajax(…).done(fn).fail(fn). progress(fn).always(fn).then(fn)。源码

deferred = jQuery.Deferred(),
completeDeferred = jQuery.Callbacks("once memory"),
...
deferred.promise( jqXHR ).complete = completeDeferred.add;
...
return jqXHR;
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.