<?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>JSToolbox - все о JavaScript &#187; Уроки</title>
	<atom:link href="http://www.jstoolbox.com/category/uroki/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jstoolbox.com</link>
	<description>Блог о программировании вообще и о JavaScript в частности, уроки, статьи, заметки, база знаний.</description>
	<lastBuildDate>Wed, 28 Jul 2010 22:33:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Как создать плагин для jQuery</title>
		<link>http://www.jstoolbox.com/2009/10/03/kak-sozdat-plagin-dlya-jquery/</link>
		<comments>http://www.jstoolbox.com/2009/10/03/kak-sozdat-plagin-dlya-jquery/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 13:11:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Уроки]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=501</guid>
		<description><![CDATA[<p>Чаще всего мне приходится писать скрипты под jQuery, и иногда очень удобно реализовывать функциональность путем создания плагина. В этой статье я покажу как это можно сделать. Пример будет тривиальный, но надеюсь понятный. Фунцкиональнось учебного плагина аналогична hover эффекту - при наведении указателя мыши на элемент, его фон меняется, если убрать указатель, то фон меняется на первоначальный (этого можно достичь при помощи CSS, но не забывайте, что это всего-лишь пример).</p>]]></description>
			<content:encoded><![CDATA[<p>Чаще всего мне приходится писать скрипты под jQuery, и иногда очень удобно реализовывать функциональность путем создания плагина. В этой статье я покажу как это можно сделать. Пример будет тривиальный, но надеюсь понятный. Фунцкиональнось учебного плагина аналогична hover эффекту &#8211; при наведении указателя мыши на элемент, его фон меняется, если убрать указатель, то фон меняется на первоначальный (этого можно достичь при помощи CSS, но не забывайте, что это всего-лишь пример).</p>
<p>В основе библиотеки jQuery лежит класс с аналогичным названием <em>jQuery</em> (у него есть псевдоним $). Подобно тому, как классы в JavaScript можно расширять, используя свойство <em>prototype</em>, точно также мы можем расширить функциональность класса <em>jQuery</em>. Именно таким образом и создаются плагины. Поскольку в jQuery для свойства <em>prototype</em> есть псевдоним <em>fn</em>, то он чаще всего и используется для этой цели.</p>
<p><span id="more-501"></span></p>
<p>Наш плагин начинаем следующим образом:</p>
<pre class="prettyprint">
(function($){
    $.fn.backgroundHover = function(options) {
       return this.each(function () {
          // Код плагина
       });
    };
})(jQuery);
</pre>
<p>Первая и последняя строка этого блока представляют собой вызов анонимной функции, единственным аргументом которого будет объект <em>jQuery</em>. В результате, мы получим еще одну область определения переменных (scope), то есть, все переменные и функции, объявленные внутри этой анонимной функции будут недоступны извне (не распространяются на глобальную область видимости <em>window</em>). Поскольку плагин выполняет действия над некоторым множеством элементов DOM в одном вызове, то мы должны обрабатывать все эти элементы в одном цикле. Это делается при помощи функции <em>each</em> в строке 3.</p>
<p>Все плагины способны принимать некоторое количество параметров, выполним эту функциональность следующим образом:</p>
<pre class="prettyprint">
$.fn.backgroundHover = function(options) {
      options = $.extend({
         background: 'red',
      }, options);
</pre>
<p>Все параметры хранятся в переменной <em>options</em>. Для инициализации этой переменной мы используем фунцию <em>$.extend()</em>, первым аргументом которой указываем объект, с параметрами по умолчанию, второй аргумент &#8211; параметры, указанные пользователем. В нашем случае, имеем всего лишь один параметр &#8211; цвет фона (background), по умолчанию он имеет значение red.</p>
<p>Ну и последний шаг &#8211; добавляем функциональность плагина внутрь функции <em>each</em>:</p>
<pre class="prettyprint">
var self = $(this);
   self.mouseover(function() {
      self.oldBG = self.css('backgroundColor');
      self.css('backgroundColor',options.background);
   });

   self.mouseout(function() {
      self.css('backgroundColor',self.oldBG);
   });
</pre>
<p>В первой строке мы создаем переменную <em>self</em>, которая будет ссылаться на текущий элемент DOM. Для всех выбранных элементов будут добавлены два обработчика событий &#8211; mouseover и mouseout, которые будут менять цвет фона в соответсвии с параметром <em>options.background</em>.</p>
<p>На этом создание плагина закончено, используется он следующим образом:</p>
<pre class="prettyprint">
$('.someNodes').backgroundHover({background: "#fce"});
</pre>
<p>Исходный код плагина можно посмотреть здесь: <a href="http://www.jstoolbox.com/js/background.jquery.js" rel="nofollow">background.jquery.js</a>.</p>
<p><a href="http://www.jstoolbox.com/demo/jqplugin/" class="demo">Демо пример</a><a href="http://blog.slackers.se/2009/09/how-to-create-jquery-plugin.html" class="external">Источник</a></p>
<div class="postLinks"><strong>При поддержке:</strong><br/><br />
<a href="http://majkop.job.ru/">http://majkop.job.ru/</a> &#8211; работа в Майкопе<br/><a href="http://foreign.domania.ru/">http://foreign.domania.ru/</a> &#8211; зарубежная недвижимость<br/><a href="http://obninsk.domania.ru/">http://obninsk.domania.ru/</a> &#8211; недвижимость в обнинске</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/10/03/kak-sozdat-plagin-dlya-jquery/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Управление табличными данными при помощи jQuery</title>
		<link>http://www.jstoolbox.com/2009/01/22/upravlenie-tablichnymi-dannymi-pri-pomoshhi-jquery/</link>
		<comments>http://www.jstoolbox.com/2009/01/22/upravlenie-tablichnymi-dannymi-pri-pomoshhi-jquery/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 15:33:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Уроки]]></category>
		<category><![CDATA[tableFormSynch]]></category>
		<category><![CDATA[туториал]]></category>
		<category><![CDATA[урок]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=355</guid>
		<description><![CDATA[<p>В одной из прошлых статей я <a href="http://www.jstoolbox.com/2008/12/21/redaktiruemyj-kontent-na-jquery/">писал</a> о том, как сделать текст на странице динамически редактируемым. Там был представлен метод редактирования при помощи плагина <a href="http://www.appelsiini.net/projects/jeditable">jEditable</a>. Таким образом можно динамически редактировать любой блок текста на странице. Однако если речь идет о табличных данных, то гораздо удобнее использовать другое решение - плагин <a href="http://www.swartzfager.org/blog/jQuery/plugins/tableFormSynch/">tableFormSynch</a>. Этот плагин связывает таблицу с формой, давая возможность динамически редактировать данные в таблице, а также добавлять и удалять записи.</p>]]></description>
			<content:encoded><![CDATA[<p style="margin: 0 0 4px 4px; padding: 2px; border: 1px solid red"><strong>Update:</strong> Внимание! Эта статья устаревшая, а плагин, который здесь используется уже не поддерживается автором и имеет неисправленные ошибки.</p>
<p>В одной из прошлых статей я <a href="http://www.jstoolbox.com/2008/12/21/redaktiruemyj-kontent-na-jquery/">писал</a> о том, как сделать текст на странице динамически редактируемым. Там был представлен метод редактирования при помощи плагина <a href="http://www.appelsiini.net/projects/jeditable">jEditable</a>. Таким образом можно динамически редактировать любой блок текста на странице. Однако если речь идет о табличных данных, то гораздо удобнее использовать другое решение &#8211; плагин <a href="http://www.swartzfager.org/blog/jQuery/plugins/tableFormSynch/">tableFormSynch</a>. Этот плагин связывает таблицу с формой, давая возможность динамически редактировать данные в таблице, а также добавлять и удалять записи.</p>
<p>В этой статье я покажу, как сделать простое приложение, реализующее редактирование, добавление и удаление записей таблицы, сохраняя данные при помощи AJAX. Чтобы создать приложение нам будут нужны библиотека <a href="http://jquery.com">jQuery</a>, плагин <a href="http://plugins.jquery.com/project/metadata">metadata</a> (требуется для работы плагина tableFormSynch), а также <a href="http://malsup.com/jquery/form/">jQuery Form Plugin</a> для сохранения данных формы через AJAX. Но прежде чем мы начнем, предлагаю посмотреть на готовый результат. <a href="http://www.jstoolbox.com/demo/tablesynch/index.php" title="Демо пример">Смотреть демо пример</a>.</p>
<p><span id="more-355"></span></p>
<p>Итак, начинаем с того, что создаем HTML страницу и подключаем к ней необходимые нам скрипты:</p>
<pre class="prettyprint">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
&lt;html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="ru-RU">

&lt;head profile="http://gmpg.org/xfn/11">
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

&lt;script type="text/javascript" src="jquery-1.2.6.min.js">&lt;/script>
&lt;script type="text/javascript" src="jquery.metadata.min.js">&lt;/script>
&lt;script type="text/javascript" src="jquery.tableFormSynch.documented.js">&lt;/script>
&lt;script type="text/javascript" src="jquery.form.js">&lt;/script>

&lt;/head>
&lt;body>

&lt;/body>
&lt;/html>
</pre>
<p>Далее добавляем табличные данные, которые мы собираемся редактировать, плюс сюда же добавляем ссылки на редактирование и удаление записи. Здесь есть обязательные условия: для каждой строки таблицы нужно указать ID записи в атрибуте <em>id</em> и метаданные (то есть все данные записи) в атрибуте <em>class</em>. И еще &#8211; все строки таблицы должны быть обязательно заключены в тэги <em>&lt;tbody&gt;</em>:</p>
<pre class="prettyprint">
&lt;tr id="1" class="{personId:1,first_name:'Иван',last_name:'Иванов',position:'Программист'}">
	&lt;td>Иван&lt;/td>
	&lt;td>Иванов&lt;/td>
	&lt;td>Программист&lt;/td>
	&lt;td>&lt;a href="#" class="edit">Редактировать&lt;/a> | &lt;a href="#" class="delete">удалить&lt;/a>&lt;/td>
&lt;/tr>
</pre>
<p>Следующий шаг &#8211; создание формы: она будет располагаться в последней строке таблицы и при загрузке страницы будет не видна. Появляться она будет по надобности, при нажатии на ссылки &#8220;добавить запись&#8221; или &#8220;редактировать&#8221;. Форма будет иметь все нужные поля (в нашем случае текстовые поля) и три кнопки &#8211; &#8220;добавить&#8221; и &#8220;редактировать&#8221;, которые появляются в зависимости от выбранного действия, а также &#8220;отмена&#8221;, по нажатию на которую форма будет исчезать.</p>
<pre class="prettyprint">
&lt;form id="rowEditForm" action="save.php" method="post">
&lt;table width="100%" cellpadding="0" cellspacing="0" border="0" id="demoTable" class="tablesCorp">

&lt;!-- строки таблицы -->

&lt;tr id="editableRow">
	&lt;td>&lt;input type="hidden" name="personId" value="0"/>&lt;input type="text" name="first_name" value=""/>&lt;/td>
	&lt;td>&lt;input type="text" name="last_name" value=""/>&lt;/td>
	&lt;td>&lt;input type="text" name="position" value=""/>&lt;/td>
	&lt;td>
		&lt;input id="updateBtn" type="submit" name="update" value="Обновить"/>
		&lt;input id="addBtn" type="submit" name="add" value="Добавить"/>
		&lt;input id="cancelBtn" type="button" name="cancel" value="Отмена"/>
		&lt;img id="loading" src="loading.gif" />
	&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/form>
</pre>
<p>Ну и самая малость &#8211; под таблицей размещаем ссылку &#8220;добавить запись&#8221;:</p>
<pre class="prettyprint">
&lt;a href="#" class="add">Добавить запись&lt;/a>
</pre>
<p>Теперь приступим к созданию скрипта нашего приложения. Как полагается для скриптов, написанных под jQuery, заключаем весь наш код в функцию <strong>$.ready()</strong>, и первое, что мы туда поместим, это вызов функции <strong>bindTableToForm()</strong>, которая связывает таблицу с формой:</p>
<pre class="prettyprint">
$(document).ready(function() {

	$("#demoTable").bindTableToForm($("#rowEditForm"),"personId");

});
</pre>
<p>Первым параметром в функцию мы передаем форму, а вторым &#8211; название ключевого поля записи, в нашем случае это ID пользователя.</p>
<p>Далее, создаем фукнцию редактирования. Добавляем ко всем ссылкам &#8220;редактировать&#8221; обработчик, который будет показывать форму редактирования под нужной строкой. Форму заполняем данными при помощи функции <strong>populateForm()</strong>и здесь же показываем конпку &#8220;редактировать&#8221; и прячем конпку &#8220;добавить&#8221;. Таким образом мы переводим форму в режим редактирования. Ну и для красоты подкрашиваем редактируемую строку бледно розовым цветом:</p>
<pre class="prettyprint">
$("a.edit").click(function() {

	$("#addBtn").hide();
	$("#updateBtn").show();

	$(this).populateForm();

	var row = $(this).parent().parent();
	row.find('td').css('background-color','#faa');
	$('#editableRow').insertAfter(row).fadeIn('slow');

	// отмена действия по умолчанию
	return false;
});
</pre>
<p>При нажатии на кнопку &#8220;обновить&#8221;, данные формы будут отправляться на сервер через AJAX, и при успешном сохранении, запись в таблице будет обновляться. Выполняем это все в обработчике <em>onclick</em> кнопки:</p>
<pre class="prettyprint">
$("#updateBtn").click(function() {
	$('#rowEditForm').ajaxForm({
		beforeSubmit : function(){
			$('#loading').show();
		},
		success : function(response){
			$('#loading').hide();
			if (response == 1)
				$("#rowEditForm").updateRow();
			else
				alert('Ошибка сохранения данных');

			var rowId = $("input[name='personId']").val();
			var row = $('tr#'+rowId).find('td').css('background-color','#F5F5F5');
			$('#editableRow').fadeOut('slow');
		}
	});
});
</pre>
<p>Здесь мы используем функцию <strong>ajaxForm()</strong> для выполнения AJAX запроса с данными формы. При успешном сохранении данных, сервер возвращает значение 1, в любом другом случае, трактуем результат как ошибку. Данные в таблице обновляем фукнцией <strong>updateRow()</strong>.</p>
<p>Далее реализовуем добавление новой записи. Всё делаем также, как и для обновления, только вместо того, чтобы заполнять форму, очищаем её функцией <strong>clearForm()</strong>. Ну и естественно, вместо кнопки &#8220;редактировать&#8221; делаем активной кнопку &#8220;добавить&#8221;:</p>
<pre class="prettyprint">
$("a.add").click(function() {
	$("#addBtn").show();
	$("#updateBtn").hide();

	// очищаем форму
	$("#rowEditForm").clearForm();
	$("input[name='personId']").val(0);

	$('#demoTable tbody').append($('#editableRow'));
	$('#editableRow').fadeIn('slow');

	return false;
});
</pre>
<p>Обработчик для кнопки &#8220;добавить&#8221; также мало чем отличается от функции обновления, за исключением того, что сервер возвращает ID новой записи, который затем передается в функцию <strong>addRow()</strong> для добавления записи:</p>
<pre class="prettyprint">
$("#addBtn").click(function() {
	$('#rowEditForm').ajaxForm({
		beforeSubmit : function(){
			$('#loading').show();
		},
		success : function(response){
			$('#loading').hide();
			if (response == 0)
				alert('Ошибка добавления данных');
			else
				$("#rowEditForm").addRow(response);

			$('#editableRow').fadeOut('slow');
		}
	});
});
</pre>
<p>Теперь выполним удаление записи &#8211; используем для этого функцию <strong>deleteRow()</strong>. Для отправки запроса на сервер будем использовать функцию <strong>$.post()</strong>, которая будет отправлять запрос в отдельный файл <em>delete.php</em>. Последний выполняет удаление записи и возвращает 1 если запись удалилась, и 0 если произошла ошибка. В самом начале функции мы получаем ID записи которую необходимо удалить, затем передаем это значение в функцию <strong>$.post()</strong> в качестве параметра <em>personId</em>, который будет установлен переменной в POST:</p>
<pre class="prettyprint">
$("a.delete").click(function() {

	var id = $(this).parent().parent().attr('id');

	var that = $(this);
	$.post('delete.php',
		{personId : id},
		function(data){
			if (data == 1)
				that.deleteRow();
			else
				alert('Ошибка удаления записи');
		});
	return false;
});
</pre>
<p>Ну и последняя, самая простая функция &#8211; &#8220;отмена&#8221;. Здесь мы просто прячем форму и закрашиваем все строки формы в стандартный цвет:</p>
<pre class="prettyprint">
$("#cancelBtn").click(function(){
	$("#editableRow").fadeOut("slow");
	$(".tablesCorp td").css('background-color','#F5F5F5');
});
</pre>
<p>Посмотреть скрипт полностью можно <a href="http://www.jstoolbox.com/demo/tablesynch/script.js">здесь</a>.</p>
<p>После этого нужно еще установить пару обязательных стилей:</p>
<pre class="prettyprint">
#editableRow {display:none}
#addBtn {display:none}
</pre>
<p>Первая строка прячет форму редактирования, а вторая кнопку &#8220;добавить&#8221;, которые в начале работы должны быть скрытыми.</p>
<p>Вот и все, наше приложение готово. Буду рад услышать Ваши замечания <img src='http://www.jstoolbox.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <br/><br />
До встречи!</p>
<p  style="margin: 0 0 4px 4px; padding: 2px; border: 1px solid red"><strong>Update:</strong> Внимание! Эта статья устаревшая, а плагин, который здесь используется уже не поддерживается автором и имеет неисправленные ошибки.</p>
<p><a href="http://www.jstoolbox.com/demo/tablesynch/index.php" class="demo">смотреть демо</a><a href="http://www.jstoolbox.com/download/synch.zip" class="download">скачать демо</a></p>
<div class="postLinks">
<strong>Спонсор статьи:</strong><br/>Автошколы, автокурсы и <a href="http://avtobip.ru/">автоинструкторы Москвы</a><br/>Курсы MBA, бизнес школа <a href="http://ukraine.ibr-network.com/">мба одесса</a><br/><a href="http://voditel.info/">Инструктор по вождению</a> &#8211; обучение вождению автомобиля в Москве</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/01/22/upravlenie-tablichnymi-dannymi-pri-pomoshhi-jquery/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>Туториал: Создание окон на Mootools</title>
		<link>http://www.jstoolbox.com/2008/09/23/okna-mootools/</link>
		<comments>http://www.jstoolbox.com/2008/09/23/okna-mootools/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 08:13:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Уроки]]></category>
		<category><![CDATA[окна]]></category>
		<category><![CDATA[туториал]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/2008/09/23/okna-mootools/</guid>
		<description><![CDATA[Различные всплывающие окошки, выполненные на JavaScript (не путать с pop-up окнами, вызываемыми при window.open), становятся все более распространенными. Чаще всего они используются для динамического отображения подсказок, диалогов, да и просто рекламы (что зачастую раздражает   ). Сегодня я расскажу то, как можно сделать такие окна при помощи популярной библиотеки Mootools. Конечный результат будет выглядеть [...]]]></description>
			<content:encoded><![CDATA[<p>Различные всплывающие окошки, выполненные на JavaScript (не путать с pop-up окнами, вызываемыми при window.open), становятся все более распространенными. Чаще всего они используются для динамического отображения подсказок, диалогов, да и просто рекламы (что зачастую раздражает <img src='http://www.jstoolbox.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). Сегодня я расскажу то, как можно сделать такие окна при помощи популярной библиотеки <a href="http://mootools.net" title="Библиотека Mootools">Mootools</a>. Конечный результат будет выглядеть следующим образом:</p>
<div class="entry_picture" style="width:252px">
<img src='http://www.jstoolbox.com/wp-content/uploads/2008/09/windows.png' alt='Окна на Mootools' />
</div>
<p><span id="more-223"></span></p>
<p>Как видите дизайн окон несколько позаимствован из <a href="http://extjs.com" title="ExtJS фреймворк">ExtJS</a>.</p>
<p>Итак, начнем с основы &#8211; определимся с HTML разметкой окна. Схематически она показана следующем рисунке:</p>
<div class="entry_picture" style="width: 624px">
<img src='http://www.jstoolbox.com/wp-content/uploads/2008/09/window_scheme.png' alt='Схема окна' />
</div>
<p>Основным контейнером для окна будет <em>&lt;div class=&#8221;dWindow&#8221;&gt;</em>, для которого установлено абсолютное позиционирование (чтобы можно было перетаскивать окно). Строка заголовка будет также выполнена в виде div-а, а вот содержимое окна и его строка состояния будут сделаны в виде элементов таблицы. На мой взгяд, таким образом легче создать границы (кромки) окна.</p>
<p>Теперь, определившись со структурой окна, можно писать код. Поскольку нам нужно создавать не одно окно, а множество, то реализуем это в виде класса:</p>
<pre class="prettyprint">
var dWindow = new Class({
	options: {
		minWidth : 150,
		minHeight : 150,
		width : 200,
		height : 200,
		top : 0,
		left : 0,
		resizable : true,
		statusBar : true,
		content : '',
		id : ''
	},

	// конструктор класса
	initialize: function(options){
		this.setOptions(options);
	}

	Implements : [Options, Events]
});
</pre>
<p>Это стандартная структура класса в Mootools. Перечисленные опции <em>options</em> определяют свойства окна &#8211; размеры, положение, и др. Теперь нам нужно сделать функцию, которя будет создавать окно и добавлять его в нужный нам элемент. Делаем её следующим образом (функция <strong>_create()</strong>):</p>
<pre class="prettyprint">
var dWindowZIndex = 100;

var dWindow = new Class({
	options: {
		minWidth : 150,
		minHeight : 150,
		width : 200,
		height : 200,
		top : 0,
		left : 0,
		resizable : true,
		statusBar : true,
		content : '',
		id : ''
	},

	handle : null,
	drag : null,
	dragParams : {},

	initialize: function(options){
		this.setOptions(options);
	},

	_create : function(id){
		var target = $(id);
		if (!target)
			return;

		this.handle = new Element('div', {
				'class':'dWindow',
				'id' : this.options.id,
				styles : {
					'width':this.options.width + 2,
					'left':this.options.left,
					'top':this.options.top,
					'z-index':dWindowZIndex
				}
			});
		dWindowZIndex++;
		this.handle.addEvent('mousedown', this.up.bind(this));

		var bar = new Element('div', {'class':'topBar'});
		var closeBtn = new Element('div', {'class':'closeBtn'});
		closeBtn.addEvent('click', this.close.bind(this));
		closeBtn.injectInside(bar);

		var table = new Element('table',{
			'class':'dContainer',
			'cellpadding':0,
			'cellspacing':0,
			'border':0
		});

		var tbody = new Element('tbody');

		// первый ряд (содержимое окна, левая и правая границы)
		var row = new Element('tr');
		var leftBorder = new Element('td', {'rowspan':2,'class':'leftBorder'});
		var rightBorder = new Element('td', {'rowspan':2,'class':'rightBorder'});
		var center = new Element('td');
		var content = new Element('div',{'class':'centralArea', styles : {'width':this.options.width, 'height':this.options.height}});
		content.set('html',this.options.content);
		center.adopt(content);

		row.adopt([leftBorder, center, rightBorder]);

		// второй ряд (строка состояния)
		var row2 = new Element('tr');
		var statusBar = new Element('td',{'class':'statusBar'});
		var brResize = new Element('div', {'class':'resize'});
		brResize.injectInside(statusBar);
		statusBar.injectInside(row2);

		// третий ряд (с нижней кромкой)
		var row3 = new Element('tr');
		var bottomBorder = new Element('td', {'colspan':3,'class':'bottomBorder'});
		bottomBorder.injectInside(row3);

		row.injectInside(tbody);
		row2.injectInside(tbody);
		row3.injectInside(tbody);
		tbody.injectInside(table);

		this.handle.adopt([bar, table]);
		this.handle.injectInside(target);
	},

	Implements : [Options, Events]
});
</pre>
<p>Функция <strong>_create()</strong> довольно таки незатейлива (пока) и все что она делает, это создает все элементы окна при помощи класса <strong>Element</strong> и добавляет их в основной контейнер окна (функции <strong>injectInside()</strong> и <strong>adopt()</strong>), создаваемый тут же. Помимо этого кнопке &quot;Закрыть&quot; назначается обработчик <strong>close()</strong> (будет создан позже), который будет закрывать окно. В конце концов, в последней строке функции, созданное окно добавляется в элемент <strong>target</strong>, имеющийся на странице, ссылка на который должна передаваться функции в качестве аргумента.</p>
<p>Также обратите внимание на глобальную переменную <strong>dWindowZIndex</strong>, которая нужна для хранения текущего максимального значения <em>z-index</em> окна. Каждый раз, когда пользователь будет кликать внутри окна, это значение будет увеличиваться на единицу и назначаться текущим значением <em>z-index</em> окна. Обработчик, который будет выполнять эту операцию &#8211; функция <strong>up()</strong> &#8211; назначается событию <em>mousedown</em> основного контейнера окна. Все эти действия направлены на то, чтобы дать пользователю возможность выбрать окно, переместив его поверх всех других при щелчке на нем.</p>
<p>Итак, на данном этапе, функция <strong>_create()</strong> создает окно, которое имеет следующую структуру:</p>
<pre class="prettyprint">
&lt;div class="dWindow" style="width: 262px; left: 236px; top: 74px; z-index: 106; position: absolute;">
	&lt;div class="topBar">&lt;div class="closeBtn"/>&lt;/div>
	&lt;table cellspacing="0" cellpadding="0" border="0" class="dContainer">
	&lt;tbody>
		&lt;tr>
			&lt;td rowspan="2" class="leftBorder">&lt;/td>
			&lt;td>
				&lt;div class="centralArea" style="width: 260px; height: 260px;">&lt;/div>
			&lt;/td>
			&lt;td rowspan="2" class="rightBorder">&lt;/td>
		&lt;/tr>
		&lt;tr>
			&lt;td class="statusBar">&lt;div class="resize"/>&lt;/td>
		&lt;/tr>
		&lt;tr>
			&lt;td colspan="3" class="bottomBorder">&lt;/td>
		&lt;/tr>
	&lt;/tbody>
	&lt;/table>
&lt;/div>
</pre>
<p>Теперь дополним наш класс недостающими функциями:</p>
<pre class="prettyprint">
_destroy : function(){
	if ($type(this.handle) == 'element'){
		this.handle.destroy();
	}
	this.handle = null;
},

open : function(elem){
	if (!this.handle)
		this._create(elem);
},

close : function(){
	this._destroy();
},

up : function(){
	this.handle.setStyle('z-index', ++dWindowZIndex);
}
</pre>
<p>Здесь указаны упомянутые выше функции <strong>up()</strong> и <strong>close()</strong>, а также функция <strong>open()</strong>, которая проверят, создано ли окно или нет, ежели нет, то оно создается функцией <strong>_create()</strong>. Функция <strong>_destroy()</strong>, противоположная последней, закрывает окно, уничтожая экземпляр класса <strong>dWindow</strong>.</p>
<p>Следующим этапом нашей разработки будет создание таблиц стилей для окна. Не особо углубляясь в детали реализации CSS верстки, ибо она довольно таки тривиальна, я просто приведу окончательный её результат:</p>
<pre class="prettyprint">
.dWindow {
	background: #aaa;
	position:absolute;
	z-index:10000;
}

.dWindow .topBar{
	height: 20px;
	background: #bad0ee url('white-top-bottom.gif') repeat-x;
	border-left: 1px solid #84a0c4;
	border-right: 1px solid #84a0c4;
}

.dWindow .closeBtn {
	position: absolute;
	top: 3px;
	right: 3px;
	width: 16px;
	height: 16px;
	cursor: pointer;
	background: url('close.gif') no-repeat;
}

.dWindow td.leftBorder {
	width:2px;
	background:#fff url('border-left.gif') repeat-y;
	cursor:w-resize;
}

.dWindow td.rightBorder {
	width:2px;
	background:#fff url('border-right.gif') repeat-y;
	cursor:e-resize;
}

.dWindow td.bottomBorder {
	height:2px;
	background: #fff url('border-bottom.gif') repeat-x;
	cursor:s-resize;
}

.dWindow .centralArea {
	width: 200px;
	height: 200px;
	background: #fafafa;
	vertical-align: top;
	overflow: auto;
}

.dWindow td.statusBar {
	position: relative;
	height: 16px;
	background: #d5e4f5;
}

.dWindow .resize {
	position: absolute;
	width: 12px;
	height: 12px;
	right:2px;
	bottom:2px;
	background: #d5e4f5 url('resize.gif') no-repeat bottom right;
	cursor: se-resize;
	font-size:1px;
	line-height:0;
}

.dragging {
	cursor: move;
}
</pre>
<p>Теперь мы приступаем к последнему шагу нашего туториала &#8211; добавим возможность перетаскивать окна и изменять их размер. В <strong>Mootools</strong> есть классы <strong>Drag</strong> и <strong>Drag.Move</strong>, которые предназначены для создания перетаскиваемых элементов. Ими мы и воспользуемся.</p>
<p>Класс <strong>Drag.Move</strong>, помимо прочего, отличается от <strong>Drag</strong> тем, что он позволяет ограничивать перетаскивание объекта рамками некоторого элемента. Используя это свойство, мы будем использовать <strong>Drag.Move</strong> для главного контейнера окна для того, чтобы ограничить перетаскивание пределами страницы.</p>
<p>Итак, создаём новый объект <strong>Drag.Move</strong>, указав для него главный контейнер окна <strong>this.handle</strong> (делаем это все в функции <strong>_create()</strong>):</p>
<pre class="prettyprint">
this.drag = new Drag.Move(this.handle, {
    snap: 0,
    handle: bar,
	container: target,
    onSnap: function(el){
        el.addClass('dragging');
    },
    onComplete: function(el){
        el.removeClass('dragging');
    }
});
</pre>
<p>В качестве параметра <strong>handle</strong> используем строку заголовка окна (переменная <em>bar</em>), ибо, именно за него окно и будет перетаскиваться. В параметр <strong>container</strong> передаем указатель на элемент страницы, который будет ограничивать перетаскивание окна (если передать сюда <em>body</em>, то перетаскивание будет ограничиваться размерами страницы). Стандартные для <strong>Drag.Move</strong> обработчики <strong>onSnap</strong> и <strong>onComplete</strong> используем для того, чтобы изменять вид курсора при перетаскивании окна.</p>
<p>Закончив с перетаскиванием окна, поработаем с его границами, перетаскиванием которых можно будет изменять размеры окна. Это будет несколько более сложно сделать, поскольку при каждом движении границы, нужно будет пересчитывать размеры окна. Для этой цели идеально подходят события <strong>onSnap</strong> (захват мышкой за кромку) и <strong>onDrag</strong> (шаг при перетаскивании) класса <strong>Drag</strong>, который мы будем использовать для границ. Реализация изменения размера по вертикали (нижняя граница) показана в следующем фрагменте:</p>
<pre class="prettyprint">
var that = this;
this.bDrag = new Drag(bottomBorder, {
	onSnap : function(elem){
		that.dragParams.h = content.getSize().y;
		that.dragParams.H = that.handle.getSize().y;
		that.dragParams.target = content;
	},

	onDrag : function(elem){
		var delta = this.mouse.now.y - this.mouse.start.y;
		var h = that.dragParams.h + delta;
		var H = that.dragParams.H + delta;
		var targetPos = that.dragParams.target.getPosition();

		if (h < that.options.minHeight || (H + targetPos.y) > (window.getScrollTop() + window.getHeight())) {
			return;
		}
		that.dragParams.target.setStyle('height', h);
		that.handle.setStyle('height', H);
	}
});
</pre>
<p>Для изменения размера окна по вертикали, нам необходимо изменять высоту окна (<em>&lt;div class=&#8221;dWindow&#8221;></em> &#8211; переменная <em>handle</em>) и размер div-а для содержимого окна (<em>&lt;div class=&#8221;centralArea&#8221;></em> &#8211; переменная <em>content</em>). В обработчике <strong>onSnap</strong> мы получаем высоту этих двух элементов, а в <strong>onDrag</strong> определяем, на какое расстояние сместился курсор мыши (<em>delta</em>), и меняем высоту элементов на полученное значение. Условный оператор в <strong>onDrag</strong> добавлен для ограничения изменения размера в соответствии со значением <em>minHeight</em> (минимальная высота) и с размерами страницы.</p>
<p>Остальные границы делаем в том же ключе, за небольшим исключением левой границы, где помимо изменения ширины окна, нужно также изменять и положение окна на странице (<em>left</em>):</p>
<pre class="prettyprint">
var that = this;

// левая граница
this.lbDrag = new Drag(leftBorder, {
	onSnap : function(elem){
		that.dragParams.w = content.getSize().x;
		that.dragParams.W = that.handle.getSize().x;
		that.dragParams.pos = content.getPosition();
		that.dragParams.target = content;
	},

	onDrag : function(elem){
		var delta = this.mouse.now.x - this.mouse.start.x;
		var w = that.dragParams.w - delta;
		var W = that.dragParams.W - delta;
		var L = this.mouse.start.x + delta;
		if (w < that.options.minWidth || L < target.getPosition().x) {
			return;
		}
		that.dragParams.target.setStyle('width', w);
		that.handle.setStyle('width', W);
		that.handle.setStyle('left', L);
	}
});

// правая граница
this.rbDrag = new Drag(rightBorder, {
	onSnap : function(elem){
		that.dragParams.w = content.getSize().x;
		that.dragParams.W = that.handle.getSize().x;
		that.dragParams.target = content;
	},

	onDrag : function(elem){
		var delta = this.mouse.now.x - this.mouse.start.x;
		var w = that.dragParams.w + delta;
		var targetPos = that.dragParams.target.getPosition();

		if (w < that.options.minWidth || (W + targetPos.x) > (window.getScrollLeft() + window.getWidth())) {
			return;
		}

		var W = that.dragParams.W + delta;
		that.dragParams.target.setStyle('width', w);
		that.handle.setStyle('width', W)
	}
});
</pre>
<p>Ну и последний элемент, это ползунок в правом нижнем углу, который позволяет одновременно изменять размер окна и по вертикали и по горизонтали. Принцип действия тот же самый что и для правой и нижней границы, только выполняется одновременно:</p>
<pre class="prettyprint">
var that = this;
this.resizeDrag = new Drag(brResize, {
	preventDefault: true,
	style: false,
	onSnap : function(elem){
		that.dragParams.h = content.getSize().y;
		that.dragParams.H = that.handle.getSize().y;
		that.dragParams.w = content.getSize().x;
		that.dragParams.W = that.handle.getSize().x;
		that.dragParams.target = content;
	},

	onDrag : function(){
		var deltay = this.mouse.now.y - this.mouse.start.y;
		var deltax = this.mouse.now.x - this.mouse.start.x;
		var h = that.dragParams.h + deltay;
		var H = that.dragParams.H + deltay;
		var w = that.dragParams.w + deltax;
		var W = that.dragParams.W + deltax;
		var targetPos = that.dragParams.target.getPosition();

		if (h < that.options.minHeight || (H + targetPos.y) > (window.getScrollTop() + window.getHeight())
			|| w < that.options.minWidth || (W + targetPos.x) > (window.getScrollLeft() + window.getWidth())) {
			return;
		}

		that.dragParams.target.setStyle('height', h);
		that.handle.setStyle('height', H);
		that.dragParams.target.setStyle('width', w);
		that.handle.setStyle('width', W);
	}
});
</pre>
<p>Вот собственно и все, окно готово. Создание экземпляра окна выглядит так:
<pre class="prettyprint">
// содержимое окна
var sText = '&lt;p class="para">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.&lt;/p>';

window.addEvent('domready', function(){
	// создаем окно
	var w = new dWindow({
		width:250,
		height:180,
		minWidth:170,
		minHeight:100,
		content: sText
	});
	// добавляем его на страницу
	w.open($(document.body));
});
</pre>
<p>Посмотреть как все это работает можно на демо примере, где показано создание множество окон по щелчку на ссылку.<br/>На сегодня это все. Буду признателен за конструктивную критику <img src='http://www.jstoolbox.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <br/>Удачи!</p>
<p><br/><br />
<a href="http://www.jstoolbox.com/demo/dWindows/index.php" class="demo" title="Демо окон на Mootools">смотреть демо</a><a href="http://www.jstoolbox.com/download/dWindows.zip" class="download" style="margin-left:18px">скачать</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2008/09/23/okna-mootools/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Туториал &#8211; приложение FAQ на jQuery</title>
		<link>http://www.jstoolbox.com/2008/05/12/tutorial-prilozhenie-faq-na-jquery/</link>
		<comments>http://www.jstoolbox.com/2008/05/12/tutorial-prilozhenie-faq-na-jquery/#comments</comments>
		<pubDate>Mon, 12 May 2008 21:55:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Уроки]]></category>
		<category><![CDATA[scrollbars]]></category>
		<category><![CDATA[туториал]]></category>
		<category><![CDATA[урок]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/2008/05/12/tutorial-prilozhenie-faq-na-jquery/</guid>
		<description><![CDATA[В этом туториале я рассмотрю пример создания приложения FAQ (часто задаваемые вопросы), в котором вопросы и ответы будут располагаться в двух расположенных рядом контейнерах с полосами прокрутки. Вместо стандартных полос прокрутки я создам собственный дизайн, а прокручивание сделаю плавным, плюс добавлю меню-аккордеон со списком вопросов.
Окончательный результат будет работать следующим образом: смотреть.
Для создания полос прокрутки я [...]]]></description>
			<content:encoded><![CDATA[<p>В этом туториале я рассмотрю пример создания приложения FAQ (часто задаваемые вопросы), в котором вопросы и ответы будут располагаться в двух расположенных рядом контейнерах с полосами прокрутки. Вместо стандартных полос прокрутки я создам собственный дизайн, а прокручивание сделаю плавным, плюс добавлю меню-аккордеон со списком вопросов.</p>
<p>Окончательный результат будет работать следующим образом: <a href="/demo/faq/faq.html" rel="nofollow">смотреть</a>.</p>
<p>Для создания полос прокрутки я буду применять плагин <a href="http://kelvinluck.com/assets/jquery/jScrollPane/">jScrollPane</a>, который в свою очередь требует <a href="http://brandonaaron.net/docs/dimensions/">jquery.dimensions.js</a>, а также <a href="http://plugins.jquery.com/project/mousewheel">jquery.mousewheel.js</a> чтобы можно было прокручивать список при помощи колесика мышки.</p>
<p><span id="more-128"></span></p>
<p>Для начала скачайте дистрибутив <a href="http://www.kelvinluck.com/assets/jquery/jScrollPane/jScrollPane.html">jScrollPane</a> и распакуйте его в папку с вашим приложением. Затем создайте HTML документ в который подключите библиотеку jQuery и затем три вышеперечисленных скрипта, которые входят в состав дистрибутива jScrollPane:</p>
<pre class="prettyprint">
&lt;script type="text/javascript" src="js/jquery.js">&lt;/script>
&lt;script type="text/javascript" src="js/jquery.dimensions.min.js">&lt;/script>
&lt;script type="text/javascript" src="js/jquery.mousewheel.min.js">&lt;/script>
&lt;script type="text/javascript" src="js/jScrollPane.js">&lt;/script>
</pre>
<p>Далее подключаем необходимые CSS файлы &#8211; jScrollPane.css, который содержит стили полос прокрутки, и style.css &#8211; файл в котором я буду указывать все остальные стили на странице:</p>
<pre class="prettyprint">
&lt;link rel="stylesheet" type="text/css" media="all" href="css/style.css" />
&lt;link rel="stylesheet" type="text/css" media="all" href="css/jScrollPane.css" />
</pre>
<p>Теперь можно собственно приступать к созданию нашего ЧаВО. Чтобы обеспечить принцип &#8220;ненавязчивости&#8221; для скрипта (пользователь должен иметь возможность пользоваться ЧаВО даже если JavaScript не включен), заголовки ответов, которые будут находиться в правой части, заключим в ссылки типа <strong>&lt;a name=&#8221;h_b_1&#8243;>ответ&lt;/a></strong> переход к которым будем осуществлять ссылками вида <strong>&lt;a href=&#8221;#h_b_1&#8243;>Q: вопрос .. ?&lt;/a></strong>.</p>
<p>Общая структура выглядит следующим образом:</p>
<pre class="prettyprint">
&lt;div id="container">
	&lt;div id="title">Часто задаваемые вопросы (ЧаВо)&lt;/div>
	&lt;div id="left_pane">
		&lt;div class="scrollable">
		&lt;h6 class="opened">Общая информация (заголовок раздела)&lt;/h6>
			&lt;ul>
			&lt;li>&lt;a href="#a_i_1">Q: Какой то вопрос?&lt;/a>&lt;/li>
			....
			&lt;/ul>
		....
		&lt;/div>
	&lt;/div>

	&lt;div id="right_pane">
		&lt;div class="scrollable">
		&lt;h4>Общая информация&lt;/h4>
		&lt;p class="question">&lt;a name="a_i_1">Q: Какой то вопрос?&lt;/a>&lt;br/>
		A: Некоторый ответ.&lt;/p>
		....
		&lt;/div>
	&lt;/div>

	&lt;br style="clear:both" />
&lt;/div>
</pre>
<p>Див с id=container размещаем посреди страницы, указывая для него width и margin, а левый и правый контейнеры для вопросов и ответов располагаем при помощи float. Div с классом <strong>scrollable</strong> используется как контейнер с прокруткой, для него ставим overflow:auto. В общем содержимое файла style.css будет следующим:</p>
<pre class="prettyprint">
body {
	font-size: 12px;
	font-family: Georgia, Arial, Verdana, sans-serif;
}

h6 {
	font-size: 12px;
	font-weight: bold;
	margin: 4px 0;
	cursor: pointer;
}

#container {
	width:780px;
	margin: 20px auto;
	background: #fff;
	border: 1px solid #aaa;
}

#title {
	padding: 6px 0;
	text-align: center;
	font-size: 20px;
}

#left_pane,
#right_pane {
	border: 1px solid #aaa;
}

.scrollable {
	width: 370px;
	height: 350px;
	overflow: auto;
}

.scrollable ul {
	position: relative;
}

#left_pane {
	float: left;
	margin: 10px 0 10px 10px;
}
#right_pane {
	float: right;
	margin: 10px 10px 10px 0;
}

.question a {font-style:italic}
</pre>
<p>На этом этапе приложение выглядит следующим образом: <a href="/demo/faq/faq2.html">смотреть</a>.</p>
<p>Теперь наведем немного красоты &#8211; создадим меню аккордеон:</p>
<pre class="prettyprint">
$(document).ready(function(){
	$('#left_pane h6').each(function(i){
		if(i!=0){
			$(this).next().hide();
			$(this).attr('class','closed');
		}
		$(this).click(function(){
			if ($(this).hasClass('opened'))
				return;

			// закрываем все подменю
			$('#left_pane h6.opened').each(function(){
				$(this).attr('class','closed');
				$(this).next().slideUp();
			});

			// открываем меню, на котором щелкнул пользователь
			$(this).attr('class','opened');
			$(this).next().slideDown('slow');
		});
	});
});
</pre>
<p>В самом начале мы закрываем все подменю при помощи функции <strong>slideUp()</strong>, оставляя открытым только первое (используем аргумент <strong>i</strong> в функции <strong>each</strong> для получения индекса). Подменю будет открываться/закрываться при нажатии на заголовке (тег <strong>h6</strong>) при помощи функций <strong>slideUp()</strong> и <strong>slideDown()</strong>, при этом открытому меню будет присваиваться класс <strong>opened</strong>, а закрытому &#8211; <strong>closed</strong>.</p>
<p>Следующий шаг &#8211; создание полос прокрутки. Для этого добавляем вызов функции <strong>jScrollPane()</strong>:</p>
<pre class="prettyprint">
$('.scrollable').jScrollPane({animateTo:true, showArrows:true, scrollbarWidth:11});
</pre>
<p>Здесь параметр <strong>animateTo</strong> указывает на то что нужно использовать анимацию при последующих вызовах <strong>scrollTo()</strong>, <strong>showArrows</strong> &#8211; для отображения стрелок вверху и внизу полосы прокрутки, <strong>scrollbarWidth</strong> устанавливает ширину полосы прокрутки.</p>
<p>И последнее, плавное прокручивание к нужному месту обеспечиваем при помощи следующей функции:</p>
<pre class="prettyprint">
$('#left_pane li a').click(function(event){
	var target = $('#right_pane a[name='+$(this).attr('href').replace('#','')+']');
	var cont = $('#right_pane .scrollable');
	var p = target.parent();
	var h = parseInt(p[0].offsetTop);
	cont[0].scrollTo(h);

	event.preventDefault();
	});
</pre>
<p>Указатель на тег с ответом мы получаем из атрибута <strong>href</strong> ссылки, затем определяем координату этого элемента по вертикали при помощи <strong>offsetTop()</strong> и затем плавное прокручивание функцией <strong>scrollTo()</strong>.</p>
<p>Окончательный код выглядит следующим образом:</p>
<pre class="prettyprint">
$(document).ready(function(){
	$('#left_pane h6').each(function(i){
		if(i!=0){
			$(this).next().hide();
			$(this).attr('class','closed');
		}
		$(this).click(function(){
			if ($(this).hasClass('opened'))
				return;

			$('#left_pane h6.opened').each(function(){
				$(this).attr('class','closed');
				$(this).next().slideUp();
			});

			$(this).attr('class','opened');
			$(this).next().slideDown('slow');

			$('#left_pane .scrollable').jScrollPane({animateTo:true, showArrows:true, scrollbarWidth:11});

		});
	});

	$('.scrollable').jScrollPane({animateTo:true, showArrows:true, scrollbarWidth:11});

	$('#left_pane li a').click(function(event){
		var target = $('#right_pane a[name='+$(this).attr('href').replace('#','')+']');
		var cont = $('#right_pane .scrollable');
		var p = target.parent();
		var h = parseInt(p[0].offsetTop);
		cont[0].scrollTo(h);

		event.preventDefault();
	});
});
</pre>
<p>Обратите внимание, что вызов функции <strong>jScrollPane()</strong> добавлен дополнительно в функцию, реализующую меню. Это сделано для того, чтобы полоса прокрутки появлялась только в том случае, если открывшееся меню будет больше видимой части контейнера.</p>
<p>И последнее &#8211; подкорректируем дизайн полосы прокрутки, редактируя файл <strong>jScrollPane.css</strong>. На следующей картинке указано, какие стили в нем нужно редактировать:</p>
<div style="width:250px;margin:10px auto"><img src='http://www.jstoolbox.com/wp-content/uploads/2008/05/scrollbar_scheme.png' alt='Стили для редактирования полос прокрутки' /></div>
<p>Всё, приложение готово.</p>
<p>P.S.: текст FAQ в демо примере взят на одном из сайтов, которые я недавно разрабатывал, ибо &#8220;Lorem Ipsum&#8221; уже несколько поднадоел.</p>
<p><a href="/demo/faq/faq.html" class="demo">смотреть демо</a><a href="/download/faq.zip" class="download" style="margin-left:18px">загрузить пример</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2008/05/12/tutorial-prilozhenie-faq-na-jquery/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss>
