<?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>Разработка &#187; javascript</title>
	<atom:link href="http://www.job-blog.bullgare.ru/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.job-blog.bullgare.ru</link>
	<description>о программировании и работе</description>
	<lastBuildDate>Fri, 03 Feb 2012 09:42:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Firefox developer tools</title>
		<link>http://www.job-blog.bullgare.ru/2012/02/firefox-developer-tools/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/02/firefox-developer-tools/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 09:42:30 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[Вёрстка]]></category>
		<category><![CDATA[firefox]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1408</guid>
		<description><![CDATA[Видео: Firefox developer tools Скачать новый Firefox (beta): http://blog.mozilla.com/futurereleases/2011/12/23/firefox-beta-with-new-developer-tools-and-enhanced-sync-is-ready-for-testing/]]></description>
			<content:encoded><![CDATA[<p>Видео: <a href="http://www.youtube.com/watch?v=VcuQ2Bn5bTA">Firefox developer tools</a></p>
<p>Скачать новый Firefox (beta): <a href="http://blog.mozilla.com/futurereleases/2011/12/23/firefox-beta-with-new-developer-tools-and-enhanced-sync-is-ready-for-testing/">http://blog.mozilla.com/futurereleases/2011/12/23/firefox-beta-with-new-developer-tools-and-enhanced-sync-is-ready-for-testing/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/02/firefox-developer-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Дизассемблирование и минификация javascript</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/%d0%b4%d0%b8%d0%b7%d0%b0%d1%81%d1%81%d0%b5%d0%bc%d0%b1%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%bc%d0%b8%d0%bd%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f-javascript/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/%d0%b4%d0%b8%d0%b7%d0%b0%d1%81%d1%81%d0%b5%d0%bc%d0%b1%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%bc%d0%b8%d0%bd%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f-javascript/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 08:47:04 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[клиентская оптимизация]]></category>
		<category><![CDATA[ссылка]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1405</guid>
		<description><![CDATA[http://pimpmyjs.com/ &#8211; Uglify or Beautify your JavaScript, it&#8217;s your choice&#8230; (minify js online) На jquery.min.js выдал ошибку, но в общем работает, и причём быстро.]]></description>
			<content:encoded><![CDATA[<p><a href="http://pimpmyjs.com/">http://pimpmyjs.com/</a> &#8211; Uglify or Beautify your JavaScript, it&#8217;s your choice&#8230; (minify js online)</p>
<p>На jquery.min.js выдал ошибку, но в общем работает, и причём быстро.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/%d0%b4%d0%b8%d0%b7%d0%b0%d1%81%d1%81%d0%b5%d0%bc%d0%b1%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%bc%d0%b8%d0%bd%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Создание web-приложения для работы без подключения к сети</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-web-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d0%b1%d0%b5%d0%b7-%d0%bf/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-web-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d0%b1%d0%b5%d0%b7-%d0%bf/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 09:10:43 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[localStorage]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1399</guid>
		<description><![CDATA[Основная идея &#8211; проверять перед сохранением данных значение navigator.onLine и слушать события online (для сохранения на сервере), offline (для сохранения в localStorage) и load (для загрузки несохранённых данных на сервер при загрузке страницы после подключения к сети). Пример: // save the string function saveStatusLocally(txt) { window.localStorage.setItem("status", txt); } // read the string function readStatus() { [...]]]></description>
			<content:encoded><![CDATA[<p>Основная идея &#8211; проверять перед сохранением данных значение <strong>navigator.onLine</strong> и слушать события <strong>online</strong> (для сохранения на сервере), <strong>offline</strong> (для сохранения в <a href="https://developer.mozilla.org/en/DOM/Storage">localStorage</a>) и <strong>load</strong> (для загрузки несохранённых данных на сервер при загрузке страницы после подключения к сети).<br />
<span id="more-1399"></span><br />
Пример:</p>
<pre class="code">
// save the string
function saveStatusLocally(txt) {
  window.localStorage.setItem("status", txt);
}

// read the string
function readStatus() {
   return window.localStorage.getItem("status");
}
function whatIsYourCurrentStatus() {
  var status = window.prompt("What is your current status?");
  if (!status) return;
  if (navigator.onLine) {
    sendToServer(status);
  } else {
    saveStatusLocally(status);
  }
}

function sendLocalStatus() {
  var status = readStatus();
  if (status) {
    sendToServer(status);
    window.localStorage.removeItem("status");
  }
}

window.addEventListener("load", function() {
   if (navigator.onLine) {
     sendLocalStatus();
   }
}, true);

window.addEventListener("online", function() {
  sendLocalStatus();
}, true);

window.addEventListener("offline", function() {
  alert("You're now offline. If you update your status, it will be sent when you go back online");
}, true);
</pre>
<p>Оригинал &#8211; <a href="http://hacks.mozilla.org/2010/01/offline-web-applications/">http://hacks.mozilla.org/2010/01/offline-web-applications/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-web-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d0%b1%d0%b5%d0%b7-%d0%bf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Сравнение 12 javascript MVC-фреймворков</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-12-javascript-mvc-%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba%d0%be%d0%b2/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-12-javascript-mvc-%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba%d0%be%d0%b2/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 08:05:14 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[проектирование]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1394</guid>
		<description><![CDATA[The Top 10 Javascript MVC Frameworks Reviewed Лучшим признан Ember.js. Надо поковырять) UPD: поковырял. В принципе, более стройная архитектура, чем у того же backbone, у которого часть логики контроллера во вью. Но из коробки нет router и не так просто с pushState, так что не стал использовать серьёзно. Возможно, через полгода-год этот фреймворк будет интереснее.]]></description>
			<content:encoded><![CDATA[<p><a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/">The Top 10 Javascript MVC Frameworks Reviewed</a><br />
Лучшим признан <a href="http://emberjs.com/">Ember.js</a>. Надо поковырять)</p>
<p>UPD: поковырял. В принципе, более стройная архитектура, чем у того же backbone, у которого часть логики контроллера во вью. Но из коробки нет router и не так просто с pushState, так что не стал использовать серьёзно. Возможно, через полгода-год этот фреймворк будет интереснее.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-12-javascript-mvc-%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba%d0%be%d0%b2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Готовый бесплатный видеоплеер на html5</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/%d0%b3%d0%be%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%b1%d0%b5%d1%81%d0%bf%d0%bb%d0%b0%d1%82%d0%bd%d1%8b%d0%b9-%d0%b2%d0%b8%d0%b4%d0%b5%d0%be%d0%bf%d0%bb%d0%b5%d0%b5%d1%80-%d0%bd%d0%b0-html5/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/%d0%b3%d0%be%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%b1%d0%b5%d1%81%d0%bf%d0%bb%d0%b0%d1%82%d0%bd%d1%8b%d0%b9-%d0%b2%d0%b8%d0%b4%d0%b5%d0%be%d0%bf%d0%bb%d0%b5%d0%b5%d1%80-%d0%bd%d0%b0-html5/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 14:18:42 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[ссылка]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1386</guid>
		<description><![CDATA[http://videojs.com/]]></description>
			<content:encoded><![CDATA[<p><a href="http://videojs.com/">http://videojs.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/%d0%b3%d0%be%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%b1%d0%b5%d1%81%d0%bf%d0%bb%d0%b0%d1%82%d0%bd%d1%8b%d0%b9-%d0%b2%d0%b8%d0%b4%d0%b5%d0%be%d0%bf%d0%bb%d0%b5%d0%b5%d1%80-%d0%bd%d0%b0-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Презентации на javascript</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/%d0%bf%d1%80%d0%b5%d0%b7%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d0%b8-%d0%bd%d0%b0-javascript/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/%d0%bf%d1%80%d0%b5%d0%b7%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d0%b8-%d0%bd%d0%b0-javascript/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 14:09:50 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[Софт и сервисы]]></category>
		<category><![CDATA[презентации]]></category>
		<category><![CDATA[ссылка]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1383</guid>
		<description><![CDATA[https://github.com/bartaz/impress.js. Вот что получается: http://bartaz.github.com/impress.js/#/bored. Кстати, есть и описание на хабре &#8211; http://habrahabr.ru/blogs/css/136505/]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/bartaz/impress.js">https://github.com/bartaz/impress.js</a>.<br />
Вот что получается: <a href="http://bartaz.github.com/impress.js/#/bored">http://bartaz.github.com/impress.js/#/bored</a>.<br />
Кстати, есть и описание на хабре &#8211; <a href="http://habrahabr.ru/blogs/css/136505/">http://habrahabr.ru/blogs/css/136505/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/%d0%bf%d1%80%d0%b5%d0%b7%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d0%b8-%d0%bd%d0%b0-javascript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Popcorn.js &#8211; удобный и простой фреймворк для создания видеоплеера на HTML5</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/popcorn-js-%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba-%d0%b4%d0%bb%d1%8f-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d1%8f-%d0%b2%d0%b8%d0%b4%d0%b5%d0%be%d0%bf%d0%bb%d0%b5%d0%b5%d1%80%d0%b0/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/popcorn-js-%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba-%d0%b4%d0%bb%d1%8f-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d1%8f-%d0%b2%d0%b8%d0%b4%d0%b5%d0%be%d0%bf%d0%bb%d0%b5%d0%b5%d1%80%d0%b0/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 09:02:30 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[ссылка]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1378</guid>
		<description><![CDATA[http://popcornjs.org/ &#8211; позволяет показывать видео и другой контент пользователю без использования flash. Есть большой каталог примеров: http://popcornjs.org/Demo/semantic-video, http://popcornjs.org/Demo/popcorn-remote]]></description>
			<content:encoded><![CDATA[<p><a href="http://popcornjs.org/">http://popcornjs.org/</a> &#8211; позволяет показывать видео и другой контент пользователю без использования flash.<br />
Есть большой <a href="http://popcornjs.org/demos">каталог примеров</a>:<br />
<a href="http://popcornjs.org/Demo/semantic-video">http://popcornjs.org/Demo/semantic-video</a>, <a href="http://popcornjs.org/Demo/popcorn-remote">http://popcornjs.org/Demo/popcorn-remote</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/popcorn-js-%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba-%d0%b4%d0%bb%d1%8f-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d1%8f-%d0%b2%d0%b8%d0%b4%d0%b5%d0%be%d0%bf%d0%bb%d0%b5%d0%b5%d1%80%d0%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Самый хороший способ подгрузки яваскриптов – тегом script</title>
		<link>http://www.job-blog.bullgare.ru/2011/11/%d1%81%d0%b0%d0%bc%d1%8b%d0%b9-%d1%85%d0%be%d1%80%d0%be%d1%88%d0%b8%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%be%d0%b4%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8-%d1%8f%d0%b2%d0%b0%d1%81%d0%ba/</link>
		<comments>http://www.job-blog.bullgare.ru/2011/11/%d1%81%d0%b0%d0%bc%d1%8b%d0%b9-%d1%85%d0%be%d1%80%d0%be%d1%88%d0%b8%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%be%d0%b4%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8-%d1%8f%d0%b2%d0%b0%d1%81%d0%ba/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 07:24:51 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[клиентская оптимизация]]></category>
		<category><![CDATA[проектирование]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1309</guid>
		<description><![CDATA[Использовали мы на проекте одну лебедевскую библиотеку &#8211; include.js. Умеет она интересные вещи, вроде последовательной загрузки зависимых библиотек в нужном порядке. Нужно в яваскрипте написать js.include( &#8216;my/coolwiidget&#8217; );. Работает она, если на пальцах, следующим образом: делается ajax-запрос, которым грузится текст нужного скрипта, потом ищутся в тексте все js.include, делается их подгрузка, после чего делается eval [...]]]></description>
			<content:encoded><![CDATA[<p>Использовали мы на проекте одну лебедевскую библиотеку &#8211; <a href="http://www.artlebedev.ru/tools/technogrette/js/include/">include.js</a>. Умеет она интересные вещи, вроде последовательной загрузки зависимых библиотек в нужном порядке. Нужно в яваскрипте написать <strong>js.include( &#8216;my/coolwiidget&#8217; );</strong>. Работает она, если на пальцах, следующим образом: делается ajax-запрос, которым грузится текст нужного скрипта, потом ищутся в тексте все <strong>js.include</strong>, делается их подгрузка, после чего делается <strong>eval</strong> полученных текстов в обратном порядке. При этом ещё и отсекаются попытки по несколько раз грузить один и тот же яваскрипт.<br />
Работал он очень неплохо, хотя и неудобно было в firebug-е искать скрипт по его имени.<br />
Основная проблема встала, когда стало нужно вынести все яваскрипты на отдельный домен. Вот тут-то и проявились проблемы &#8211; ajax-ом нельзя грузить код с других доменов. Помогает заголовок <strong>Access-Control-Allow-Origin</strong>, но его понимают только современные браузеры (к примеру, firefox с версии 3.5), а на проекте критична максимально возможная совместимость (как обычно и бывает). Так что этот способ может быть актуален года через 3-5.<br />
Посмотрели на другие способы, в итоге пришли к динамическому добавлению тега <strong>script</strong> в <strong>head</strong>, но особого смысла в этом нет, т.к. зависимости, для которых и городился изначально огород, при этом способе не отслеживаются (JSONP с колбэками не подошёл, т.к. в проекте много legacy-кода, который использует глобальные переменные, причём даже не как константы).<br />
В итоге было принято гениальное в своей простоте решение &#8211; отказаться от всех этих изысков нафик и грузить скрипты как раньше &#8211; при загрузке страницы.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2011/11/%d1%81%d0%b0%d0%bc%d1%8b%d0%b9-%d1%85%d0%be%d1%80%d0%be%d1%88%d0%b8%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%be%d0%b4%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8-%d1%8f%d0%b2%d0%b0%d1%81%d0%ba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Фреймворки для создания MVC-подобной архитектуры на javascript</title>
		<link>http://www.job-blog.bullgare.ru/2011/11/%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba%d0%b8-%d0%b4%d0%bb%d1%8f-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d1%8f-mvc-%d0%bf%d0%be%d0%b4%d0%be%d0%b1%d0%bd%d0%be%d0%b9-%d0%b0%d1%80%d1%85/</link>
		<comments>http://www.job-blog.bullgare.ru/2011/11/%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba%d0%b8-%d0%b4%d0%bb%d1%8f-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d1%8f-mvc-%d0%bf%d0%be%d0%b4%d0%be%d0%b1%d0%bd%d0%be%d0%b9-%d0%b0%d1%80%d1%85/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 12:08:23 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[проектирование]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[MVVM]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1270</guid>
		<description><![CDATA[Выбирал между backbone (habrahabr.ru/blogs/javascript/118782/) и knockout (http://habrahabr.ru/blogs/javascript/121926/). Для выбора полезно почитать stackoverflow.com/questions/5112899/knockout-js-vs-backbone-js-vs. В итоге выбрал knockout &#8211; менее монструозный и лично мне показался понятнее, к тому же не навязывает REST и не требует дополнительных библиотек. Он реализует паттерн MVVM, который, думаю, больше подходит для клиентской части web-приложения, чем MVC. На сайте есть подробные доки и [...]]]></description>
			<content:encoded><![CDATA[<p>Выбирал между <a href="http://documentcloud.github.com/backbone/">backbone</a> (<a href="habrahabr.ru/blogs/javascript/118782/">habrahabr.ru/blogs/javascript/118782/</a>) и <a href="http://knockoutjs.com/">knockout</a> (<a href="http://habrahabr.ru/blogs/javascript/121926/">http://habrahabr.ru/blogs/javascript/121926/</a>).<br />
Для выбора полезно почитать <a href="stackoverflow.com/questions/5112899/knockout-js-vs-backbone-js-vs">stackoverflow.com/questions/5112899/knockout-js-vs-backbone-js-vs</a>.<br />
В итоге выбрал <strong>knockout</strong> &#8211; менее монструозный и лично мне показался понятнее, к тому же не навязывает REST и не требует дополнительных библиотек.<br />
Он реализует паттерн <a href="ru.wikipedia.org/wiki/MVVM">MVVM</a>, который, думаю, больше подходит для клиентской части web-приложения, чем MVC.<br />
На сайте есть подробные доки и очень удобный интерактивный туториал.<br />
Пока в проектах не использовал, так что писать особо нечего(</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2011/11/%d1%84%d1%80%d0%b5%d0%b9%d0%bc%d0%b2%d0%be%d1%80%d0%ba%d0%b8-%d0%b4%d0%bb%d1%8f-%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d1%8f-mvc-%d0%bf%d0%be%d0%b4%d0%be%d0%b1%d0%bd%d0%be%d0%b9-%d0%b0%d1%80%d1%85/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lazy load баннеров</title>
		<link>http://www.job-blog.bullgare.ru/2011/11/lazy-load-%d0%b1%d0%b0%d0%bd%d0%bd%d0%b5%d1%80%d0%be%d0%b2/</link>
		<comments>http://www.job-blog.bullgare.ru/2011/11/lazy-load-%d0%b1%d0%b0%d0%bd%d0%bd%d0%b5%d1%80%d0%be%d0%b2/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 07:58:18 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[клиентская оптимизация]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1282</guid>
		<description><![CDATA[Сегодня из-за очередных проблем с sol.adbureau.net было решено реализовать ленивую загрузку баннеров. Начальное решение было использовать iframe, но идея была не очень удачной, т. к. могут быть проблемы с подсчётом кликов, да и модные картинки, увеличивающиеся при наведении, будут вести себя странно. А как этот iframe смотрится в разных браузерах &#8211; это вообще сказка) В [...]]]></description>
			<content:encoded><![CDATA[<p>Сегодня из-за очередных проблем с sol.adbureau.net было решено реализовать ленивую загрузку баннеров.<br />
Начальное решение было использовать iframe, но идея была не очень удачной, т. к. могут быть проблемы с подсчётом кликов, да и модные картинки, увеличивающиеся при наведении, будут вести себя странно. А как этот iframe смотрится в разных браузерах &#8211; это вообще сказка)<br />
В итоге родилась идея: при генерации страницы размещать в нужных местах, к примеру, пустые дивы с id с нужным префиксом (<strong>&lt;div id=&raquo;js-advert-place-{num}&raquo;&gt;&lt;/div&gt;</strong>), а сами баннеры загружать в футер вот в такую, к примеру, разметку:</p>
<pre class="code">
&lt;div id="js-all-advert-block" class="all-advert-block"&gt;
	&lt;div class="js-advert-block-content" data-number="1"&gt;
		{баннер}
	&lt;/div&gt;
	&lt;div class="js-advert-block-content" data-number="5"&gt;
		{баннер}
	&lt;/div&gt;
	&lt;div class="js-advert-block-content" data-number="15"&gt;
		{баннер}
	&lt;/div&gt;
&lt;/div&gt;
{здесь грузится счётчик показов}
</pre>
<p>После загрузки страницы размещаем все баннеры на нужных местах:</p>
<pre class="code">
	(function( $ ) {
		function moveAdvert() {
			$( '#js-all-advert-block' ).find( '.js-advert-block-content' ).each( function() {
				var $oldContent = $( this );

			// в ие перемещаем
				if ( $.browser.msie ) {
					$( "#js-advert-place-" + $oldContent.data( "number" ) ).append( $oldContent );
				}
			// в других браузерах убираем лишнее и вставляем заново
				else
				{
					var cleanedContent = $oldContent.html().replace( /document\.write/gi, 'function a__(){}' );

					$( "#js-advert-place-" + $oldContent.data( "number" ) ).html( cleanedContent );
					$oldContent.remove();
				}

			// этот вариант менее хороший - глюки в ие и проблемы с яндекс.директ

			//	var $newContent = $.browser.msie ? $( $oldContent.html() ) : $oldContent.clone( true );

			//// не надо заново создавать скрипты - они заново выполнятся, а там document.write
			//	$newContent.find( "script, link" ).each( function() {
			//		$( this ).remove();
			//	} );

			//// вставляем
			//	$( "#js-advert-place-" + $oldContent.data( "number" ) ).html( $newContent );

			//// на старом месте нужно убить всё, кроме скриптов
			//// (в скриптах могут быть необходимые для правильного подсчёта кликов переменные)
			//	$oldContent.find( '*' ).each( function() {
			//		var $el = $( this );
			//		if ( ! $( 'script, link', $el ).length &#038;&#038; this.tagName.toLowerCase() != 'script' &#038;&#038; this.tagName.toLowerCase() != 'link' ) {
			//			$el.remove();
			//		}
			//	} );
			} );
		}

		$( document ).ready( function() {
			moveAdvert();
		} );
	}( jQuery ));
</pre>
<p>В итоге отвалившаяся внешняя баннерная площадка позволяет корректно отображать сайт без лишних задержек.<br />
За рамками осталась работа сервер-сайда, где нужно собрать данные по всем отображаемым на странице баннерам, а потом вывести их все сразу внизу.</p>
<p>UP:<br />
Всё-таки проблем оказалась куча. К примеру, opera 10.10 (хотя у меня 11.52) некорректно понимает тег <strong>script</strong> при <strong>.html( cleanedContent )</strong>, поэтому приходится чистить все теги <strong>script</strong>, но тогда умирает yandex.direct. К сожалению, на проекте нет нормальной возможности отделить директ от остальной рекламы (нет возможности объяснить тем людям, как что нужно настраивать), поэтому этот способ подходит с большими оговорками.<br />
UP2: Наткнулся на гениальное решение &#8211; переопределить <strong>document.write</strong>, потом немного доработал и вот что получилось:</p>
<pre class="code">
(function ( $ )
{
	// для собирания тега script
	var previousValue = '',
	// для проверки, собрали ли уже полный тег script
		reTestIfScript = new RegExp( '&lt;\/scr' + 'ipt&gt;$', 'i' ),
	// чтобы найти id дива, куда вставлять код соли
		reGetSolId = new RegExp( "sol\\.adbureau\\.net[^&gt;]+aamsz=(\\d+x\\d+)", 'i' ),
	// для проверки, что это относится к яндекс-директу
		reYandexDirect = new RegExp( "an\\.yandex\\.ru", 'i' );

// заменяем стандартные методы
	document.writeln = document.write = function(value)
	{
	// если последовательно пишут в документ для получения тега script (document.write( '&lt;SCR' ); document.write( '&lt;IPT src="...' );)
		try {
			$( value );
		}
		catch ( e )
		{
			var joinedValue = previousValue + value;
		// сли собрали полный тег скрипт, то вставляем его, куда надо
			if ( reTestIfScript.test( joinedValue ) )
			{
				value = joinedValue;
				previousValue = '';
			}
		// если начали писать тег скрипт, продолжаем до сбора всего тега
			else if ( joinedValue.toLowerCase().indexOf( '&lt;sc' ) == 0 )
			{
				previousValue = joinedValue;
				return;
			}
		// непонятно что это - ничего не делаем
			else {
				return;
			}
		}

		var parentNodeId,
			matches;
	// если в строке есть упоминание яндекса - вставляем в яндекс
		if ( reYandexDirect.test( value ) ) {
			parentNodeId = 'adv_media';
		}
	// если в строке есть упоминание соли - ищем id и вставляем в нужный div
		else if ( matches = value.match( reGetSolId ) ) {
			parentNodeId = 'sol' + matches[1];
		}

	// скрипт вставляем только в нужный элемент
		if ( $( value )[0].tagName == "SCRIPT" &#038;&#038; parentNodeId )
		{
			var js = document.createElement( 'SCRIPT' );
			var obj = document.getElementById( parentNodeId ).appendChild( js );

		// подгрузка внешнего скрипта
			if ( $( value ).attr( 'src' ) !== "undefined" ) {
				$( obj ).attr( {type: 'text/javascript', 'src': $( value ).attr( "src" )} );
			}
		// выполнение скрипта
			else
			{
				var reReplaceWrite = new RegExp( '(document\\.write[a-zA-Z]{0,2}\\([^)]+)(\\))', 'ig' );
				eval( $( value ).text().replace( reReplaceWrite, "$`$1, '" + parentNodeId + "'$2$'" ) );
			}
		}
	// стили ставим в head
		else if ( $( value )[0].tagName == "LINK" )
		{
			var js = document.createElement( 'LINK' );
			var obj = document.getElementsByTagName( 'head' )[0].appendChild( js );
			$( obj ).attr( {rel: 'stylesheet', 'href': $( value ).attr( "href" ) , type: 'text/css'} );
		}
		else if ( $( value )[0].tagName == "STYLE" )
		{
			if ( $.browser.msie ) {
				var css = document.createElement( 'STYLE' );
				document.documentElement.firstChild.appendChild( css );
				$( obj ).attr( {type: "text/css"} );
				css.styleSheet.cssText = $( value ).html();
			}
			else {
				$( value ).appendTo( $( "head" ) );
			}
		}
	// любой другой элемент вставляем в DOM, только если поняли, в какой элемент вставлять
		else if (  parentNodeId ) {
			$( value ).appendTo( $( "#" + parentNodeId ) );
		}
	};
}( jQuery ));
</pre>
<p>Всё бы ничего с этим решением, и даже знает, как собирать тег <strong>script</strong> из кусочков, но всё-таки мы не можем знать, в какое место DOM должна была производится запись, так что там есть костыли с определением места по контенту, и это решение не универсально.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2011/11/lazy-load-%d0%b1%d0%b0%d0%bd%d0%bd%d0%b5%d1%80%d0%be%d0%b2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

