Показаны сообщения с ярлыком HTML. Показать все сообщения
Показаны сообщения с ярлыком HTML. Показать все сообщения

суббота, 29 сентября 2012 г.

Codeigniter Bootstrap Pagination

Twitter Bootstrap стал безумно популярным фронт-энд фреймворком. Всё чаще и чаще слышу от клиентов, хочу «бутстрэп» (хотя они до конца сами не понимают что это), это больше дань моде, ну это такое. В этой статье хочу рассказать, как адаптировать стандартый pagination класс CodeIgniter-а под новомодный Bootstrap style.

Я находил много решений, вплоть до кастомного MY_Pagination класса для стилизации Bootstrap под CI, каждый ухитряется, как может. Но, я полагаю, это не лучший выход. Вы лишаетесь гибкости, перекрывая нативный класс пагинации кодигнайтера, если выходит новая версия CodeIgniter обновился класс Pagination, то прийдётся заново его адаптировать и искать что изменилось.

Гораздо более удобный способ, это через конфигурацию самого Pagination навесить все необходимые стили и изменить только «обвёртку» для стандартных элементов интерфейса. Сделать это легко. Создаём в папке application/config/ файл с именем pagination.php. В этот файл дописываем следующий конфиг для Pagination Class:

/* twitter bootstrap overrides */
$config['full_tag_open'] = '<div class="pagination pagination-centered"><ul>';
$config['full_tag_close'] = '</ul></div><!--/pagination-->';

$config['first_link'] = '&laquo; First';
$config['first_tag_open'] = '<li class="prev page">';
$config['first_tag_close'] = '</li>';

$config['last_link'] = 'Last &raquo;';
$config['last_tag_open'] = '<li class="next page">';
$config['last_tag_close'] = '</li>';

$config['next_link'] = 'Next &rarr;';
$config['next_tag_open'] = '<li class="next page">';
$config['next_tag_close'] = '</li>';

$config['prev_link'] = '&larr; Previous';
$config['prev_tag_open'] = '<li class="prev page">';
$config['prev_tag_close'] = '</li>';

$config['cur_tag_open'] = '<li class="active"><a href="">';
$config['cur_tag_close'] = '</a></li>';

$config['num_tag_open'] = '<li class="page">';
$config['num_tag_close'] = '</li>';
/* END twitter bootstrap overrides */

Ну и финальный штрих, это подгрузить наш конфигурационный файл в место, где происходит инициализация pagination в самом контроллере, например:

…
$this->config->load('pagination', TRUE);
$config = array_merge($this->config->item('pagination'), Array(
  'base_url'   => site_url('items/'),
  'total_rows'  => $total,
  'per_page'   => 10,
  'uri_segment'  => 2
  ));
$this->load->library('pagination');
$this->pagination->initialize($config);
…

Всё, теперь в любом месте, где вы будете рендерить элементы для постраничной навигации, будет выводиться Codeigniter Bootstrap Pagination. Приведеный выше пример гарантированно рабочий и отлаженный, работает на версии CodeIgniter Framework 2.1.2 и Twitter Bootstrap Version 2.1.1.

вторник, 26 апреля 2011 г.

Disabling arrow keys at Fancybox (отменить перехват курсорных клавиш в Fancybox)

Используя замечательный плагин Fancybox для jQuery, натолкнулся на один очень неприятный момент. При использовании его, например, в совокупности с элементами формы input или textarea невозможно было перемещаться внутри этих элементов влево и вправо, используя курсорные клавиши. Происходило это по причине перехвата событий от клавиш-стрелок (keycodes 37 и 39) функцией навигации в плагине Fancybox. Оказалось, что простой опции отключить навигацию курсорными клавишами в этом плагине нет, пришлось хучить.

Чтобы обойти дефолтное поведение, решил создать дополнительную переменную в конфиге, и подправить функцию навигации плагина.

Для начала я добавил новую переменную в файл, где хранились дефолтные значения оцпий для Fancybox, назвал её disableNavButtons:

$.fn.fancybox.defaults = {
 ...
 disableNavButtons : true,
 ...
};

Затем, пропатчил функцию fancybox_set_navigation, в условных выражениях добавил обработчики на проверку равен ли e.keycode 37 или 39 и при этом currentOpts.disableNavButtons выставлено в false. И если условие выполняется, то переназначить действия для левой и правой курсорных клавиш.

