Здравствуйте уважаемые читатели, на официальном сайте появилась новая версия jQuery 1.5, что нового придумала команда разработчиков?.
Прежде всего, изменения коснулись модуля ajax, в него было добавлено обширное количество новых опций - contents, converters, crossDomain, headers, statusCode!
Начнем с простого - с опции statusCode, данная опция запускает функцию при возврате сервером определенного HTTP ответа, например - 404, 503 и т.д. К примеру, в следующем случае, если ответ будет 404, то появиться диалоговое окно:
| 1. | $.ajax({ |
| 2. | statusCode: {404: function() { |
| 3. | alert('page not found'); |
| 4. | } |
| 5. | } |
| 6. | }); |
Если запрос завершился успешно, опция statusCode принимает те же параметры, что и опция success, если запрос завершится ошибкой, то параметры будут те же, что и параметры возвращаемые опцией error.
Опция headers так же является нововведением и представляет собой объект содержащий данные об HTTP заголовках запроса, передаваемые вместе с запросом, значения содержащиеся в данной опции могут быть перезаписаны в опции beforeSend. Синтаксис использования данной опции очень прост:
| 1. | $.ajax({ |
| 2. | headers: { |
| 3. | "Content-Type": "application/json", |
| 4. | "Accept": "application/json" |
| 5. | }, |
| 6. | type: "POST", |
| 7. | url: "/JSON-RPC", |
| 8. | processData: false, |
| 9. | data: jsonData, |
| 10. | dataType: "json", |
| 11. | success: function(json){ |
| 12. | do something... |
| 13. | } |
| 14. | }); |
Опция contents определяет, как должен jQuery разобрать ответ сервера, основываясь на заголовке Content-Type.
Добавлена опция converters, предназначенная для конвертации полученных данных из одного типа данных в другой, так же опция предназначена для создания собственных типов содержимого (заголовок Content-Type), в нижеуказанном примере, конечно не конвертирую данные, но преобразую строку в верхний регистр встроенным методом toUpperCase():
| 1. | $(document).ready(function() { |
| 2. | response = $.ajax({ |
| 3. | converters: {"* text": window.String, "text html": true, "text json": jQuery.parseJSON, "text xml": function(data){return data.toUpperCase()}}, |
| 4. | |
| 5. | type: "POST", |
| 6. | url: "test1.php", |
| 7. | dataType: "xml", |
| 8. | cache: "false", |
| 9. | |
| 10. | success: function(result) { |
| 11. | alert($(result).find("city").text()); |
| 12. | } |
| 13. | }); |
| 14. | }); |
Я думаю, в общих чертах, Вы разобрались с опцией converters, пойдём дальше - к опции crossDomain. Данная опция так же не проста в понимании с первого взгляда, но в целом, суть её в том, что если Вы установите значение опции как true, то на серверной стороне позволено будет создавать перенаправление на другой домен(то есть, вы задаёте таким образом, кроссдоменный запрос), что, видимо, - по умолчанию запрещено в jQuery.
Пожалуй, об изменениях в ajax можно закончить рассказывать, однако хотелось просветить аудиторию по поводу объекта jqXHR, поскольку с него начнётся объяснение того, что отличает jQuery от множества других подобных фреймовиков. Данный объект стал поддерживать возможность установки очереди функций для ajax, в зависимости от типа ответа. Разберём пример:
| 1. | <script type="text/javascript"> |
| 2. | $(document).ready(function() { |
| 3. | jqxhr = $.ajax({url: "test1.php"}) |
| 4. | .success(function() { alert("success"); }) |
| 5. | .error(function() { alert("error"); }) |
| 6. | .complete(function() { alert("complete"); }); |
| 7. | |
| 8. | // ваш код ... |
| 9. | |
| 10. | // вторая функция в очереди после успешного выполнения |
| 11. | jqxhr.complete(function(){ alert("second complete"); }); |
| 12. | }); |
| 13. | </script> |
При успешности запроса, сперва будет выполнена срока 4, после 6, затем строка 11. Указанный порядок можно установить с помощью отложенных методов к подробному рассмотрению которых мы и подошли.
К данным методам относятся методы, добавленные в jQuery 1.5:
Разберём каждую подробней!
Методы deferred.done(), deferred.fail(), deferred.then() схожи тем, что выполняют функцию обратного вызова с тем лишь отличием, метод deferred.done() запускается после успешного выполнения, deferred.fail() - после не успешного, deferred.then() - после функций специально созданных. Можно сказать, что методы deferred.done(), deferred.fail() - аналоги методов .success( doneCallbacks ) .error( failCallbacks ). Общий пример:
| 1. | <script type="text/javascript"> |
| 2. | $(document).ready(function() { |
| 3. | function getData(){ |
| 4. | return $.get('test1.php'); |
| 5. | } |
| 6. | |
| 7. | function showDiv(){ |
| 8. | var dfd = $.Deferred(); |
| 9. | |
| 10. | dfd.done(function(){ |
| 11. | console.log('Анимация завершена, но не ajax'); |
| 12. | }); |
| 13. | |
| 14. | $('#foo').fadeIn( 1000, dfd.resolve ); |
| 15. | |
| 16. | return dfd.promise(); |
| 17. | |
| 18. | } |
| 19. | |
| 20. | |
| 21. | $.when( showDiv(),getData() ) |
| 22. | .then(function(){ |
| 23. | console.log( 'Ajax и анимация(fadeIn) завершены!' ); |
| 24. | }) |
| 25. | .fail(function(){ |
| 26. | console.log( 'Метод fail будет запущен только в случае не успешного выполнения одной из функций -showDiv(),getData() .' ); |
| 27. | }); |
| 28. | }); |
| 29. | </script> |
| 30. |
В вышеуказанном коде, в строке 8 создаётся объект Deferred(), который используется для создания очередей функций, очередь инициируется с помощью метода resolve(), очищается очередь с помощью метода reject(). Строка 14 создаёт очередь, используя объект Deferred(), при этом функции, содержащиеся в очереди, начинают выполняться, как только функция fadeIn() полностью завершится. Объект Deferred() необходимо указывать для тех методов или пользовательских функций, в которых отсутствует встроенный объект Deferred(). Объект Deferred() встроен во все методы jQuery ajax на основе библиотеки promise. В конце всего листинга есть метод $.when(), данный метод так же является нововведением в jQuery 1.5, суть его согласно официальной документации - в отслеживании выполнения функций, указанных в качестве аргументов, и запуске очереди функций указанных далее.
Метод when() принимает один или несколько объектов, которые должны содержать встроенные объекты Deferred(), если вы передадите в качестве аргументов метода when() простые объекты, то все функции обратного вызова будут вызваны немедленно, а не в порядке очередности. Поэтому в следующем листинге alert сработает после успешного выполнения запроса:
| 1. | $.when( $.ajax("test.aspx") ).then(function(ajaxArgs){ |
| 2. | alert(ajaxArgs[1]); /* ajaxArgs is [ "success", statusText, jqXHR ] */ |
| 3. | }); |
А в этом листинге метод when потеряет практическую надобность, так как в него передан не объект Deferred(), а простая функция.
| 1. | function showDiv(){ |
| 2. | $('#foo').fadeIn( 5000 ); |
| 3. | } |
| 4. | |
| 5. | $.when( showDiv() ) |
| 6. | .then(function(){ |
| 7. | console.log( 'Ajax и анимация(fadeIn) завершены!' ); |
| 8. | }); |
Ёще один пример, разъясняющий суть метода when, в котором , при нажатии по ссылке, проверяется метка времени и в зависимости от этого происходит запрос к странице test1.php в 9 строке, если ранее запрос совершался хотя бы раз, то с помощью строки ( $.data( element, 'timestamp', timestamp );) устанавливается атрибут timestamp, с той целью, чтобы кэшировать данные и не повторять запроса:
| 1. | <script type="text/javascript"> |
| 2. | $(document).ready(function(){ |
| 3. | function startTask( element ){ |
| 4. | var timestamp = $.data( element, 'timestamp' ); |
| 5. | |
| 6. | if( timestamp ){ |
| 7. | return timestamp; |
| 8. | } else { |
| 9. | return $.get('test1.php').success(function( timestamp ){ |
| 10. | alert(timestamp) |
| 11. | $.data( element, 'timestamp', timestamp ); |
| 12. | }); |
| 13. | } |
| 14. | } |
| 15. | |
| 16. | $('#launchApplication').click(function( event ){ |
| 17. | |
| 18. | event.preventDefault(); |
| 19. | |
| 20. | $.when( startTask(this) ).done(function( timestamp ){ |
| 21. | $('#status').html( '<p>You first started this task on: ' + timestamp + '</p>'); |
| 22. | }); |
| 23. | |
| 24. | |
| 25. | }); |
| 26. | }); |
| 27. | </script> |
Метод reject удаляют созданную очередь, рассмотрим его на примере недавно указанном выше:
| 1. | <script type="text/javascript"> |
| 2. | $(document).ready(function() { |
| 3. | function getData(){ |
| 4. | return $.get('test1.php'); |
| 5. | } |
| 6. | |
| 7. | function showDiv(){ |
| 8. | var dfd = $.Deferred(); |
| 9. | |
| 10. | dfd.done(function(){ |
| 11. | console.log('Анимация завершена, но не ajax'); |
| 12. | }); |
| 13. | dfd.reject(); |
| 14. | $('#foo').fadeIn( 1000, dfd.resolve ); |
| 15. | |
| 16. | return dfd.promise(); |
| 17. | |
| 18. | } |
| 19. | |
| 20. | |
| 21. | $.when( showDiv(),getData() ) |
| 22. | .then(function( ajaxResult ){ |
| 23. | console.log('Анимация и AJAX запрос завершены!'); |
| 24. | |
| 25. | // 'ajaxResult' ответ сервера |
| 26. | }); |
| 27. | }); |
| 28. | </script> |
В 13 строке происходит удаление очереди создаваемой объектом Deferred, в результате чего так метод then не будет выполнен, так как метод when не получит завершение функции showDiv().
Методы выполняют те же функции, что и методы resolve и reject, однако вам позволено использовать дополнительные аргументы которые будут доступны в методе done, через this, например:
| 1. | <script type="text/javascript"> |
| 2. | $(document).ready(function() { |
| 3. | |
| 4. | var dfd = $.Deferred(); |
| 5. | var dfdnew = $.Deferred(); |
| 6. | |
| 7. | dfd.done(function(){ |
| 8. | console.log('Массив с именем: '+this.name); |
| 9. | }); |
| 10. | dfdnew.done(function(){ |
| 11. | console.log('Массив с именем: '+this.name); |
| 12. | }); |
| 13. | |
| 14. | var data = {name: "Pete",age: 15}; |
| 15. | var newdata = {name: "Alex",age: 15}; |
| 16. | |
| 17. | dfdnew.resolveWith(newdata); |
| 18. | dfd.resolveWith(data); |
| 19. | |
| 20. | return dfd.promise(); |
| 21. | |
| 22. | }); |
| 23. | </script> |
Объект jqXHR переработан, в jQuery теперь каждый метод поддерживает объект Deferred, нет надобности создавать его явно, так же все методы ajax стали поддерживать повторяющиеся функции обратного вызова, основанные на ajax событиях (error, .success и .complete). В следующем листинге создана цепь функций обратного вызова, в которой созданы так же повторяющиеся методы (complete()):
| 1. | var jqxhr = $.get("example.php", function() { |
| 2. | alert("success"); |
| 3. | }) |
| 4. | .success(function() { alert("second success"); }) |
| 5. | .error(function() { alert("error"); }) |
| 6. | .complete(function() { alert("complete"); }); |
| 7. | |
| 8. | |
| 9. | |
| 10. | jqxhr.complete(function(){ alert("second complete"); }); |
Согласно официальному руководству, данный метод является кроссбраузерным решением для разбора xml файлов. Пример официального руководства:
| 1. | <script type="text/javascript"> |
| 2. | $(document).ready(function() { |
| 3. | |
| 4. | var xml = '<rss version="2.0"><channel><title>RSS Title</title></channel></rss>', |
| 5. | xmlDoc = $.parseXML( xml ), |
| 6. | $xml = $( xmlDoc ), |
| 7. | $title = $xml.find( 'title' ); |
| 8. | |
| 9. | // append "RSS Title" to #someElement |
| 10. | $( '#foo' ).append( $title.text() ); |
| 11. | |
| 12. | // change the title to "XML Title" |
| 13. | $title.text( 'XML Title' ); |
| 14. | |
| 15. | // append "XML Title" to #anotherElement |
| 16. | $( '#new' ).append( $title.text() ); |
| 17. | |
| 18. | }); |
| 19. | </script> |
Метод создаёт новую копию jQuery объекта ,чьи свойства и методы могут быть изменены без изменение оригинальных свойств и методов jQuery. Ниже, указан пример, в котором создана полная копия jQuery, в которой создается собственный метод myCustomMethod.
| 1. | <script type="text/javascript"> |
| 2. | $(document).ready(function() { |
| 3. | |
| 4. | var sub$ = jQuery.sub(); |
| 5. | |
| 6. | sub$.fn.myCustomMethod = function(){ |
| 7. | return 'just for me'; |
| 8. | }; |
| 9. | |
| 10. | sub$(document).ready(function() { |
| 11. | sub$('body').myCustomMethod() // 'just for me' |
| 12. | }); |
| 13. | |
| 14. | alert(typeof jQuery('body').myCustomMethod) // undefined |
| 15. | // alert(typeof jQuery('body').myCustomMethod) // для примера |
| 16. | }); |
| 17. | </script> |
На последок расскажу Вам про изменения касающиеся метода clone, - в него добавлен необязательный аргумент deepWithDataAndEvents, который необходимо использовать одновременно с аргументом withDataAndEvents, для того чтобы скопировать обработчики событий даже для вложенных элементов копируемого родительского элемента.
1.1
Александр
Не за что!