<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>JSToolbox - все о JavaScript</title>
	
	<link>http://www.jstoolbox.com</link>
	<description>Блог о программировании вообще и о JavaScript в частности, уроки, статьи, заметки, база знаний.</description>
	<pubDate>Fri, 29 May 2009 21:10:59 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Jstoolbox" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">Jstoolbox</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Обесцвечивание элементов веб страниц</title>
		<link>http://www.jstoolbox.com/2009/05/29/obescvechivanie-elementov/</link>
		<comments>http://www.jstoolbox.com/2009/05/29/obescvechivanie-elementov/#comments</comments>
		<pubDate>Fri, 29 May 2009 20:59:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[CSS]]></category>

		<category><![CDATA[Canvas]]></category>

		<category><![CDATA[Эффекты]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[обесцвечивание]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=456</guid>
		<description><![CDATA[<p>Недавно нашел <a href="http://james.padolsey.com/javascript/grayscaling-in-non-ie-browsers/" title="Grayscaling in non-IE browsers">интересный метод</a> обесцветить, т.е. сделать черно-белым любой элемент на веб странице, будь то изображение изображение, таблица, форма или что-либо еще.</p>
<p>Казалось бы, зачем это может понадобиться? Однако у меня сразу же появилась мысль о том, где такая возможность пригодиться. Довольно часто в моей практике встречались дизайны, в которых существовали элементы управления (различные кнопки, иконки) в двух видах - цветной, обозначающий что элемент активен, и серый, обозначающий что элемент не активен и нажимать на него не имеет смысла. Раньше я использовал два разных изображения - одно цветное, одно черно-белое, и если элемент деактивировался, то я подставлял нецветную картинку. Недостаток такого метода в том, что браузер должен подгружать дополнительную картинку, и представьте себе, что этих картинок может быть довольно много... Кроме того, нужно тратить время на то, чтобы создавать все эти нецветные изображения. При помощи предлагаемого здесь метода, обесцвечивание можно выполнить простой функцией <strong>grayscale()</strong>.</p>]]></description>
			<content:encoded><![CDATA[<p>Недавно нашел <a href="http://james.padolsey.com/javascript/grayscaling-in-non-ie-browsers/" title="Grayscaling in non-IE browsers">интересный метод</a> обесцветить, т.е. сделать черно-белым любой элемент на веб странице, будь то изображение, таблица, форма или что-либо еще.</p>
<p>Казалось бы, зачем это может понадобиться? Однако у меня сразу же появилась мысль о том, где такая возможность пригодиться. Довольно часто в моей практике встречались дизайны, в которых существовали элементы управления (различные кнопки, иконки) в двух видах - цветной, обозначающий что элемент активен, и серый, обозначающий что элемент не активен и нажимать на него не имеет смысла. Раньше я использовал два разных изображения - одно цветное, одно черно-белое, и если элемент деактивировался, то я подставлял нецветную картинку. Недостаток такого метода в том, что браузер должен подгружать дополнительную картинку, и хуже всего, что этих картинок может быть довольно много&#8230; Кроме того, нужно тратить время на то, чтобы создавать все эти нецветные изображения. При помощи предлагаемого здесь метода, обесцвечивание можно выполнить простой функцией <strong>grayscale()</strong>.</p>
<p>Чтобы вам была более понятна суть, посмотрите мой <a href="/demo/grayscale.php" title="Демо пример обесцвечивания элементов DOM">демо пример</a>. Однако здесь же замечу, что, хотя этот метод и тестировался в разных браузерах, все же пока это экспериментальное решение.</p>
<p><span id="more-456"></span></p>
<p>Теперь вкратце опишу принцип работы этого метода.</p>
<p>Хоть я частенько и ругаю IE за его огрехи, но в этом случае он справляется лучше всех, ибо в Internet Explorer существует специальный фильтр который позволяет сделать такое преобразование цвета:</p>
<pre class="prettyprint">
elem.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)';
</pre>
<p>Фильтр может быть установлени и в CSS:</p>
<pre class="prettyprint">
elem {
    filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
    /* Элемент должен иметь "hasLayout"! */
    zoom: 1;
}
</pre>
<p>Что касается остальных браузеров, то здесь все гораздо сложнее. Во первых обесцвечивание обычных элементов - параграфов, таблиц и т.п. В этом случае нужно просматривать значения &#8220;цветных&#8221; стилей: color, background-color, и изменять их цвет следующими фукнциями:</p>
<pre class="prettyprint">
// Уменьшение насыщенности
function RGBtoDesat(r,g,b) {
    var average = (r + g + b) / 3;
    return {
        r: average,
        g: average,
        b: average
    };
}

// Преобразование в черно-белый цвет
function RGBtoGrayscale(r,g,b) {
    var mono = parseInt( (0.2125 * r) + (0.7154 * g) + (0.0721 * b), 10 );
    return {
        r: mono,
        g: mono,
        b: mono
    };
}
</pre>
<p>Для обесцвечивания изображений используется другая технология - элемент <strong>&lt;canvas&gt;</strong> и его метод <strong>getImageData()</strong>, но при этом изображение должно находиться на том же домене, что и веб страница. По всей видимости метод <strong>getImageData()</strong> не поддерживается в <em>Chrome</em> и <em>Safari</em> меньше четвертой версии, поэтому для этих браузеров такой метод работать не будет.</p>
<h3>Использование</h3>
<p>Чтобы выполнить обесцвечивание, нужно вызвать функцию <strong>grayscale()</strong>, передав в качестве параметра элемент или коллекцию элементов:</p>
<pre class="prettyprint">
// один элемент
var el = document.getElementById( 'myEl' );
grayscale( el );

// Массив элементов DOM
grayscale( document.getElementsByTagName('div') );

// Также работает с коллекциями jQuery
grayscale( $('div') );
</pre>
<p>Чтобы вернуть элемент в первоначальное, цветное, состояние, нужно воспользоваться функцией <strong>grayscale.reset()</strong>:</p>
<pre class="prettyprint">
grayscale.reset( el );
grayscale.reset( $('div') );
</pre>
<p>При всем этом, я бы не советовал вам использовать такую методику для больших изображений, так как их использование в элементе <strong>canvas</strong> может поглотить много ресурсов, даже если вы используете предлагаемую автором фунцкию <strong>grayscale.prepare()</strong> работы с такими изображениями.</p>
<p>Больше информации можете узнать на <a href="http://james.padolsey.com/javascript/grayscaling-in-non-ie-browsers/" title="Grayscaling in non-IE browsers">здесь</a>. Там же можно <a href="http://james.padolsey.com/demos/grayscale/">скачать скрипт и посмотреть демо пример автора</a>.</p>
<p><a href="/demo/grayscale.php" class="demo" title="Демо пример">Смотреть демо</a></p>
<div class="postLinks"><strong>Спонсор статьи:</strong><br/><a href="http://www.domania.ru/">http://www.domania.ru/</a> - продажа квартир в Москве<br/><a href="http://www.automania.ru/">http://www.automania.ru/</a> - подержанные автомобили<br/><a href="http://www.job.ru/">http://www.job.ru/</a> - работа в москве</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/05/29/obescvechivanie-elementov/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Lighter.js - подсветка синтаксиса для Mootools</title>
		<link>http://www.jstoolbox.com/2009/05/02/lighterjs-podsvetka-sintaksisa-dlya-mootools/</link>
		<comments>http://www.jstoolbox.com/2009/05/02/lighterjs-podsvetka-sintaksisa-dlya-mootools/#comments</comments>
		<pubDate>Sat, 02 May 2009 20:50:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[MooTools]]></category>

		<category><![CDATA[Плагины]]></category>

		<category><![CDATA[подсветка синтаксиса]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=449</guid>
		<description><![CDATA[<p><a href="http://pradador.com/code/lighterjs/" title="Lighter.js">Lighter.js</a> - это скрипт для подсветки синтаксиса, который использует для своей работы библиотеку <a href="http://mootools.net" title="Mootools">Mootools</a>. Скрипт прост в использовании и настройке, имеет различные цветовые темы. Я создал небольшой демо пример, чтобы вы могли оценить его способности. <a href="http://jstoolbox.com/demo/lighter.php" title="Демо пример подсветки синтаксиса">Смотреть демо пример</a>.</p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://pradador.com/code/lighterjs/" title="Lighter.js">Lighter.js</a> - это скрипт для подсветки синтаксиса, который использует для своей работы библиотеку <a href="http://mootools.net" title="Mootools">Mootools</a>. Скрипт прост в использовании и настройке, имеет различные цветовые темы. Я создал небольшой демо пример, чтобы вы могли оценить его способности. <a href="http://jstoolbox.com/demo/lighter.php" title="Демо пример подсветки синтаксиса">Смотреть демо пример</a>.</p>
<p><span id="more-449"></span></p>
<p>Теперь о том, как подключить и использовать скрипт.</p>
<p>Во-первых нужно скачать и подключить необходимые скрипты:</p>
<pre class="prettyprint">
&lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/mootools/1.2.1/mootools-yui-compressed.js">&lt;/script>
&lt;script type="text/javascript" src="source/Lighter.js">&lt;/script>
&lt;script type="text/javascript" src="source/Flame.js">&lt;/script>
&lt;script type="text/javascript" src="source/Flame.git.js">&lt;/script>
&lt;script type="text/javascript" src="source/Fuel.js">&lt;/script>
&lt;script type="text/javascript" src="source/Fuel.js.js">&lt;/script>
&lt;script type="text/javascript" src="source/Fuel.ruby.js">&lt;/script>
</pre>
<p>Сначала подключается файл библиотеки Mootools, затем исходники Lighter.js. Заметьте, что файлы с префиксом <em>Flame</em>, содержат темы для подсветки синтаксиса. То есть, если вы хотите иметь подсветку в стиле <a href="http://github.com">github.com</a>, то подключите файл <em>Flame.git.js</em>. Файлы с префиксом <em>Fuel</em> распознают исходный код языков. Это значит, что если вам нужно подсвечивать исходники на языках <em>Ruby</em> и <em>JavaScript</em>, то нужно подключить файлы <em>Fuel.ruby.js</em> и <em>Fuel.js.js</em>.</p>
<p>Блоки с подсвечиваемым кодом нужно отметить классом, в котором нужно указать язык программирования и тему подсветки:</p>
<pre class="prettyprint">
&lt;pre class="ruby:git">
// далее подсвечиваемый код
&lt;/pre>
</pre>
<p>Помимо этого, есть и другой способ указать скрипту тему и язык программирования - это указать в опциях вызова скрипта параметры <strong>Flame</strong> и <strong>Fuel</strong>.</p>
<p>Заключительный шаг - вызов функции <strong>light</strong>, в которую можно передать различные параметры работы скрипта:</p>
<pre class="prettyprint">
$$('pre').light({
    altLines: 'hover',
    mode: 'ol'
});
</pre>
<p>Здесь, в качестве параметров я передаю значение <em>hover</em> для парметра <strong>altLines</strong> для подсветки строк при наведении на них указателя мышки, <em>ol</em> для параметра <strong>mode</strong> для того, чтобы показывать номера строк. Все остальные опции можно узнать <a href="http://pradador.com/code/lighterjs/">здесь</a>.</p>
<p><a href="http://jstoolbox.com/demo/lighter.php" class="demo">Смотреть демо</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/05/02/lighterjs-podsvetka-sintaksisa-dlya-mootools/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Реализация бесконечной прокрутки на jQuery</title>
		<link>http://www.jstoolbox.com/2009/04/18/realizaciya-beskonechnoj-prokrutki-na-jquery/</link>
		<comments>http://www.jstoolbox.com/2009/04/18/realizaciya-beskonechnoj-prokrutki-na-jquery/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 21:44:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[jQuery]]></category>

		<category><![CDATA[бесконечная прокрутка]]></category>

		<category><![CDATA[юзабилити]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=428</guid>
		<description><![CDATA[<p>Всем вам должны быть хорошо известны интерфейсы просмотра лент новостей, записей блогов, в которых новые записи подгружаются по мере чтения. Новые данные подгружаются в тот момент, когда полоса прокрутки достигает самого низа. Хорошим примером такого интерфейса является <a href="http://reader.google.com" rel="nofollow">Google Reader</a>, а также сайт <a href="http://dzone.com" rel="nofollow">DZone</a>. Сегодня я покажу, как можно сделать такой интерфейс при помощи jQuery. Приложение будет имитировать работу блога, в котором при загрузке страницы, посредством AJAX будут загружаться первые 10 записей, а остальные будут подгружаться по мере чтения.</p>]]></description>
			<content:encoded><![CDATA[<p>Всем вам должны быть хорошо известны интерфейсы просмотра лент новостей, записей блогов, в которых новые записи подгружаются по мере чтения. Новые данные подгружаются в тот момент, когда полоса прокрутки достигает самого низа. Хорошим примером такого интерфейса является <a href="http://reader.google.com" rel="nofollow">Google Reader</a>, а также сайт <a href="http://dzone.com" rel="nofollow">DZone</a>. Сегодня я покажу, как можно сделать такой интерфейс при помощи jQuery. Приложение будет имитировать работу блога, в котором при загрузке страницы, посредством AJAX будут загружаться первые 10 записей, а остальные будут подгружаться по мере чтения.</p>
<p><span id="more-428"></span><br />
<br/></p>
<p>Начнем с создания простой HTML страницы, в теле которой имеется всего лишь один <em>div</em> - в него будут подгружаться записи. В этот div добавим элемент <em>&lt;div id=&#8221;loader&#8221;&gt;</em>, для того, чтобы использовать его как индикатора ожидания.</p>
<pre class="prettyprint">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
&lt;html>
&lt;head>
	&lt;script type="text/javascript" src="jquery.js">&lt;/script>

	&lt;style type="text/css">
	#blog {border:1px solid #aaf;background:#f9f9f9;padding:4px}
	.post {border:1px solid #aaa;background:#fff;padding:4px;margin: 2px 0}
	#loading {height: 40px}
	&lt;/style>
&lt;/head>

&lt;body id="hello_body">

	&lt;div id="blog">
		&lt;div id="loading" style="display:none">Loading....&lt;/div>
	&lt;/div>
&lt;/body>
&lt;/html>
</pre>
<p>Здесь также подключаем скрипт <em>jquery.js</em>, а также стили для блога и записей.</p>
<p>Далее переходим к созданию скрипта, вся функциональность которого будет заключена в объект <em>engine</em>:</p>
<pre class="prettyprint">
var engine = {
	posts : [],
	target : null,
	busy : false,
	count : 5
}
</pre>
<p>В переменных объекта <em>engine</em> хранятся различные параметры работы скрипта - количество подгружаемых за один раз записей (<strong>count</strong>), элемент, в который эти записи должны добавляться (<strong>target</strong>), состояние скрипта (<strong>busy</strong>), и массив записей (<strong>post</strong>).</p>
<p>Инициализация скрипта будет производиться функцией <strong>init</strong>:</p>
<pre class="prettyprint">
init : function(posts, target){
	if (!target)
		return;

	this.target = $(target);

	this.append(posts);

	var that = this;
	$(window).scroll(function(){
		if ($(document).height() - $(window).height() <= $(window).scrollTop() + 50) {
			that.scrollPosition = $(window).scrollTop();
			that.get();
		}
	});
}
</pre>
<p>Функция принимает два параметра - массив записей и элемент, в который записи должны быть добавлены. В конце функции добавляется обработчик события <em>onscroll</em> для объекта <em>window</em>. Его задача - определять положение полосы прокрутки, и если она находится в крайнем нижнем положении, то вызывать функцию подгрузки записей <strong>get()</strong>. Фунция <strong>get()</strong> отправляет AJAX запрос на сервер и, получая в ответ записи блога, добавляет их в элемент <em>target</em>:</p>
<pre class="prettyprint">
get : function() {
	if (!this.target || this.busy) return;

	if (this.posts &#038;&#038; this.posts.length) {
		var lastId = this.posts[this.posts.length-1].id;
	} else {
		var lastId = 0;
	}

	this.setBusy(true);

	var that = this;
	$.getJSON('getposts.php', {count:this.count, last:lastId},
		function(data){
			if (data.length > 0) {
				that.append(data);
			}
			that.setBusy(false);
		}
	);
}
</pre>
<p>Данные о всех записях, которые загружаются с сервера, хранятся в переменной <em>engine.posts</em>. Перед отправкой очередного запроса на сервер, функция <strong>get()</strong> получает id последнего элемента в этом списке (<em>lastId</em>), для того чтобы передать его в параметрах запроса. Это нужно для того, чтобы серверный скрипт знал, какие записи уже получены, и какие элементы нужно отправить.</p>
<p>Как в функции <strong>init()</strong>, так и в функции <strong>get()</strong>, для отображения записей используется функция <strong>append()</strong>, которая в связке с <strong>render()</strong> создает HTML код записи и добавляет его в целевой элемент (target):</p>
<pre class="prettyprint">
append : function(posts){
	posts = (posts instanceof Array) ? posts : [];
	this.posts = this.posts.concat(posts);

	for (var i=0, len = posts.length; i < len; i++) {
		this.target.append(this.render(posts[i]));
	}

	if (this.scrollPosition !== undefined &#038;&#038; this.scrollPosition !== null) {
		$(window).scrollTop(this.scrollPosition);
	}
},

render : function(obj){
	var xhtml = '&lt;div class="post" id=post_'+obj.id+'>';
	if (obj.title) {
		xhtml += '&lt;h2>'+obj.title+'&lt;/h2>';
	}
	if (obj.posted_at) {
		xhtml += '&lt;div class="posted_at">Posted on: '+obj.posted_at+'&lt;/div>';
	}
	if (obj.comments_count) {
		xhtml += '&lt;div class="comments_count">Comments: ' + obj.comments_count + '&lt;/div>';
	}
	xhtml += '&lt;div class="content">' + obj.content + '&lt;/div>';
	xhtml += '&lt;/div>';

	return xhtml;
}
</pre>
<p>Еще стоит упомянуть одну небольшую деталь: в обработчике события <strong>onscroll</strong> я сохраняя позицию полосы прокрутки, чтобы потом, после добавления новых записей, восстановить её. Это нужно для того, чтобы положение полосы прокрутки не изменялось, при добавлении новых записей в конец списка:</p>
<pre class="prettyprint">
// сохраняем значение в обработчике onscroll
that.scrollPosition = $(window).scrollTop();

.......

// восстанавливаем значение в функции append
if (this.scrollPosition !== undefined &#038;&#038; this.scrollPosition !== null) {
	$(window).scrollTop(this.scrollPosition);
}
</pre>
<p>Теперь, после того, как скрипт создан, можно использовать его. Так же как и для большинства скриптов jQuery, добавляем код инициализации  в фукнцию <strong>ready()</strong>:</p>
<pre class="prettyprint">
$(document).ready(function(){
	engine.init(null, $("#blog"));
	engine.get();
});
</pre>
<p>Вот пожалуй и все описание скрипта, как видите он совсем не сложный. Демо приложения можно посмотреть здесь: <a href="/demo/endless/">смотреть демо</a>. Полностью скрипт доступен на <a href="http://gist.github.com/97794">github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/04/18/realizaciya-beskonechnoj-prokrutki-na-jquery/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Интерфейс ‘Events’ для jQuery</title>
		<link>http://www.jstoolbox.com/2009/04/06/interfejs-events-dlya-jquery/</link>
		<comments>http://www.jstoolbox.com/2009/04/06/interfejs-events-dlya-jquery/#comments</comments>
		<pubDate>Sun, 05 Apr 2009 22:12:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=438</guid>
		<description><![CDATA[<p>По моему скромному мнению, код скриптов, написанных на jQuery порою напоминают что угодно, только не язык программирования JavaScript. Все дело в обильном применении шаблона программирования &#34;цепь&#34; - когда результат выполнения одной функции непосредственно передается в другую.</p>
<p>Конечно же это дело вкуса, но лично мне такая запись не всегда нравится. <a href="http://james.padolsey.com/">James Padolsey</a> решил немного изменить такую ситуацию, однако только в плане работы с событиями.]]></description>
			<content:encoded><![CDATA[<p>По моему скромному мнению, код скриптов, написанных на jQuery порою напоминают что угодно, только не язык программирования JavaScript. Все дело в обильном применении шаблона программирования &quot;цепь&quot; - когда результат выполнения одной функции непосредственно передается в другую:</p>
<pre class="prettyprint">
$('selector').click().onmouseover().onmouseout().focus();
</pre>
<p>Конечно же это дело вкуса, но лично мне такая запись не всегда нравится. <a href="http://james.padolsey.com/">James Padolsey</a> решил немного изменить такую ситуацию, однако только в плане работы с событиями. В одной из своих <a href="http://james.padolsey.com/javascript/events-interface-for-jquery/">статей</a> он предложил вариант назначения обработчиков при помощи созданной им функции <em>events</em>:</p>
<p><span id="more-438"></span></p>
<pre class="prettyprint">
$(elem).events({
    focus : function(){...},
    click : function(){...},
    mouseup : function(){...},
    'mousedown.namespace' : function(){...},
    exit : function(){...}
});
</pre>
<p>Как по мне, такой вариант гораздо лучше читается. Хотелось бы, чтобы в jQuery появилась такая функция, тем более, что её реализация очень проста - всего 6 строк:</p>
<pre class="prettyprint">
jQuery.fn.events = function(o){
    for (var i in o) {
        this.bind(i, o[i]);
    }
    return this;
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/04/06/interfejs-events-dlya-jquery/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Что такое JSONP?</title>
		<link>http://www.jstoolbox.com/2009/03/18/chto-takoe-jsonp/</link>
		<comments>http://www.jstoolbox.com/2009/03/18/chto-takoe-jsonp/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 14:54:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[JSON]]></category>

		<category><![CDATA[MooTools]]></category>

		<category><![CDATA[jQuery]]></category>

		<category><![CDATA[XMLHTTPRequest]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=422</guid>
		<description><![CDATA[<p>В последнее время довольно часто замечал в разных статьях упоминание о JSONP. Судя по названию это тот же JSON, но с каким-то наворотом. Поразобравшись немного с этим, оказалось что этот формат нужен для того, чтобы иметь возможность выполнять асинхронные запросы к серверу расположенному на другом домене. Напомню, что для объекта XMLHTTPRequest есть такое ограничение. То есть, если ваш сайт расположен по адресу <em>mysite.com</em>, то AJAX запрос на сервер <em>anothersite.com</em> выполнить не удастся.</p>]]></description>
			<content:encoded><![CDATA[<p>В последнее время довольно часто замечал в разных статьях упоминание о JSONP. Судя по названию это тот же JSON, но с каким-то наворотом. Поразобравшись немного с этим, оказалось что этот формат нужен для того, чтобы иметь возможность выполнять асинхронные запросы к серверу расположенному на другом домене. Напомню, что для объекта XMLHTTPRequest есть такое ограничение. То есть, если ваш сайт расположен по адресу <em>mysite.com</em>, то AJAX запрос на сервер <em>anothersite.com</em> выполнить не удастся.</p>
<p><span id="more-422"></span></p>
<p>Так вот, чтобы обойти это ограничение поступали следующим образом - динамически создавали и добавляли в документ новый тег <em>&lt;script&gt;</em>, который подгружал скрипт с нужными данными:</p>
<pre class="prettyprint">
&lt;script src="/some/url/here" type="text/javascript">&lt;/script>
</pre>
<p>При динамической подгрузке данных нужно выполнять callback, а для этого в конец подгружаемого скрипта добавляем вызов этой функции. В общем, получаемый от сервера скрипт может выглядеть следующим образом:</p>
<pre class="prettyprint">
var data = {
    one : "12",
    two : "34"
}

someCallback(data);
</pre>
<p>Если в указанном выше примере не объявлять переменную <em>data</em>, а сразу поместить её в вызов <em>someCallback</em>, то получим то, что сейчас стали называть <strong>JSONP</strong>:</p>
<pre class="prettyprint">
someCallback({ one : "12",  two : "34" });
</pre>
<p>В данный момент некоторые популярные сервисы поддерживают как JSON, так и JSONP. Типичным примером является API для поиска от YAHOO. Чтобы получить данные от сервера в виде JSON, мы указываем параметр <em>output=json</em>:</p>
<p><a href="http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=YahooDemo&#038;query=finances&#038;format=pdf&#038;output=json">http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=YahooDemo&#038;query=finances&#038;format=pdf&#038;output=json</a></p>
<p>Теперь, чтобы получить данные в виде JSONP, просто добавляем название функции-callback, в которую будут &#8220;завернуты&#8221; возвращаемые данные. Указанная выше ссылка будет выглядеть так:</p>
<p><a href="http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=YahooDemo&#038;query=finances&#038;format=pdf&#038;output=json&#038;callback=loadit">http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=YahooDemo&#038;query=finances&#038;format=pdf&#038;output=json&#038;callback=loadit</a></p>
<p>По этой ссылке сервер вернет следующие данные:</p>
<pre class="prettyprint">
loadit({"ResultSet":{"type":"web","totalResultsAvailable":22600000,"totalResultsReturned":10, ... } });
</pre>
<p>Теперь, короткий пример получения и обработки формата JSONP:</p>
<pre class="prettyprint">
&lt;html>
&lt;head>
&lt;script type="text/javascript">

// callback
function loadit(data) {
  // работаем с данными
  if (!data) {
    return;
  }

  var oTotal = document.getElementById("total");
  oTotal.innerHTML = data.ResultSet.totalResultsAvailable;
}

// здесь будет ссылка на новый элемент script
var oElem = null;

function sendJSONP(url, callback) {
  if (!url || !callback)
    return;

  url += '&#038;callback='+callback;

  // выполняем запрос JSONP
  if (oElem) {
    oElem.parentNode.removeChild(oElem);
  }

  oElem = document.createElement('script');
  oElem.setAttribute('type','text/javascript');
  document.getElementsByTagName('head')[0].appendChild(oElem);
  oElem.setAttribute('src', url);
}

window.onload = function(){
  document.getElementById("searchBtn").onclick = function(){
    var query = document.getElementById("query").value;
    sendJSONP('http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=YahooDemo&#038;query='+encodeURIComponent(query)+'&#038;output=json', 'loadit');
  }
}
&lt;/script>
&lt;/head>
&lt;body>
&lt;input type="text" name="search" value="" id="query" />&lt;input type="button" value="Искать" name="s" id="searchBtn"/>
&lt;div id="total">&lt;/div>
&lt;/body>
&lt;/html>
</pre>
<p>Этот скрипт работает следующим образом: пользователь вводит в поле поиска искомую фразу и нажимает на кнопку <em>&#8220;Искать&#8221;</em>. Из возвращаемых результатов поиска мы выделяем значение общего количества результатов <em>totalResultsAvailable</em> и показываем это значение в элементе <em>&lt;div id=total&gt;</em>. Запрос к серверу выполняется в функции sendJSONP, которая принимает 2 параметра - url и callback.</p>
<p>В библиотеке jQuery имеется встроенная поддержка формата JSONP. При использовании этого фреймворка, нет нужды самому код, который добавляет тег SCRIPT в DOM. Всё, что нужно будет сделать, это изменить URL, чтобы указать jQuery, что выполняется JSONP запрос. Заканчивая URL вопросительным знаком, мы даем jQuery понять, что получаемые данные будут в формате JSONP. Не нужно также и указывать название функции обработчика. Пример:</p>
<pre class="prettyprint">
&lt;html>
&lt;head>
&lt;script src="/jquery/jquery.js">&lt;/script>
&lt;script>
var baseurl = 'http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&#038;output=json&#038;query='

function search() {
     var search = $("#search").val()
     console.log(search)
     var surl = baseurl + escape(search) + '&#038;callback=?'
     $.getJSON(surl, function(data) {
          var res = '&lt;h1>Search for '+search+'&lt;/h1>'
          res += '&lt;p>There were '+data.ResultSet.totalResultsAvailable+' results.&lt;/p>'
          for(var i=0; i&lt;data.ResultSet.Result.length; i++) {
               var result = data.ResultSet.Result[i]
               var resultStr = '&lt;img src="'+result['Thumbnail']['Url']+'" align="left">';
               resultStr += '&lt;a href="'+result['ClickUrl']+'">'+result['Title']+'&lt;/a>&lt;br clear="left"/>'
               res+=resultStr
           }
          $("#result").html(res)
      })
}
$(document).ready(function() {
     $("#searchBtn").click(search)
});

&lt;/script>
&lt;/head>

&lt;body>
    &lt;input type="text" name="search" id="search"> &lt;input type="button" value="Search" id="searchBtn">
    &lt;div id="result">&lt;/div>
&lt;/body>
&lt;/html>
</pre>
<p>Этот пример для работы с jQuery позаимствован на <a href="http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html">InsideRIA</a>.</p>
<p>Поддержка JSONP скоро будет доступна и в <a href="http://mootools.net">Mootools</a>. В данный момент она уже есть в версии 1.3rc1. Выглядит это так:</p>
<pre class="prettyprint">
new JsonP('http://api.cnet.com/restApi/v1.0/techProductSearch', {
    data: {
        partTag: 'mtvo',
        iod: 'hlPrice',
        iewType: 'json',
        results: '100',
        query: 'ipod'
    },
    onComplete: myFunction.bind(someObject)
}).request();
</pre>
<p>На мой взгляд гораздо понятнее и проще, чем чудеса с вопросительными знаками в jQuery <img src='http://www.jstoolbox.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/03/18/chto-takoe-jsonp/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