function fancybox_set_navigation() {
  $(document).unbind('keydown.fb').bind('keydown.fb', function(e) {
    if (e.keyCode == 27 && currentOpts.enableEscapeButton) {
      e.preventDefault();
      $.fancybox.close();
    
    } else if (e.keyCode == 37 && !currentOpts.disableNavButtons) {
      e.preventDefault();
      $.fancybox.prev();
    
    } else if (e.keyCode == 39 && !currentOpts.disableNavButtons) {
      e.preventDefault();
      $.fancybox.next();
    }
    ...

вторник, 1 марта 2011 г.

Простой RSS-ридер на PHP (Simple RSS reader using PHP)

Думаю, что такое RSS все знают, это базовый XML формат для публикации сводной информации по сайту. Сама аббревиатура RSS как раз это и раскрывает: Really Simple Syndication (RSS 2.x), что дословно переводится как «очень простой сбор сводной информации».

Допустим, у нас есть главный сайт и отдельно блог с новостями, они разнесены на разные поддомены и работают с разными БД, на разных CMS. Нам необходимо встроить в новостной блок на главной странице последние новости, опубликованные в блоге. Для этого нам вовсе не понадобится писать функций импорта, который будет обращаться к другой БД, разбираться со структурой таблиц, например, движка WordPress. Есть более простой путь это реализовать – сделать экспорт-импорт через RSS.

Функцию экспорта краткой версии новостей (постов из блога) нам писать не придётся, RSS-каналы есть в любом блоггерском движке. А вот написать клиентскую часть, на PHP, тоже не составит труда, для этого надо написать простой парсер RSS-канала.

Что же представляет из себя RSS-канал, давайте рассмотрим. Корневой элемент RSS-документа содержит единый элемент channel. Элемент channel содержит метаданные о канале, включая интересующие нас title (заголовок), language (язык), pubDate (дата обновления канала) и link (URL блога). Так же внутри содержатся статьи, заключённые в тег item. Каждый item имеет элемент link, с URL на статью, ну и непосредственно заголовок title и описание description, которые содержат простой текст.

PHP5 имеет достаточно «жирные» инструменты, для доступа к различным узлам XML, а всё благодаря SimpleXML API. Есть прекрасная функция simplexml_load_file(), которая и делает всю работу. Она не только загружает документ из указанного URL, парсит (разбирает) документ, но и ставит указатель на корневой элемент документа, которым выступает у нас 'rss'.

Приведу пример простого RSS-ридера на PHP используя SimpleXML API:

<?php
$items_to_display = 2;
$url = "http://webaurum.blogspot.com/feeds/posts/default";
$rss = simplexml_load_file($url);
if ($rss)
{
  echo '<h1>' . $rss->channel->title . '</h1>';
  echo '<br/>' . $rss->channel->pubDate . '<br/>';
  $items = $rss->channel->item;
  $item_count = 0;
  foreach($items as $item)
  {
    $title = $item->title;
    $link = $item->link;
    $ts = strtotime($item->pubDate);
    $published_on = date("Y-m-d", $ts);
    $description = $item->description;
    echo '<h3><a href="' . $link . '">' . $title . '</a></h3>';
    echo '<span>' . $published_on . '</span>';
    echo '<p>' . $description . '</p>';
    if(++$item_count >= $items_to_display)
      break;
  }
}
?>

Скрипт обращается по адресу указанному в переменной $url, считывает RSS feed, парсит документ, и выводит количество записей, ограниченных количеством, заданном в переменной $items_to_display.

Такой скрипт вообще можно положить отдельным файлом на сервере, и делать простой SSI include в обычную статичную html страницу, во всех местах, где нужен этот блок новостей.

четверг, 3 февраля 2011 г.

Подсказки в input: text полях (default search text at input using jQuery)

На сайтах часто попадаются подсказки в input: text полях, например, в полях для поиска, когда написан текст «Поиск по сайту», а при вводе в него значения – он исчезает и пользователь может ввести критерий поиска.

Алгоритм работы данного функционала прост. Задается текст-подсказка (описание поля) по умолчанию, зачастую бледного цвета, а при фокусе на элементе всё очищается. При потере фокуса, если значение поля осталось пустым, то снова возвращается текст подсказка.

Самый простой способ, для «любителей» размещать весь код инлайн, реализуется при помощи JS, навесив два события onfocus и onblur на input элемент формы:

<input type="text" value="Поиск по сайту…" onfocus="if (this.value == 'Поиск по сайту…') {this.value = '';}" onblur="if (this.value == '') {this.value ='Поиск по сайту…';}" />

Есть, конечно, и много уже готовых плагинов для отображения подсказки в input полях, но мне почему-то больше всех приглянулся jquery.hint.js (как пользоваться расписано тут).  Как мне показалось, jquery.hint.js вполне удачное, маленькое и элегантное решение для такой задачи.

В любом случае, плагины уже нашёл после того, как написал собственное решение для этой задачи, да и подгружать отдельный js файл на каждую html страницу - непозволительная роскошь, из-за одного маленького input в блоке поиска. Вот этот кусочек js-кода, который с использованием jQuery навешивает подсказку для input text поля с id-шником search:

$('#search').focus(function(){
    if($(this).val() == $(this).attr('title')){
      $(this).val('').css('color','#333');
    }
  }).blur(function(){
    if($(this).val() != $(this).attr('title') && $.trim($(this).val()).length == 0){
      $(this).val($(this).attr('title')).css('color','#AAA');
    }
}).blur();

Сам элемент input выглядет следующим образом:

<input id="search" type="text" name="search" value="" title=" Поиск по сайту…" />

Скрипт использует значение, которое задано в атрибуте title в качестве текста подсказки и выводит его серым цветов в самом input. Как только пользователь ставит/убирает курсор в поле для ввода, срабатывает событие focus/blur, которое и показывает/скрывает текст подсказки и меняет CSS стиль для элемента.

Для того чтобы submit формы не происходил с нашим фейк-значением подсказки, я навесил дополнительное событие onsubmit="checkFakeSearchValues();" на элемент form. Эта функция выглядит следующим образом:

function checkFakeSearchValues(){
  var search = $('#search');
  if($(search).val() == $(search).attr('title')){
    $(search).val('');
  }
}

и проверяет значение поля для ввода перед submit формы.  Если пользователь ничего не вводил в поле, значение осталось равно значению текста подсказки, то оно будет почищено и оставлено пустым.

четверг, 21 октября 2010 г.

Коды кнопок добавления в социальные закладки (Share Button Codes)

Так как часто приходится встраивать кнопки закладок для всякого рода социальных ресурсов решил создать памятку, чтобы все были в одном месте.

Код формирования ссылки для сервиса Facebook:
http://www.facebook.com/sharer.php?u={ссылка на страницу}
Код формирования ссылки для сервиса Twitter:
http://twitter.com/home/?status={заголовок страницы}+{ссылка на страницу} 
Код формирования ссылки для сервиса Google Buzz:
http://www.google.com/buzz/post?url={ссылка на страницу}&title={заголовок страницы}
Код формирования ссылки для сервиса Я.ру:
http://my.ya.ru/posts_add_link.xml?URL={ссылка на страницу}&title={заголовок страницы}
Код формирования ссылки для сервиса Вконтакте:
http://vkontakte.ru/share.php?url={ссылка на страницу}
Код формирования ссылки для сервиса LiveInternet:
http://www.liveinternet.ru/journal_post.php?action=n_add&cnurl={ссылка на страницу}
Код формирования ссылки для сервиса Livejournal:
http://www.livejournal.com/update.bml?event={ссылка на страницу}&subject={заголовок страницы}
Код формирования ссылки для сервиса Memori:
http://memori.ru/link/
Код формирования ссылки для сервиса Мой Мир (mail.ru):
http://connect.mail.ru/share?share_url={ссылка на страницу}
Возможно ещё что-то упустил - смело пишите в комментариях - добавлю.

четверг, 11 марта 2010 г.

Вёрстка, "overflow:hidden" для ячейки таблицы

Появилась задача сверстать таблицу так, чтобы столбцы и ячейки table не разъезжались, не тянулись, при изменении количества содержимого внутри ячейки. Оказалось, не всё так просто. Повесив свойство overflow:hidden для ячейки таблицы - не будет работать. Как растягивал таблицу контент внутри ячеек, так и будет тянуть.

Нашёл, что к тегу <table> или к элементу, у которого свойство display установлено как table или inline-table можно применять свойство:

table-layout: auto | fixed

Применив для таблицы table-layout:fixed задача решилась сама собой, таблицу не растягивает, но и скролл не появляется.

Дело в том, что значение fixed ещё при этом и повышает производительность построения таблиц. Ширина колонок в этом случае определяется либо с помощью тега <col>, либо вычисляется на основе первой строки. Если данные о форматировании первой строки таблицы по каким-либо причинам получить невозможно, в этом случае таблица будет делиться на колонки равной ширины. При использовании этого параметра содержимое, которое не помещается в ячейку указанной ширины, будет «обрезано» либо наложено поверх ячейки.

Работает под браузерами: IE6+, IE7+, Firefox 2+, Firefox 3+, Opera 9.52+, Safari 3.1+, Chrome 0.3+.

четверг, 24 сентября 2009 г.

Как браузер определяет next page на странице для быстрой постраничной навигации?

Как браузер определяет ссылку «next page» на странице? – Задался я сегодня таким вопросом, в процессе навигации по поисковику при помощи комбинаций клавиш, без использования мыши. Общеизвестный факт, что для постраничной навигации в браузере можно использовать комбинации клавиш вида ctrl+курсорные клавиши. По крайней мере, это работает без проблем на многих популярных сайтах в браузерах Opera и Firefox.

Но как же браузер определяет, какая ссылка является следующей логической страницей в цепочке html-документов? Начал рассматривать варианты реализации. Самое первое, что пришло на ум, это использование отношений ссылок в документе при помощи атрибута rel у элементов <a>. Догадка оказалась неверна, её в основном используют поисковики для индексации, но никак не браузеры. Ещё вариант в <head> html-страницы указать

<LINK rel="prev" href="page2.html">
<LINK rel="next" href="page4.html">

но назначние такое же, суть вопроса не меняется.

Второй вариант, как это можно реализовать, это повесить события JavaScript на нажатия клавиш, для быстрого перехода по пейджерам. Собственно, поисследовав код на поисковике Яндекс, я нашёл следующее. Они вешают вызов функции на событие document.onkeydown. Сама функция выглядит следующим образом:

function keyboard_navigation(D) {
  D = D || window.event;
  var A = D.keyCode;
  if (D.ctrlKey) {
    var B = $id("b-head-search");
    if (A == 13) {
      B.submit();
    }
    var E = (D.target || D.srcElement).tagName;
    if (E != "INPUT" && E != "TEXTAREA") {
      var C;
      if (A == 37) {
        C = $id("previous_page");
      }
      if (A == 39) {
        C = $id("next_page");
      }
      if (C) {
        location.href = C.href;
      }
      if (A == 38 && B.text) {
        B.text.focus();
        B.text.select();
      }
    }
  }
}

После этого, полез смотреть на Google, как реализована у них постраничная навигация при помощи комбинации клавиш ctrl+cursor left или ctrl+cursor right. Но, оказалось, что никаких обработчиков событий с клавиатуры у них не висит, и в Firefox подобный финт не работает. Такая комбинация клавиш отрабатывала только в Opera.

Получается, что браузер Opera имеет собственный детектор пейджингов на странице. Поиски в просторах Интернета не сразу дали ответ на мой вопрос. Моё упорство и сильный интерес всё-таки победили после получасовых поисков. Оказывается, браузер Opera использует собственную технологию для определения ссылок перехода на следующую страницу, для многостраничных документов или блогов. Имя этой технологии FastForward.

Opera FastForward – технология, введенная ещё со времён Opera 7. Она автоматически «угадывает» следующую страницу, и обеспечивает быструю навигацию по цепочке страниц. Это очень удобно, например, при чтении блогов, можно осуществлять постраничное чтение, всего лишь нажимая пробел для пролистывания. Как это работает? Opera загружает содержимое страницы и в нём ищет определённые ссылки, которые часто используются для навигации по многостраничным документам, содержащие текст вида "next" или ">>". Я сразу же полез в папку, где лежит исполняемый файл Оперы, и начал искать в конфигах. Нашёл файл fastforward.ini, в нём и находились настройки для этого заветного FFwd. Оказывается, в нём прописаны самые распространенные сигнатуры для большинства языков, по которым в тексте ссылок ищется адрес перехода на следующую страницу. Опытным путём, я выяснил, если на странице находится несколько подобных ссылок, то во внимание будет взято лишь последнее вхождение на странице. Так что, такую вот хитрую технологию использовали разработчики браузера Opera.

Именно за такие мелкие навороты, удобство и скорость работы я и люблю браузер Opera, постоянно использую для серфинга по internet.

вторник, 18 августа 2009 г.

Эмулирование border-color:transparent в IE6

Все браузеры, как браузеры, нормально работают со свойством border-color:transparent, один Internet Explorer 6 его не понимает. Приведу кусочек кода для примера:

.mydiv
{
width: 400px;
height: 200px;
border: solid 2px transparent;
}

Браузеры Internet Explorer 7, Firefox, Opera and Safari на границах элемента отобразят пустое прозрачное место шириной в 2px. Вместо прозрачного бордера в IE 6 появится чёрная сплошная полоса.

Исправить это можно, сделав небольшой хак, который поймёт только IE6:

*html .mydiv
{
border-color: pink;
filter: chroma(color=pink);
}

И вуаля! Убогий бордер исчез и стал прозрачным.

суббота, 9 мая 2009 г.

Копирование стиля элемента в JavaScript

Может такое случиться, что понадобится скопировать часть атрибутов одного элемента в другой. «Что тут такого сложного?!», – подумаете вы, но решение такой задачи не тривиальное, как может показаться с первого взгляда.

Internet Explorer 7 и некоторые другие не могут установить значение стиля, класса или хендлера событий используя метод setAttribute. В IE8 вроде бы исправили это, но всё равно нельзя устанавливать обработчики событий. Некоторые браузеры имеют проблемы и со считыванием через getAttribute. В частности, Internet Explorer возвращает результат неправильного типа, например, вместо объекта строку, при использовании getAttribute для получения этих атрибутов. DOM обеспечивает несколько альтернативных решений для выполнения этих задач в такиз браузерах.

Класс доступен для чтения/записи через строку className.

Аттрибут обработчика события доступен через ссылку на функцию,с именем, совпадающем с именем атрибута, к примеру, element.onclick. Он доступен для чтения и записи, но запись должна происходить как ссылка на функцию, а не как прямая строка. Аттрибут можно записать используя конструктор функции:

element.onclick = new Function(codeAsAString);

Аттрибут обработчика события может быть прочитан при помощи метода toString функции, но следует помнить, что он может быть недоступен в некоторых браузерах (зачастую в браузерах мобильных телефонов или других специфических устройств). Опять же, заметьте, может быть и недоступен вовсе, если атрибут просто не задан.

var functioncode = element.onclick.toString();

Значение атрибута style доступно для чтения и записи через строку cssText, которая является свойством стиля объекта, которая в свою очередь является свойством элемента. Это свойство может плохо поддерживаться старыми браузерами, к примеру, Safari не поддерживал его вплоть до версии 1.1. Поэтому для избежания проблем стоит использовать комбинацию cssText и getAttribute/setAttribute. Для чтения:

var cssString;
cssString = element.style.cssText;
if( typeof(cssString) != 'string' ) {
 cssString = element.getAttribute('style');
}

Для записи атрибута style лучше использовать оба метода, а браузер уже сам выставит тем методом, который в нём отработает правильно:

var cssString = 'color:lime;font-weight:bold;';
element.style.cssText = cssString;
element.setAttribute('style',cssString);

Вот вроде бы и всё, что хотел рассказать по поводу копирования атрибутов средствами JavaScript и то, что смог найти в интернете, думаю, кому-то ещё пригодится, на работе уже сталкивались с такой проблемой.

суббота, 28 марта 2009 г.

Коды основных символов HTML

Часто используемые
&nbsp;   неразрывный пробел
&ensp;   короткий пробел
&emsp;   длинный пробел
&shy; ­ мягкий перенос
&mdash; — длинное тире
&ndash; – короткое тире
&hellip; … многоточие
&laquo; « левая кавычка елочка
&raquo; » правая кавычка елочка
&copy; © (c)
&reg; ® (R)
&trade; ™ TM
Математические
&plusmn; ± +-
&times; × умножить
&ne; ≠ не равно
&lt; < <
&gt; > >
&le; ≤ <=
&ge; ≥ >=
&radic; √ квадратный корень
&sup2; ² квадрат, вторая степень
&sup3; ³ куб, третья степень
&frac14; ¼ 1/4
&frac12; ½ 1/2
&frac34; ¾ 3/4
&infin; ∞ бесконечность
Стрелки
&larr; ← стрелка влево
&uarr; ↑ стрелка вверх
&rarr; → стрелка вправо
&darr; ↓ стрелка вниз
&harr; ↔ стрелка влево и вправо
&crarr; ↵ стрелка вниз, потом влево, как Enter
&lArr; ⇐ стрелка двойная влево
&uArr; ⇑ стрелка двойная вверх
&rArr; ⇒ стрелка двойная вправо
Прочие
&amp; & амперсанд
&euro; ? евро
&prime; ′ '
&Prime; ″ ''
&middot; · точка на середине высоты строки
&oline; ‾ Надчерк
&deg; ° градус

jQuery Tabs. Ajax загрузка в один и тот же div контейнер

Эта статья будет полезна тем, кто использует такую мощную штуку как jQuery UI, в частности элемент интерфейса Tabs. jQuery Tabs позволяет в несколько строчек кода создавать удобный и быстрый набор вкладок на HTML странице.

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

Приведу пример использования:

<div id="contacttabs">
  <ul>
    <li><a href="all.html"><span>Все контакты</span></a></li>
    <li><a href="friends.html"><span>Друзья</span></a></li>
    <li><a href="invisible.html"><span>Список невидящих</span></a></li>
    <li><a href="ignore.html"><span>Список игнорируемых</span></a></li>
  </ul>
</div>

<script type="text/javascript">
  $(document).ready(function() {
    $("#contacttabs").tabs({
      spinner: 'загрузка...'
});
  }
</script>

После загрузки страницы создастся четыре вкладки, содержимое, в каждую из них, будет загружено динамически ajax-ом. Все недостающие контейнеры, в которые загружать содержимое вкладок, jQuery создаст сам. Эта часть будет выглядеть приблизительно вот так (содержимое div-ов опущено для упрощения восприятия):

<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">
...
</ul>
<div id="ui-tabs-16" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"></div>
<div id="ui-tabs-27" class="ui-tabs-panel ui-widget-content ui-corner-bottom"></div>
<div id="ui-tabs-29" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"></div>
<div id="ui-tabs-31" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"></div>

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

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

Единственным выходом для меня было – подчищать содержимое контейнеров неактивных вкладок, дабы не возникало дублирование ID-шников. Такой опции в jQuery Tabs, я найти не смог, пришлось написать небольшой hook. Я навесил на событие select, возникающее в Tabs, в момент переключения активной вкладки, очистку всех неактивных контейнеров <div>.

<script type="text/javascript">
  $(document).ready(function() {
    $("#contacttabs").tabs({
      spinner: 'загрузка...',
      select: function(event, ui) {
        /*clear all divs content except active one*/
        fakes = ui.panel.parentNode.getElementsByTagName('div');
        for(i=0;i<fakes.length;i++){
          if(fakes[i] != ui.panel){
            fakes[i].innerHTML = '';
          }
        }
      }
    });
  });
</script>

И тогда всё заработало, как следует..

среда, 3 декабря 2008 г.

Flash Player 10 – теперь Clipboard требует взаимодействия с пользователем

В web-приложениях часто приходится иметь дело с копированием какого-то string-значения в системный буфер обмена. Это становится реальной проблемой, когда нужна кроссбраузерность. Из JavaScript-а работать с буфером обмена можно, но это позволяет лишь Internet Explorer и Firefox, но с некоторыми ограничениями.

Нашёл для себя выход – использовать Flash-объект (вроде, copyToClipboard.swf назывался), встроенный на страницу. На элемент HTML-страницы вешается событие, JavaScript-ом передаётся нужный параметр во Flash-объект, а уже тот в свою очередь имеет доступ к буферу обмена пользователя. Таким образом, можно было положить любую строку из браузера пользователя в буфер обмена операционной системы.

Недавно мой Flash Player 9 нашёл в сети новую версию и предложил обновиться на 10-ю версию, на что я дал утвердительный ответ. Скачал, обновился, проверил flash объекты, все работают, всё функционирует так же, ... но потом обнаружилось, что в буфер обмена не попадает заветная строка.

На сайте adobe нашёл информацию о новом релизе, и начал разбираться, в чём дело. Оказалось, что изменений было много, и самые важные коснулись безопасности нового Flash Player-а, в числе которых и были ограничения на работу с clipboard. В девятой версии плеера ActionScript мог устанавливать значение в системный буфер обмена в любое время. В Flash Player 10 метод System.setClipboard() может быть успешно вызван только через ActionScript вызванный именно взаимодействием пользователя. Это могут быть, как события вызванные мышью, так и события исходящие от клавиатуры. Это нововведение с взаимодействием пользователя так же касается и нового ActionScript 3.0 метода Clipboard.generalClipboard.setData() и метода Clipboard.generalClipboard.setDataHandler().

Таким образом, эти изменения в основном затрагивают все SWF-файлы, которые используют System.setClipboard() метод. Нововведения касаются всех SWF-фалов проигрываемых в версиях Flash Player 10 и старше.

Подведу итог. Если вы хотите, чтобы ваши web-приложения работали адекватно с буфером обмена и в новых версиях Flash Player, то не забудьте обновить логику работы с System.setClipboard(). Этот метод теперь нужно вызывать непосредственно действием пользователя, к примеру, через кнопку, клавишную комбинацию быстрого вызова, или мышь.

четверг, 27 ноября 2008 г.

5 аргументов не использовать inline CSS и JavaScript код

Если вы попали на мой блог, значит, вас интересует веб-программирование. Основой веб-программирования, понятное дело, является HTML, но никакой современный сайт уже не обходится без CSS и JS. В интернете можно встретить много разговоров о стандартах в web-программировании, в каком стиле лучше писать код. Ну а толку с них, - скажете вы, - если есть W3C, который занимается стандартизацией и там всё можно почитать. Конечно, можно, но там тонны информации, которую сложно переварить и надо затратить много времени на её изучение.

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

Итак, что же такое inline JavaScript и CSS, - это когда внутри html страницы идут вперемешку скрипты и описания стилей через строчку с html разметкой. Под JavaScript-ом вперемешку я понимаю не вызовы функций по событиям on_click, а непосредственно объявление этих самых вызываемых функций или объявление переменных между тегами <> < /script>, разбросанное по всей странице. Какая разница? – спросит большинство. А разница всё-таки есть, и я приведу вам 5 аргументов не использовать inline CSS и JavaScript код.


Аргумент 1: Кэширование и большинство оптимизаций не работают.
Большинство браузеров для убыстрения работы и уменьшения перегоняемого трафика используют в своей работе кэширование страниц. HTML страницы никогда не кэшируются. Что же касается графических изображений, внешних каскадных таблиц стилей (CSS) и файлов JS скриптов – то браузер пользователя наоборот, старается сохранить файлы в кэше при первом визите и при последующих запросах этих файлов не загружать их заново. Таким образом, объёмы загружаемой информации резко уменьшаются, перегружается только HTML-код страницы, а всё остальное подгружается из локального кэша браузера.

Аргумент 2: Непонятность кода и сложность нейтрализации ошибок
Допустим, у вас по большой HTML странице разбросаны JavaScript вставки. При наступлении какого-то события с неявно указанным обработчиком вам будет сложно выудить необходимый участок кода и нейтрализовать программные ошибки. А если страница компонуется из нескольких вставок, то обработчик и вовсе не будет отрабатывать, по той простой причине, что этот участок кода был случайно не включён.

Аргумент 3: HTML код становится тяжелее.
На выходе ваш HTML код получится значительно тяжелее и больше по объёму. HTML страница пронизанная JS и CSS вставками будет весить в килобайтах гораздо больше, чем аналогичная страница «чистая» по своей структуре.

Аргумент 4: Сложность модификации.
Лучше код взаимодействия вынести в одно централизованное место, чем просматривать весь текст в поисках однотипных участков кода для изменения, разбросанных по всем страницам сайта. Не каждый программист выдержит поддержку такого кода, разбросанного по всему сайту.

Аргумент 5: Невозможность повторного использования кода.
Если вы реализовали отличный по функционалу элемент интерфейса, то вы наверняка захотите его повторно использовать в остальных своих проектах. Но он намертво «вшит» по всем страницам сайта, и вам придется потратить уйму времени на его выуживание и прикручивание к другому сайту. При реализации, разнесенной по отдельным внешним файлам, всё, на что бы вам пришлось потратить время – это сделать подгрузку этих файлов, и вставить в необходимые места вызовы методов.

Надеюсь, мои 5 аргументов не использовать inline CSS и JavaScript код вас хоть немного убедили, и вы возьмёте их на заметку. Успешного кода, программист, и держи реализацию CSS и JavaScript в отдельных внешних файлах.

Рекоммендую

Попробуйте надёжный хостинг от Scala Hosting