<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>fxposter&#039;s wave &#187; JavaScript</title>
	<atom:link href="http://blog.fxposter.org/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.fxposter.org</link>
	<description>Stories about Ruby, JavaScript, Objective-C and other cool tools</description>
	<lastBuildDate>Sun, 30 Oct 2011 20:00:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>10K Apart</title>
		<link>http://blog.fxposter.org/2010/08/23/10k-apart/</link>
		<comments>http://blog.fxposter.org/2010/08/23/10k-apart/#comments</comments>
		<pubDate>Sun, 22 Aug 2010 21:31:21 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=842</guid>
		<description><![CDATA[Потихоньку подходит к концу конкурс 10K Apart. Заходишь, смотришь и думаешь - &#8220;дааа, чего только люди не впихнут в 10 килобайт JavaScript-а&#8221;. :) Из наиболее понравившегося: Fontanero - увлекательная игрушка на тему &#8220;жизнь водопроводчика&#8221;. На Хабре про неё уже писали создатели. Poker Heads Up - долго играл, доиграл до конца, выиграл, понравилось. Из названия понятно, [...]]]></description>
			<content:encoded><![CDATA[<p>Потихоньку подходит к концу конкурс <a href="http://10k.aneventapart.com/">10K Apart</a>. Заходишь, смотришь и думаешь - &#8220;дааа, чего только люди не впихнут в 10 килобайт JavaScript-а&#8221;. :)</p>
<p>Из наиболее понравившегося:</p>
<ul>
<li><a href="http://10k.aneventapart.com/Entry/177">Fontanero</a> - увлекательная игрушка на тему &#8220;жизнь водопроводчика&#8221;. На Хабре про неё уже <a href="http://habrahabr.ru/blogs/webdev/102153/">писали</a> создатели.</li>
<li><a href="http://10k.aneventapart.com/Entry/50">Poker Heads Up</a> - долго играл, доиграл до конца, выиграл, понравилось. Из названия понятно, о чем игрушка. :)</li>
<li><a href="http://10k.aneventapart.com/Entry/198">Racer 10k</a> - вызвавшие ностальгию по моему первому компьютеру (а это был в далеком 1995-м году первый пентиум 133МГц) гоночки. Не очень затягивает, но не написать не мог. PS. Игра работает в Chrome намного быстрее, чем в FF, что положительным образом <a href="http://twitter.com/fxposter/status/21855636182">сказывается</a> <a href="http://twitter.com/fxposter/status/21856094251">на результатах</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2010/08/23/10k-apart/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Особенности работы jQuery.live()</title>
		<link>http://blog.fxposter.org/2010/06/16/jquery-live-method/</link>
		<comments>http://blog.fxposter.org/2010/06/16/jquery-live-method/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 23:21:26 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Работа]]></category>
		<category><![CDATA[event bubbling]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[live]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=787</guid>
		<description><![CDATA[На работе столкнулись с &#8220;особенностью&#8221; работы jQuery.live(), на которую хотелось бы обратить внимание, потому как, судя по всему, отнюдь не все о ней знают (и в результате чего пишут неработающий код). Итак, простой пример - навешивание двух событий на один и тот же элемент: &#60;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&#62; &#60;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>На <a href="http://waysgo.com/">работе</a> столкнулись с &#8220;особенностью&#8221; работы <a href="http://api.jquery.com/live/">jQuery.live()</a>, на которую хотелось бы обратить внимание, потому как, судя по всему, отнюдь не все о ней знают (и в результате чего пишут неработающий код).</p>
<p>Итак, простой пример - навешивание двух событий на один и тот же элемент:</p>
<pre><code class="html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-type" content="text/html; charset=UTF-8" /&gt;
  &lt;title&gt;jQuery.live() test page&lt;/title&gt;
  &lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
  jQuery(function() {
    $("a").bind("click", function(e) {
      alert("a");
      return false;
    });
    $("a").bind("click", function(e) {
      alert("b");
      return false;
    });
  });
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;a href="http://blog.fxposter.org/"&gt;Блог FX-а&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>Пример можно посмотреть <a href="http://blog.fxposter.org/wp-content/uploads/2010/06/test.html">здесь</a>. В результате клика на ссылку - получаем 2 alert-а, всё хорошо, ожидаемо и предсказуемо.</p>
<p>Переписываем код для работы с jQuery.live(). Для тех, кто в танке - live() вешает событие не на сам элемент, а на document. В результате <a href="http://www.quirksmode.org/js/events_order.html">bubbling-а</a> событие, которое произошло над каким-либо элементом поднимается вверх по <a href="http://ru.wikipedia.org/wiki/Document_Object_Model">DOM-дереву</a> и соответственно вызывает обработчики всех элементов, которые оно встретит. Если вы и этого не знали - то вам не нужно читать мой блог, а пора идти и покупать книгу по JavaScript-у (мне, кстати, тоже давно пора, но всё никак не соберусь). Итак, в конце концов событие доходит до document-а и обработчики вызываются у него. Обработчик, который устанавливает jQuery.live() проверяет - соответствует ли event.target (а именно здесь хранится обьект DOM-дерева, с которым произошло событие) соответствующему селектору (в данном случае - это селектор &#8220;a&#8221;) и если соответствует - то выполняет обработчик.</p>
<p>Преимущества и недостатки - это тема отдельной статьи. Если не уклонятся в сторону оптимизации, то основным преимуществом, на мой взгляд, является тот факт, что обработчики, навешенные live()-ом будут запускаться даже для элементов, которые были динамически добавлены на страницу, в отличии от <a href="http://api.jquery.com/bind/">bind()</a>-обработчиков, которые на эти элементы нужно будет навешивать вручную (если непонятно, почему это работает именно так - читаем предыдущий абзац, если все равно непонятно - идем покупать всё ту же книгу).</p>
<p>Далее - зачем нужен &#8220;return false&#8221; в конце обработчика? Он предотвращает от того, чтобы вызывалось действие по умолчанию (в данном случае - переход по ссылке и событие не поднималось выше). Чаще всего JS-разработчики вообще не думают о bubbling-е и под &#8220;return false&#8221; понимают только &#8220;отмену действия по умолчанию&#8221;, ну или они вообще не знают, что именно происходит и пишут &#8220;return false&#8221;, потому что так работает.</p>
<p>Такое отношение jQuery частенько прощает. Но не в случае с live()-методом. Попробуем запустить следующий <a href="http://blog.fxposter.org/wp-content/uploads/2010/06/test2.html">пример</a>:</p>
<pre><code class="html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-type" content="text/html; charset=UTF-8" /&gt;
  &lt;title&gt;jQuery.live() test page&lt;/title&gt;
  &lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
  jQuery(function() {
    $("a").live("click", function(e) {
      alert("a");
      return false;
    });
    $("a").live("click", function(e) {
      alert("b");
      return false;
    });
  });
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;a href="http://blog.fxposter.org/"&gt;Блог FX-а&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>В результате клика теперь выскакивает только один alert. Пора обратится к <a href="http://api.jquery.com/live/">документации</a>:</p>
<blockquote><p># To stop further handlers from executing after one bound using .live(), the handler must return false. Calling .stopPropagation()  will not accomplish this.</p></blockquote>
<p>Хаха. В данном случае jQuery интерпретирует false &#8220;несколько иначе&#8221;. :)</p>
<p>Для того, чтобы &#8220;пофиксить&#8221; подобный баг нужно обратится все к тому же bubbling-у и обработке событий и сделать именно то, что предполагается разработчиком - &#8220;отменить действие по умолчанию&#8221;. Это делается с помощью метода <a href="https://developer.mozilla.org/en/DOM/event.preventDefault">event.preventDefault()</a> (<a href="http://blog.fxposter.org/wp-content/uploads/2010/06/test3.html">пример</a>):</p>
<pre><code class="html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-type" content="text/html; charset=UTF-8" /&gt;
  &lt;title&gt;jQuery.live() test page&lt;/title&gt;
  &lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
  jQuery(function() {
    $("a").live("click", function(e) {
      alert("a");
      e.preventDefault();
    });
    $("a").live("click", function(e) {
      alert("b");
      e.preventDefault();
    });
  });
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;a href="http://blog.fxposter.org/"&gt;Блог FX-а&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>И самое главное (барабанная дробь!) - при использовании bind() для навешивания обработчиков preventDefault() тоже можно использовать!</p>
<p>Наткнулись мы на эту &#8220;фичу&#8221;, когда у нас почему-то перестали вызываться <strong>некоторые</strong> обработчики</p>
<p>Напоследок, замечу еще одно - элемент, на который навешено хотя бы один обработчик события через bind() с &#8220;правильно работающим return false&#8221;, никогда не будет вызывать никакие live()-события. ;)</p>
<p>Так что будьте бдительны и не забывайте об особенностях обработки событий в JS. Удачи.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2010/06/16/jquery-live-method/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Аналог PHP-шной asort() на JavaScript</title>
		<link>http://blog.fxposter.org/2008/11/28/asort-in-javascript/</link>
		<comments>http://blog.fxposter.org/2008/11/28/asort-in-javascript/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 22:21:23 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=589</guid>
		<description><![CDATA[На днях попросили меня помочь написать функцию сортировки массива на JavaScript, чтобы сохранилась связь между ключами и их значениями, т.е. аналог asort() в PHP. Поверхностный поиск в Google ничего подобного найти не смог, поэтому родилась вот такая функция (принимает массив или хеш, на выходе - хеш): function asort(arr, sort_function) { if (sort_function == undefined) sort_function [...]]]></description>
			<content:encoded><![CDATA[<p>На днях попросили меня помочь написать функцию сортировки массива на JavaScript, чтобы сохранилась связь между ключами и их значениями, т.е. аналог asort() в PHP. Поверхностный поиск в Google ничего подобного найти не смог, поэтому родилась вот такая функция (принимает массив или хеш, на выходе - хеш):</p>
<pre><code class="javascript">function asort(arr, sort_function) {
  if (sort_function == undefined)
    sort_function = function(a, b) { return a - b }

  var b = [];
  for (var i in arr)
    b.push([i, arr[i]]);
  b.sort(function(a, b) { return sort_function(a[1], b[1]) });

  c = {};
  for (var i in b)
    c[b[i][0]] = b[i][1];
  return c;
}</code></pre>
<p>Примеры использования:</p>
<pre><code class="javascript">// сортировка по возрастанию
var h = asort([1, 10, 2, 5, 4]);
for(i in h)
  alert(h[i]);

// сортировка по убыванию
var j = asort([1, 10, 2, 5, 4], function(a, b) { return b - a });
for(i in j)
  alert(j[i]);</code></pre>
<p><em><strong>PS</strong>. В JS я не спец, так что, возможно, всё сделано абсолютно неправильно :)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2008/11/28/asort-in-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Шахматы на JavaScript</title>
		<link>http://blog.fxposter.org/2008/06/12/javascript-chess/</link>
		<comments>http://blog.fxposter.org/2008/06/12/javascript-chess/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 18:40:44 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Разное]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=443</guid>
		<description><![CDATA[Блог Nihilogic в очередной раз удивил. На этот раз - шахматами на JavaScript в полном 3D с поддержкой управления как клавиатурой, так и мышкой. Читаем. Играем.]]></description>
			<content:encoded><![CDATA[<p>Блог Nihilogic в очередной раз удивил. На этот раз - шахматами на JavaScript в полном 3D с поддержкой управления как клавиатурой, так и мышкой.</p>
<p><a href="http://blog.nihilogic.dk/2008/06/3d-javascript-chess-mouse-support.html">Читаем</a>. <a href="http://www.nihilogic.dk/labs/chess/">Играем</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2008/06/12/javascript-chess/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>jQuery 1.2.6 Release Notes</title>
		<link>http://blog.fxposter.org/2008/06/03/jquery-126-release-notes/</link>
		<comments>http://blog.fxposter.org/2008/06/03/jquery-126-release-notes/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 17:44:31 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=435</guid>
		<description><![CDATA[После релиза jQuery 1.2.6 долгое время раздел Release Notes пустовал. Сегодня вот заметил, что его наконец заполнили. Из улучшений: Глобальное ускорение работа с событиями ускорена более чем в два раза селекторы ускорены на 13% .offset() ускорен на 21% работа с CSS (.css()) ускорена на четверть Кое-что улучшено, кое-что добавлено, вроде в API ничего не изменено]]></description>
			<content:encoded><![CDATA[<p>После релиза jQuery 1.2.6 долгое время раздел <a href="http://docs.jquery.com/Release:jQuery_1.2.6">Release Notes</a> пустовал. Сегодня вот заметил, что его наконец заполнили.</p>
<p>Из улучшений:</p>
<ul>
<li>Глобальное ускорение
<ul>
<li>работа с событиями ускорена более чем в два раза</li>
<li>селекторы ускорены на 13%</li>
<li>.offset() ускорен на 21%</li>
<li>работа с CSS (.css()) ускорена на четверть</li>
</ul>
</li>
<li>Кое-что улучшено, кое-что добавлено, вроде в API ничего не изменено</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2008/06/03/jquery-126-release-notes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Вышел jQuery UI 1.5 RC1</title>
		<link>http://blog.fxposter.org/2008/06/03/jquery-ui-15-rc1/</link>
		<comments>http://blog.fxposter.org/2008/06/03/jquery-ui-15-rc1/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 21:24:42 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery UI]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=434</guid>
		<description><![CDATA[Как сообщает нам наш официальный источник - вышел первый релиз-кандидат jQuery UI - набора виджетов и визуальных эффектов для известного в узких кругах JS-фреймворка jQuery. Как утверждает источник, RC1 довольно стабилен, а точнее - это самая стабильная версия из тех, которые вообще выпускались. :) Так что - спешите обновляться. Ах да, чуть не забыл - [...]]]></description>
			<content:encoded><![CDATA[<p>Как сообщает нам наш официальный источник - <a href="http://jquery.com/blog/2008/06/02/jquery-ui-15-release-candidate-were-getting-excited/">вышел первый релиз-кандидат jQuery UI</a> - набора виджетов и визуальных эффектов для известного в узких кругах JS-фреймворка jQuery.</p>
<p>Как утверждает источник, RC1 довольно стабилен, а точнее - это самая стабильная версия из тех, которые вообще выпускались. :) Так что - <a href="http://ui.jquery.com/download">спешите обновляться</a>.</p>
<p>Ах да, чуть не забыл - в некоторых местах поменялось API (в draggable и resizable модулях так точно поменялось), так что будьте всё же осторожны и предусмотрительны.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2008/06/03/jquery-ui-15-rc1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Используем Google AJAX Libraries API</title>
		<link>http://blog.fxposter.org/2008/05/29/using-google-ajax-libraries-api/</link>
		<comments>http://blog.fxposter.org/2008/05/29/using-google-ajax-libraries-api/#comments</comments>
		<pubDate>Thu, 29 May 2008 00:41:15 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=433</guid>
		<description><![CDATA[Авось, кто-то еще не догадался&#8230; :) Самый простой способ использования своих скриптов совместно с Google AJAX Libraries API: google.load("jquery", "1"); google.setOnLoadCallback(function() { $('&#60;script type="text/javascript" src="_url_вашего_скрипта_"&#62;&#60;/script&#62;').appendTo('head'); $('&#60;script type="text/javascript" src="_url_вашего_другого_скрипта_"&#62;&#60;/script&#62;').appendTo('head'); // ... }); Аналогичным образом подключаются, например, плагины для jQuery.]]></description>
			<content:encoded><![CDATA[<p>Авось, кто-то еще не догадался&#8230; :)</p>
<p>Самый простой способ использования своих скриптов совместно с Google AJAX Libraries API:</p>
<pre><code class="javascript">google.load("jquery", "1");

google.setOnLoadCallback(function() {
  $('&lt;script type="text/javascript" src="_url_вашего_скрипта_"&gt;&lt;/script&gt;').appendTo('head');
  $('&lt;script type="text/javascript" src="_url_вашего_другого_скрипта_"&gt;&lt;/script&gt;').appendTo('head');
  // ...
});</code></pre>
<p>Аналогичным образом подключаются, например, плагины для jQuery.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2008/05/29/using-google-ajax-libraries-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Мысли о Unobtrusive Javascript</title>
		<link>http://blog.fxposter.org/2008/05/24/unobtrusive-javascript-minds/</link>
		<comments>http://blog.fxposter.org/2008/05/24/unobtrusive-javascript-minds/#comments</comments>
		<pubDate>Sat, 24 May 2008 09:50:19 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Разное]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Unobtrusive JavaScript]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=429</guid>
		<description><![CDATA[Кросспост моего поста про unobtrusive javascript на хабрахабр вызвал целую кучу критики: Пока дождешься DOMContentLoaded и, соответственно, применения связей событий - пройдет куча времени &#8220;Ссылки вида &#60;a href=&#8221;javascript:saw(111)&#8221;&#62; мне нравятся больше&#8221; Производительность инлайн-вставок JS будет выше и т.д. По-моему вывод можно сделать один - многие люди не готовы принять этот подход - может, слишком сложно, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://habrahabr.ru/blog/javascript/42876.html">Кросспост</a> <a href="http://blog.fxposter.org/2008/05/23/unobtrusive-javascript/">моего поста про unobtrusive javascript</a> на хабрахабр вызвал целую кучу критики:</p>
<ul>
<li>Пока дождешься DOMContentLoaded и, соответственно, применения связей событий - пройдет куча времени</li>
<li>&#8220;Ссылки вида &lt;a href=&#8221;javascript:saw(111)&#8221;&gt; мне нравятся больше&#8221;</li>
<li>Производительность инлайн-вставок JS будет выше</li>
<li>и т.д.</li>
</ul>
<p>По-моему вывод можно сделать один - многие люди не готовы принять этот подход - может, слишком сложно, может, еще что-то?.. Не знаю, не знаю..</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2008/05/24/unobtrusive-javascript-minds/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Unobtrusive JavaScript</title>
		<link>http://blog.fxposter.org/2008/05/23/unobtrusive-javascript/</link>
		<comments>http://blog.fxposter.org/2008/05/23/unobtrusive-javascript/#comments</comments>
		<pubDate>Fri, 23 May 2008 03:04:06 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Unobtrusive JavaScript]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=428</guid>
		<description><![CDATA[Цель статьи - показать, что из себя представляет &#8220;ненавязчивый JavaScript&#8221;, для чего он нужен, и чем он лучше &#8220;навязчивого&#8221; JavaScript. В рунете я подобных статей не встречал (может они и есть, но мне на глаза не попадались и немного погуглив, я тоже ничего не нашел), а как показывает практика - очень многие не знают, что [...]]]></description>
			<content:encoded><![CDATA[<p>Цель статьи - показать, что из себя представляет &#8220;ненавязчивый JavaScript&#8221;, для чего он нужен, и чем он лучше &#8220;навязчивого&#8221; JavaScript. В рунете я подобных статей не встречал (может они и есть, но мне на глаза не попадались и немного погуглив, я тоже ничего не нашел), а как показывает практика - очень многие не знают, что это такое и как этим пользоваться.</p>
<h3>Что такое Unobtrusive JavaScript</h3>
<p>Unobtrusive JavaScript - это техника программирования на языке JavaScript, которая состоит из следующих принципов:</p>
<ul>
<li>разделения структуры (HTML) / оформления (CSS) и поведения (JavaScript)</li>
<li>использование JavaScript для повышения удобства использования уже <strong>рабочего</strong> приложения</li>
<li>применения техники Graceful degradation - если браузер не поддерживает те или иные функции, которые мы добавляем в приложение с помощью JavaScript - приложение всё равно остается рабочим</li>
</ul>
<h3>Зачем?</h3>
<p>Это удобно, это практично, это легко реализуемо и это помогает Вам увеличить аудиторию вашего сайта за счет пользователей, пользующихся старыми браузерами, отключающими JavaScript, пользователей, которые пользуются интернетом с мобильных устройств.</p>
<h3>Как?</h3>
<p>Легче всего показать это на примере. За ним далеко идти не нужно - возьмем всеми любимый Хабрахабр:</p>
<pre><code class="html">&lt;div class="text_comments"&gt; 

  &lt;div class="comment_item" style="margin-left: 0px;"&gt;

    &lt;div class="service_text_comments_holder"&gt;
      &lt;a href="http://fxposter.habrahabr.ru/" class="comments_nickname"&gt;fxposter&lt;/a&gt;
      ...
    &lt;/div&gt;

    &lt;div class="comment_text"&gt;...&lt;/div&gt;

    &lt;div class="comments_reply"&gt;
      &lt;div class="reply_word_holder" id="reply_link866650"&gt;(&lt;a href="javascript:saw(866650);"&gt;ответить&lt;/a&gt;)&lt;/div&gt;

        &lt;div style="display: none" id="reply866650"&gt;
        &lt;!-- форма отправки комментария --&gt;
      &lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
<p>Это код комментариев, которые показываются на страничке о посте. Для наглядности ненужные фрагменты были убраны.</p>
<p>Что плохо в этом фрагменте кода?</p>
<ol>
<li>JavaScript идет вперемешку с HTML (<code class="html">&lt;a href="javascript:saw(866650);"&gt;ответить&lt;/a&gt;</code>)</li>
<li>У людей с отключенным JavaScript&#8217;ом ответить на комментарий не получится в принципе</li>
</ol>
<p>Как его можно улучшить?</p>
<ol>
<li>Вынести &#8220;навешивание&#8221; событий в отдельный файл</li>
<li>Сделать так, чтобы при отключенном JavaScript&#8217;е пользователь перебрасывался на отдельную страницу, где бы он мог ответить на выбранный комментарий</li>
</ol>
<p>Сказано - сделано. Преобразуем HTML к следующему виду:</p>
<pre><code class="html">&lt;div class="text_comments"&gt; 

  &lt;div class="comment_item" style="margin-left: 0px;"&gt;

    &lt;div class="service_text_comments_holder"&gt;
      &lt;a href="http://fxposter.habrahabr.ru/" class="comments_nickname"&gt;fxposter&lt;/a&gt;
      ...
    &lt;/div&gt;

    &lt;div class="comment_text"&gt;...&lt;/div&gt;

    &lt;div class="comments_reply"&gt;
      &lt;div class="reply_word_holder" id="reply_link866650"&gt;(&lt;a href="reply.php?comment_id=866650" class="show_reply_form" id="show_reply_form_866650"&gt;ответить&lt;/a&gt;)&lt;/div&gt;

        &lt;div style="display: none" id="reply866650"&gt;
        &lt;!-- форма отправки комментария --&gt;
      &lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
<p>Как видите - я изменил тег &lt;a&gt; (присвоил ему &#8220;нормальный&#8221; href, добавил id и class). Теперь при нажатии на ссылку &#8220;ответить&#8221; пользователя будет перебрасывать на страницу ответа на выбранный вопрос. Этим я выполнил второй пункт в списке улучшений. Теперь давайте взглянем на первый пункт: для того, чтобы у пользователей, у которых включен JavaScript вместо редиректа выполнялось открытие формы под самим комментарием мне нужно выбрать все элементы с классом &#8220;<code>show_reply_form</code>&#8221; и каждому из них назначить на событие onclick функцию, которая бы &#8220;открывала&#8221; соответствующую форму.</p>
<p>Напишем соответствующую функцию:</p>
<pre><code class="javascript">function showForm(event) {
  var id = parseInt(this.id.replace('show_reply_form_', ''));
  saw(id);
  return false;
}</code></pre>
<p>Она берет <code>this.id</code> (т.е. id текущего обьекта), убирает из него &#8220;фразу&#8221; &#8220;<code>show_reply_form_</code>&#8220;, тем самым получая номер элемента, который нам нужно открыть и вызывает функцию saw, которая присутствовала изначально в HTML-коде. Для того, чтобы не произошел редирект после клика на ссылку - функция возвращает <code>false</code>.</p>
<p>Осталось только связать эту функцию с нашими ссылками.</p>
<p>В <a href="http://jquery.com/">jQuery</a> это делается так:</p>
<pre><code class="javascript">$('.show_reply_form').click(showForm);</code></pre>
<p>В <a href="http://prototypejs.org/">PrototypeJS</a> - так:</p>
<pre><code class="javascript">$$('.show_reply_form').each(function(element) {
  element.onclick = showForm;
});</code></pre>
<p>После присвоения нашей функции элементу - <code>this.id</code> станет относится к id этого элемента (да, это &#8220;магия JavaScript&#8221; :) ).</p>
<p>Весь JavaScript-код теперь можно вынести в отдельный файл:</p>
<pre><code class="javascript">function showForm(event) {
  var id = parseInt(this.id.replace('show_reply_form_', ''));
  saw(id);
  return false;
}

window.onload = function(event) {
  $$('.show_reply_form').each(function(element) {
    element.onclick = showForm;
  });
}</code></pre>
<p>Здесь мы вызываем &#8220;связывание&#8221; наших ссылок с функцией показа формы при событии <code>window.onload</code> (при загрузке страницы).</p>
<p>Таким образом я выполнил и первый пункт в списке улучшений.</p>
<h3>Выводы</h3>
<p>На мой взгляд, такое использование JavaScript, а именно - вынос всех функций на JS в отдельный файл и связывание этих функций с элементами страницы с помощью различных событий (здесь мы видели события <code>window.onload</code> и <code>element.onclick</code>) - это на данный момент - единственно правильное использование JavaScript.</p>
<p>Дерзайте, господа. :)</p>
<p><em><strong>PS</strong>. Я прекрасно знаю, что можно использовать событие не <code>window.onload</code>, а <code>DOMContentLoaded</code>. Но я считаю, что для примера понятнее будет всё же использование <code>window.onload</code>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2008/05/23/unobtrusive-javascript/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Конкурс для javascript-гуру!</title>
		<link>http://blog.fxposter.org/2008/05/18/js-competition/</link>
		<comments>http://blog.fxposter.org/2008/05/18/js-competition/#comments</comments>
		<pubDate>Sun, 18 May 2008 12:29:52 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=419</guid>
		<description><![CDATA[Никита организовал конкурс для JS-программистов. Задание довольно простое, у меня ушел примерно час на написание + рефакторинг. Главный приз - логотип для блога, так что если вы более-менее разбираетесь в JS - почему бы не выкроить часик и не поучаствовать?]]></description>
			<content:encoded><![CDATA[<p><a href="http://seleckis.lv/">Никита</a> организовал конкурс для JS-программистов. <a href="http://seleckis.lv/journal/fun/konkurs-dlya-javascript-guru">Задание</a> довольно простое, у меня ушел примерно час на написание + рефакторинг. Главный приз - логотип для блога, так что если вы более-менее разбираетесь в JS - почему бы не выкроить часик и не поучаствовать?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2008/05/18/js-competition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced

Served from: blog.fxposter.org @ 2012-02-10 06:28:32 -->
