02
Июл

Очередная кроссбраузерность

Написал Максим Крентовский в Архив изысканий

Вы, наверное, любите делать сайты с применением AJAX. И наверняка души не чаете в библиотеке Prototype и браузере Mozilla Firefox с плагином FireBug. Последний, кстати, здорово помогает, когда что-то вполне очевидное перестает работать как надо.

Все бы ничего, но чтобы вэб-разработчикам жизнь малиной не казалась, существует «мировой заговор браузеров». Иными словами, то, что вполне адекватно работает в одном браузере, может успешно неработать в другом.

Итак, начнем с синтаксиса. Например, вы написали такой простенький апдейтер:

1
2
3
4
5
6
var myAjax = new Ajax.Updater('productitem', "gpi.php", {
                evalScripts: true,
                method: 'get',
                parameters: pars,
                asynchronous: true,
            });

Приглядитесь получше? Есть ошибки? Странно, а в FireFox работает. А вот Opera и IE бастуют. К чему бы это? Елки! Мы же забыли убрать запятую после asynchronous: true! Только один браузер посчитал это как пустой элемент, а остальные — как ошибку синтаксиса. Внимательнее надо быть, товарисч!

Другой пример. Все мы знаем про регулярные выражения. Или не знаем. Так или иначе, скоро жизнь заставит, так что… Берем простой код:

1
var ai = obj.elements[i].name.split(/\D/);

…и удивляемся: там, где Opera и Firefox вернут массивы, IE — вернет таки значение! Не, разумеется, мы можем использовать exec, который работает примерно одинаково, ну а если нам вдруг захотелось серьезных извращений? Решение может быть найдено в следующем wtf-коде:

1
2
var ai = obj.elements[i].name.split(/\D/);
var a = (Prototype.Browser.IE) ? ai : ai[2];

Некрасиво? Согласен. Надо переделать.

И напоследок маленькое «хозяйке на заметку»:

Ajax.Updeter развращает. В случае, если посетитель перейдет на несуществующую страницу, он получит 404 в чистом виде, а вот если по каким-либо причинам браузер не может подгрузить кусок данных по AJAX-у, то… клиент будет тупо втыкать в бегущие огоньки, пока, наконец, не закроет страницу и попробует зайти на другой аналогичный сайт, после чего обнаружит, что у него банально грохнулся канал.

Потому хорошим приемом будет использование следующей конструкции:

1
2
3
4
5
6
new Ajax.Updater( { success: 'items' }, '/items', {
  parameters: { text: $F('text') },
  onFailure: function() {
     alert('Не удалось выполнить требуемую операцию, попробуйте еще раз!');
  }
});
Комментирование недоступно.
Максим Крентовский
системный архитектор
E-mail / GTalk: mkrentovskiy@gmail.com
Skype: mkrentovskiy