Архив категории «Прочее»

  • Подключение entity в XSL-шаблон

    Я очень люблю использовать XSL в качестве шаблонизатора — более гибкого механизма для вывода HTML/XML не придумаешь. А еще я использую Eclipse в качестве основной среды разработки: хоть он тяжелый и глючный, собака, но он единственный удовлетворяет большинство моих потребностей (никуда не перелезу, пока там не появится аналог PyDev и Mylyn).

    Шаблоны, которые я использую, построены на кастомных энтити. Так как XSL-переменные нельзя использовать в атрибуте match шаблона, это довольно удобный способ их эмулировать:

    <!ENTITY navigation "/document/system/navigation[@type = 'root']">
    ...
    <xsl:template match="&navigation;">
    	<ul id="nav">
    		...
    	</ul>
    </xsl:template>
    

    Все энтити хранятся в отдельном файле (entities.dtd), которые я подключаю вот так:

    
    <!DOCTYPE xsl:stylesheet SYSTEM "entities.dtd">
    
    <xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	...
    </xsl:stylesheet>
    

    В «штатном» Eclipse XSL editor это приводит к тому, что перестает code complete по XSL-тэгам — это баг всего Web Tools Project, связанный с тем, что при одновременном использовании XML Schema и внешнего файла с энтити предпочтение по code complete отдается последнему. Поиск решения этой проблемы привел меня к довольно интересному открытию. Теперь энтити я подключаю вот так:

    <!DOCTYPE xsl:stylesheet [
    	<!ENTITY % core SYSTEM "entities.dtd">
    	%core;
    ]>
    

    Это не только восстанавливает работу code complete, но и добавляет следующее преимущество: можно создавать локальные энтити в каждом файле и матчить на них шаблоны:

    <!DOCTYPE xsl:stylesheet [
    	<!ENTITY % core SYSTEM "entities.dtd">
    	%core;
    	<!ENTITY my_entity "/path/to/element[@with = 'very complex expression']">
    ]>
    ...
    <xsl:template match="&my_entity;">
    	сделать что-нибудь
    </xsl:template>
    
    <xsl:template match="&my_entity;[@some_attr = 'true']">
    	сделать что-нибудь другое
    </xsl:template>
    
    Метки: , ,
  • Техсуппорт по-русски

    Недавно один из клиентов переслал мне письмо, пришедшее на support@ от одного недовольного пользователя, который заявлял, что не может выполнить какие-то действия на сайте. Причина: появляется сообщение, что в его браузере чего-то сделать нельзя. Я был крайне удивлен этим, так как сам лично контролирую поддержку проекта и таких сообщений на сайте не должно быть в принципе.

    Но суть не в этом. На просьбу прислать ссылку на страницу, где появляется такое сообщение, а также название и версию браузера получил вот такой ответ:

    значит, объясняю, как решаются такие вопросы:

    [...]

    если все везде работает — пишете любому клиенту “ставь последнюю версию браузера и не парь нам мозги, все везде должно работать”

    если что-то где-то не работает — ставите на заглавник определитение браузера и пишете тем, кому не повезло, что им не повезло — сразу, чтобы они время не теряли

    [...]

    могу проконсультировать вашу контору по этому и подобным вопросам, чтобы не ерундой занимались, а эффективно обслуживали клиентов

    И дело тут совсем не в том, что на банальную просьбу выслать URL и название браузера я получил нравоучения о том, как жить дальше. А в том, что такой «консультант» с порога предлагает писать пользователям «ставь последнюю версию браузера и не парь нам мозги», даже не исследовав проблему.

    К моему великому сожалению такая модель поведения типична для российский веб-разработчиков. Если где-то что-то не работает, то клиент обязательно должен разбиться в лепешку: поставить все обновления системы, десять раз перезагрузится, отключить все файерволы и антивирусы, проапгрэйдить свой компьютер, купить шаманский бубен, наконец (видел такой в магазине «Экспедиция»). И все это для того, чтобы 5 минут посмотреть на очередной шедевр подпольного сайтостроения Васи Пупкина. У разработчика, видите ли, в инкубаторных условиях все работает, а если клиент, не дай бог, нажал кнопки не в той последовательности — то виноват, конечно же, сам клиент.

    Потому что разработчик провозгласил себя священной коровой, которой все обязаны. Не работает кнопка? А в моем SuperMegaBrowser 0.6 alpha все работает замечательно, поставьте его себе. На странице все разъехалось? Ничего не знаю, у меня сайт валидный, должно везде работать, а если не работает — значит, у вас говеный браузер. У вас IE6? Сначала обновитесь хотя бы до IE7, а потом заходите на сайт. И мне плевать, что в вашем банке другие браузеры использовать нельзя, и что вы хотите купить на сайте, который сделал Я, телефон за 1000$. Идите ко всяким лузерам, которые не думают о валидности и верстают таблицами.

    Почему разработчики до сих пор не могут понять, что клиентов абсолютно не волнует размер мозолей на руках от постоянной дрочки на валидатор? Что дизайнерам пофигу, как вы сверстаете макет: таблицами или дивами. Что на дворе сейчас XXI век и инетрнет заполнен не гиками, а обычными пользователями, которые понятия не имеют, что такое HTML или JavaScript. Зато эти пользователи очень здорово умеют нажимать на кнопку «Купить» и следовать пошаговой инструкции, как расстаться с деньгами.

  • Почему сайты на флэше — это плохо

    Давно хотелось поделиться соображениями и опытом использования флэша на сайте. А также объяснить позицию Студии Лебедева в этом вопросе.

    Предыстория

    Когда-то давно студия начала отказываться от использования флэша для создания анимационных эффектов. Поначалу на это даже обращали внимание в описании проекта, а потом JavaScript-эффекты воспринимались как само собой разумеющееся.

    Из-за этого у многих людей возникло ощущение, что студия ненавидит флэш. Это в корне не верно — к флэшу студия относится так же, как и к любой другой технологии. А именно: применяет её там, где это действительно необходимо.

    У студии особый подход к созданию сайтов, приходится учитывать массу факторов, порой не заметных даже профессионалу: начиная от разного размера шрифта в браузере пользователя, заканчивая возможным желанием заказчика добавить ещё 10 пунктов в горизонтальное меню. Молчу про то, что все сайты должны растягиваться, причем растягиваться должен не только контентный блок, как это привыкли делать на Западе, а вообще весь сайт. В какой-то момент мы поняли, что заточить флэш-ролики под эти нужды гораздо сложнее и дольше, чем сделать анимации на JS.

    Так в чем проблема?

    Хочу сразу оговориться: в этой заметке я не затрагиваю промо-сайты вроде dexter.ru или Mitsubishi Lancer Sportback — это как раз примеры правильного использования флэша для создания нужного вау-эффекта у пользователя. Речь пойдет о тех случаях, когда флэш используют для моргающего и прыгающего меню, а также о сверхидиотских случаях создания информационных ресурсов полностью на флэше ради двух-трех примитивных эффектов (вспомните хотя бы top4top).

    Итак, какие же сложности возникают при использовании флэша?

    Наиболее актуальная и коварная проблема — внедрение флэша на страницу и использование альтернативного контента на случай отсутствия флэш-плагина. Да-да, я знаю, что есть SWFObject, но он не решает очень серьезную проблему, о которой многие даже не догадываются.

    В свое время я довольно много поработал с большими компаниями (несколько тысяч сотрудников). И практически у всех этих компаний была одна особенность: они активно боролись с распиздяйством своих сотрудников в рабочее время. Руководство искренне верило в то, что на работе нужно работать, а не видео смотреть и в игрушки играться. А в чем нынче распространяется весь развлекательный контент? Правильно, во флэше. Поэтому суровые админы таких компаний просто блокируют подобные файлы на уровне корпоративного файервола.

    Как это выглядит на практике с точки зрения веб-разработчика. После загрузки страницы SWFObject радостно сообщает: «Флэш-плагин у пользователя есть!». Разработчик без тени сомнения заменяет html-меню на флэшовое: это ведь так просто, написал swfobject.embedSWF() и все само работает. Но не тут-то было: между браузером пользователя и интернетом стоит злобный файервол, который, сверившись со своим черным списком, просто блокирует доступ к swf-файлу. В итоге пользователь остался и без html, и без флэша. И это при том, что у него может стоять самая последняя версия флэш-плагина.

    It’s always lupus

    Ещё одна проблема, которая возникает при использовании флэшовых компонентов на сайте, это их «чужеродность» по отношению к html. Для флэша необходимо создать некую прямоугольную область, в пределах которой будет происходить вся анимация. Например, для того, чтобы переместить картинку размером 100×100 из левого верхнего угла браузера в правый нижний необходимо создать блок размером со страницу. Естественно, в этот момент будет заблокирован весь интерфейс сайта без видимых на то, с точки зрения пользователя, причин.

    Зато на флэше проще делать сайты

    Одна из самых тупых отмазок, которые сегодня можно услышать. Обычно в таких случаях флэшер за 10 секунд создает какой-нибудь полупрозрачный градиентный блок со скругленными уголками и текстом внутри и с надменным видом спрашивает у бедного html-кодера: «Ну и сколько тебе времени нужно, чтобы это кроссбраузерно заверстать?».

    Что ж, давайте вернемся, так сказать, к самым примитивным вещам, о которых мы даже не думаем. Вот я верстаю простейший сайт: одна колонка шириной 70%, располагается по центру экрана. Контента в этом сайте уже на три экрана. Что делает браузер в таком случае? Показывает мне вертикальную прокрутку. Я могу прокрутить страницу любым известным мне способом: колесом мыши, пробелом, стрелками вверх/вниз, подергать за ползунок, в конце концов. То есть я уже на подсознательном уровне, ни секунды не задумываясь, листаю документ и получаю необходимую информацию.

    Что же происходит на флэшовом сайте? Начнем с того, что если контент не поместится в видимую область экрана, то не произойдет ровным счетом ничего, если об этом не позаботился флэшер. То есть флэшеру нужно воссоздать механизм прокрутки документа. Другой вопрос, как он воссоздаст этот механизм. Как правило, все ограничивается лишь созданием говеного скроллбара, который является единственным способом прокрутить документ. Флэшер помещает меня — пользователя — в абсолютно чужеродную среду, где мои инстинкты больше не действуют. Вместо того, чтобы получать удовольствие от проекта, мне необходимо сосредоточится на процессе получения необходимой информации. Это такая сломанная машина времени: меня хотят отправить в светлое будущее, но попадаю я в мрачное прошлое, когда мышек с колесиком ещё не изобрели.

    Дальше — больше. Простейшее желание вставить нумерованный список или таблицу в середину текста оборачивается настоящей головной болью для флэшера. Потому что у него есть TextField, который способен отображать только обычный текст и картинки, но никак не структуры данных. Чтобы создать хоть сколько-нибудь интересный текстовый эффект, нужно потратить несколько часов работы флэшера, а не 5 минут кодера на работу с CSS. Именно поэтому отличить флэшовые сайты от нефлэшовых можно по абсолютно уебанской текстовой работе — всем лень тратить время на то, что уже много лет нормально работает в браузерах.

    Можно долго хвастаться тем, что десятый флэш плеер умеет круто работать с 3D графикой, только он до сих пор не в состоянии открыть ссылку в новом табе по моему требованию. Сколько лет существуют табы в браузерах? Это — наглядный пример нарушения так называемого user experience. На флэшовых сайтах пользователь не может стандартными средствами увеличить размер шрифта, не может сохранить понравившуюся картинку на рабочий стол, не может использовать любимый плагин для автоматической прокрутки длинных текстов. Много чего из того, к чему он привыкал годами, нельзя сделать на флэшовых сайтах. Зато можно увидеть, как прикольно выезжает картинка, да. Или подолгу пялиться на прелоудер после каждого клика.

    ***

    Действительно ли проще и быстрее делать качественные сайты на флэше? Как вы считаете?

    Метки:
  • Пузырьки

    Пузырьки

    По-настоящему оценят страничку владельцы Маков.

    Метки:
  • Аякс ради аякса

    В последнее время наблюдаю абсолютно нездоровое стремление некоторых разработчиков делать сайты полностью на аяксе. Это когда нет переходов на разделы сайтов, они просто подгружаются на текущую страницу. Типичный пример использования технологии только ради того, чтобы сказать: она тут используется. Я не нашел ни одной проблемы, которую мог бы решить такой подход.

    Может, это я старею? Может, действительно за этим будущее и пора бы уже менять принципы создания сайтов? Вооружившись последним файрфоксом и файербагом решил проверить «под микроскопом» приведенные примеры. Действительно ли это наше будущее, или всего лишь очередной оральный вау-импульс для начинающих гиков?

    Основная проблема таких сайтов — сохранение истории навигации по сайту. Посмотрим, как это работает с точки зрения пользователя.

    1. Сайты, где используется раздражающая уже на пятом разе анимация, удалось завалить довольно быстро: достаточно быстро перейти по истории на 2—3 шага вперед/назад. В половине случаев я видел только крутящийся прелоудер, во второй половине случаев слетала история навигации. То есть я переходил куда угодно, но не туда, куда ожидал.
    2. Когда я хожу по истории обычных, олдскульных сайтов, браузер запоминает, где я закончил просматривать страницу. Угадайте с трех раз, какую часть страницы я видел на анимированных сайтах?
    3. Следующий пример поведения. Когда я захожу на сайты я обычно открываю интересующие меня страницы в новых табах с помощью Command-click. Естественно, некоторые разработчики плевать хотели на разные модели поведения пользователя, поэтому на одном сайте страницы загружались в том же окне при любом клике на ссылку.
    4. Даже не удивился, что кое-где перемещение по истории сопровождалось новым обращением на сервер. Такая вот экономия на траффике.

    Это те проблемы, которые я увидел как обычный пользователь. Теперь посмотрим, что я получу от такого подхода как разработчик. Иду на форум. Как и ожидалось, разработчики поимели целый букет проблем, которых раньше просто не было: начиная от неправильной инициализации скриптов при загрузке, заканчивая отслеживанием страниц с помощью Google Analytics.

    ***

    Всегда удивлялся тому, как разработчики любят усложнять себе жизнь. Проблемы не существует, но ее обязательно придумывают, не спят ночами чтобы решить ее, а потом радуются как дети работающему через жопу решению. К сожалению, программисты разучились думать как обычные люди — те самые, которые ежедневно ходят на сайты и ради которых эти сайты делаются. У таких разработчиков одна цель — показать, что они умеют пользоваться готовыми библиотеками.

    Но что больше всего меня позабавило: Яндекс-карты почему-то не подключаются на страницу, на них просто стоит ссылка. Вот такой вот аякс.

  • Краткий экскурс в профайлинг JS

    Недавно с коллегой переписывался о том, как нужно делать профайлиг JavaScript-кода. Решил, может информация будет еще кому-нибудь полезна. Предыстория: коллега делает анимацию на JS, пытаемся понять, почему она сильно тормозит.

    Внёс изменения. Поставил таймер на mouseOver. Получается, что функция calculateSize выполняется 20-23ms. До этого примерно так и было.

    Нужно не таймером, а профайлером замерять (есть в Firebug и последних версиях Webkit).

    Ну я имею в виду функцию FireBug’а console.time() и console.timeEnd(). Они делают то же, что профайлер, только для определенного куска кода.

    Так а зачем тебе для определенного куска в данном случае? Тебе же нужно видеть, какие именно функции у тебя выполняются в данный момент времени и искать проблемные места, а не произвольно замерять функции.

    Я просто не могу понять в этом профайлере где именно тормозит. Там всё исписано в init() :)

    Вот смотри, сейчас профайлер тебе говорит, что во время работы твоего эффекта больше всего ресурсов жрет функция init() из jQuery, которая вызывается почти 6000 раз:

    firebug1

    Так как сама по себе эта информация нам мало полезна, тебе нужно найти ту функцию, которая так часто вызывает init(). Для этого отсортируем данные по колонке Time (общее время выполнения функции). Видим, что на первом и втором месте стоит jQuery-функция, а на 3 и 4 — функции calculateSize() и imgSize(), время выполнения которых — 588 и 547 мс соответcтвенно.

    firebug2

    Тут явно видно, что сами эти функции выполняются очень быстро (см. Own Time), но вот они вызывают другие функции, которые и дают те самые 588 и 547 мс.

    Смотрим calculateSize(), проблемные места:

    var prevImg = slctdImg.parent().prevAll();
    var nextImg = slctdImg.parent().nextAll();
    

    Это все выборки по дереву, очень тяжелые операции.

    Смотрим imgSize(), проблемные места:

    imgCont.width(newWidth).height(newHeight);
    imgCont.css({
    	width: newWidth,
    	height: newHeight,
    	margin: (!dir) ? "0 0 " + k + "px 0" : k + "px 0 0 0",
    	zIndex: count - num,
    	opacity: 1 - (num) / 30
    });
    

    два раза устанавливаешь width и height

    В целом, чтобы избавиться от этих проблемных мест, нужно полностью переписать логику работы библиотеки. Другой вопрос, даст ли это необходимый прирост производительности. Попробуй временно отключить изменение размеров картинки и opacity, просто сделай перемещение и посмотри, как работает. Если работает медленно, то проблема описана выше. Если работает быстро, значит, проблема в изменении габаритов и opacity, тут уже вряд ли что-то поделаешь.

    Метки: , , ,
  • Смотрим в браузер клиента

    Нереально крутой сервис: http://www.wizhelp.com.

    Позволяет прямо в браузере смотреть и управлять удаленным рабочим столом. Например, пишет клиент: «У меня что-то не работает на сайте». Максимум, что можно добиться от клиента в такой ситуации — скриншот сайта, а потом пытаться «вылечить по фотографии». Теперь его можно отправить на этот абсолютно бесплатный сервис и посмотреть, что же на самом деле у него происходит.

    Все что нужно — поддержка Java. Протестировал на маке и винде, все работает замечательно.

  • rocon — подробности

    Рассмотрим, как работает библиотека rocon.

    rocon дожидается загрузки DOM-дерева документа и ищет все элементы с классом rcN, где N — радиус скругления, и добавляет им скругленные уголки.

    Safari

    Создается новая новая таблица стилей в документе, в которой классам rcN указываются CSS-свойства -webkit-border-radius и -khtml-border-radius.

    Firefox

    По аналогии с Safari указывается CSS-свойство -moz-border-radius.

    Opera

    Через <canvas> рисуется звездочка, которая затем преобразуется в data: URL картинку. Затем для каждого уголка создается по отдельному элементу и каждому указывается эта картинка в качестве фона. Все CSS-свойства указываются в таблице стилей, а не в самих элементах (это значит, что их можно легко перекрывать).

    Internet Explorer

    Такой же способ, как и у Opera, только используется VML. Соответственно, уголок вставляется как элемент, а не как фоновая картинка.

    С первыми двумя случаями все довольно просто: используем внутренние возможности браузера для рисования скругленных уголков. Для двух последних все намного сложнее. После инициализации основному блоку указывается класс rocon-init — это значит, что элемент был инициализирован. Также добавляется класс rocon__N, где N — некий порядковый номер, характеризующий набор уникальных свойств блока: радиус скругления, цвет фона, толщина бордюра и так далее. Соответственно, если попадаются элементы с одинаковым набором этих характеристик, новые уголки не рисуются, а достаются из кэша. Для каждого создаваемого элемента с уголком присваиваются классы rocon-tl, rocon-tr, rocon-bl, rocon-br, что означает, соответственно, левый верхний, правый верхний, левый нижний и правый нижний. Все стили записываются в новую таблицу стилей, а не в сам элемент. Тем самым вы можете менять некоторые свойства уголка через CSS, что будет особенно полезно в IE6. Дело в том, что в этом браузере неправильно работают CSS-свойства right и bottom. И если первое свойство я смог эмулировать с помощью margin-left: 100%, то со вторым проблема: я пока не знаю, как это можно исправить. Поэтому вам придется указывать вручную его позицию. Так как уголок добавляется в самый конец блока, вы можете воспользоваться тем, что его сместит контент блока в самый низ и подкорректировать его позицию с помощью свойства margin-top (на забудьте поставить bottom: auto).

    Можно в любой момент добавить любому блоку скругление или поменять его свойства (радиус, цвет фона и так далее). Чтобы изменения вступили в силу, нужно вызвать метод rocon.update(elem), где elem — указатель на элемент, который нужно обновить.

    Все пожелания и комментарии просьба указывать в багтрекере.

    Метки: , ,
  • rocon — экспериментальная библиотека для создания скругленных уголков

    Устав каждый раз создавать новые картинки для блоков с разным радиусом скругления и цветом фона, решил создать библиотеку, которая сама будет рисовать необходимые картинки и размещать их на странице.

    Библиотека называется rocon. Работает она довольно просто: подключаете файл rounded-corners.js на страницу и нужным блокам указываете класс rcN, где N — радиус скругления:

    <script type="text/javascript" src="rounded-corners.js"></script>
    <div class="rc10" style="background: red; padding: 5px;">Rounded block</div>
    

    Получим блок с радиусом скругления в 10 пикселей.

    Метод создания скруглений основан на моей лекции в Техногрете. Так же, как и в лекции, можно создавать скругления двух типов: формы и контр-формы. По умолчанию создается контр-форма, для создания формы нужно указать класс rc-shape:

    <script type="text/javascript" src="rounded-corners.js"></script>
    <div class="rc10 rc-shape" style="background: red; padding: 5px;">Rounded block</div>
    

    Вот основные достоинства библиотеки:

    • Работает во всех современных браузерах: IE6+, Safari 3+, Firefox 2+, Opera 9.25+.
    • Позволяет без проблем с производительностью создавать десятки скругленных блоков на странице (в моих тестах 100 блоков создавалось около 1 секунды).
    • Можно динамически менять цвет фона блока и радиус скругления с помощью метода rocon.update(elem).
    • Уголками можно управлять через CSS.
    • В IE6 этот способ будет работать намного быстрее, чем использование полупрозрачных PNG через AlphaImageLoader.

    Больше примеров можно найти на тестовой странице. Предупреждаю, что библиотека экспериментальная и находится в стадии активной разработки.

    Скачать с Google.Code

новое →