<?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/oop/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>Работа с классами в Mootools</title>
		<link>http://www.jstoolbox.com/2008/06/09/rabota-s-klassami-v-mootools/</link>
		<comments>http://www.jstoolbox.com/2008/06/09/rabota-s-klassami-v-mootools/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 21:53:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MooTools]]></category>
		<category><![CDATA[ООП]]></category>
		<category><![CDATA[классы]]></category>
		<category><![CDATA[наследование]]></category>
		<category><![CDATA[слайдшоу]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/2008/06/09/rabota-s-klassami-v-mootools/</guid>
		<description><![CDATA[В одной из прошлых статей я писал об основах программирования с использованием Mootools, а именно о работе с элементами и событиями. В этом уроке речь пойдет о несколько более сложной теме &#8211; объектно-ориентированном программировании, в частности о создании классов и объектов, а также о наследовании. В качестве примера я покажу процесс создания класса SlideShow (для [...]]]></description>
			<content:encoded><![CDATA[<p>В одной из прошлых <a href="http://www.jstoolbox.com/2008/04/18/mootools-dlya-nachinayushhix-rabota-s-elementami-i-sobytiyami/">статей</a> я писал об основах программирования с использованием <a href="http://mootools.net">Mootools</a>, а именно о работе с элементами и событиями. В этом уроке речь пойдет о несколько более сложной теме &#8211; объектно-ориентированном программировании, в частности о создании классов и объектов, а также о наследовании. В качестве примера я покажу процесс создания класса SlideShow (для отображения слайдов) и двух его дочерних классов &#8211; ImageSlideShow (для показа изображений) и RssSlideShow (для показа лент новостей).</p>
<p><span id="more-148"></span></p>
<p>Для начала немного теории. Новые классы в Mootools создаются при помощи класса <strong>Class</strong>, который принимает один аргумент &#8211; свойства (properties):</p>
<pre class="prettyprint">
var newCls = new Class(properties);
</pre>
<p>В качестве свойств могут передаваться три специльных свойства &#8211; функция <strong>initialize</strong>, явлющаяся конструктором класса, <strong>Extend</strong>, для реализации наследования, и <strong>Implement</strong> &#8211; для заимствования свойств других объектов или классов.</p>
<p>Итак, создаем каркас нашего приложения-слайдшоу:</p>
<pre class="prettyprint">
var SlideShow = new Class({
	options: {
		slides : [],
		startIndex : 0,
		wrap : true
	},

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

	// заимствуем методы классов Options и Events
	Implements : [Options, Events]
});
</pre>
<p>При помощи свойства <strong>Implements</strong> мы заимствуем методы классов <strong>Options</strong> и <strong>Events</strong>, которые доступны в библиотеке Mootools. Метод <strong>setOptions()</strong> класса <strong>Options</strong> используется в конструкторе <strong>initialize</strong> для установки значений опций <strong>options</strong>. В данном случае в качестве опций мы указываем на массив слайдов в структуре DOM (например так: $$(&#8217;slides&#8217;)), индекс слайда, с которого начинать показ, и значение <strong>wrap</strong>, указывающего на цикличность показа слайдов. Такой шаблон можно использовать для создания подавляющего большинства классов в Mootools.</p>
<p>Далее мы добавим функции, которые будут управлять работой слайдшоу &#8211; добавлять и поочередно показывать слайды:</p>
<pre class="prettyprint">
var SlideShow = new Class({
	options: {
		slides : [],
		startIndex : 0,
		wrap : true
	},

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

		this.slides = [];
		this.addSlides(this.options.slides);

		if (this.slides.length)
			this.showSlide(this.options.startIndex);
	},

	Implements : [Options, Events],

	/**
	 * Добавление слайдов в слайдшоу
	 */
	addSlides: function(slides){
		$$(slides).each(function(slide){
			this.slides.include($(slide));
			slide.addEvent('click', this.cycleForward.bind(this));
		}, this);
	},

	/**
	 * Добавление одного слайда
	 */
	addSlide: function(slide){
		this.addSlides([slide]);
	},

	/**
	 * Прокрутка слайдов вперед
	 */
	cycleForward: function(event){
		if($chk(this.now) &amp;&amp; this.now &lt; this.slides.length-1)
			this.showSlide(this.now+1);
		else if (this.now &amp;&amp; this.options.wrap)
			this.showSlide(0);
		else if(!$defined(this.now))
			this.showSlide(this.options.startIndex);
	},

	/**
	 * Прокрутка слайдов назад
	 */
	cycleBack: function(){
		if(this.now > 0)
			this.showSlide(this.now-1);
		else if(this.options.wrap)
			this.showSlide(this.slides.length-1);
	},

	/**
	 * Показ слайда
	 */
	showSlide: function(iToShow){
		var now = this.now;
		var current = this.slides[now];
		var slide = this.slides[iToShow];
		if(slide){
			if($chk(now) &amp;&amp; now != iToShow){
				var hideEffect = new Fx.Morph(current, {duration: 'long'});
				hideEffect.start({'opacity':0}).chain(
					function(){
						current.setStyle('display','none');
						slide.setStyles({
							'display':'block',
							'opacity':'0'
						});
						var showEffect = new Fx.Morph(slide, {duration: 'long'});
						showEffect.start({'opacity':1});
					}.bind(this)
				);
			} else {
				slide.setStyle('display','block');
			}
		}
		this.now = iToShow;
	}
});
</pre>
<p>Здесь мы добавили пять новых функций &#8211; <strong>addSlide()</strong> и <strong>addSlides()</strong> для добавления одного и группы слайдов в список отображения, <strong>cycleForward()</strong> и <strong>cycleBack()</strong> для просмотра следующего (предыдущего) слайда, и <strong>showSlide()</strong> для показа слайда (здесь используется эффект <a href="http://www.jstoolbox.com/2008/04/22/morfing-na-mootools/">Fx.Morph</a> для плавного появления слайдов). В функци <strong>addSlides()</strong> мы добавляем обработчик <strong>cycleForward()</strong> для события onclick, следовательно переход от слайда к слайду будет осуществляться по щелчку мыши на нем. В конструктор же добавляем вызов функции <strong>showSlide()</strong> для того, чтобы после создания объекта класса сразу показать первый слайд.</p>
<p>В итоге мы получили вполне работоспособный класс. Создаём объект класса:</p>
<pre class="prettyprint">
window.addEvent('domready', function(){
	new SlideShow({
		slides: $$('div.slide')
	});
});
</pre>
<p>Здесь в качестве слайдов выступают несколько div-ов с атрибутом class=&quot;slide&quot;. Посмотреть демо этого примера можно <a href="http://www.jstoolbox.com/demo/slideshow/slideshow.html">здесь</a>.</p>
<p>Теперь рассмотрим пример создания дочернего класса ImageSlideShow для создания слайдшоу изображений. Класс мы будем создавать точно также, только вместо свойства <strong>Implements</strong> (его исользовать не нужно, так как методы классов Options и Events будут наследоваться от SlideShow), будем использовать свойство <strong>Extends</strong>, указывающее на родительский класс:</p>
<pre class="prettyprint">
var ImageSlideShow = new Class({
	options: {
		imgUrls: [], // URL изображений
		container: false // ID контейнера
	},

	Extends : SlideShow,

	initialize: function(options){
		this.parent(options);
		// получаем ссылку на контейнер
		this.container = $(this.options.container);
		if(!this.container) {
			return;		// нет такого контейнера, завершаем работу
		}
		this.options.imgUrls.each(this.addImg.bind(this));
		this.showSlide(this.options.startIndex);
	},

	/**
	 * Добавление изображений в контейнер
	 */
	addImg: function(url){
			var img = new Element('img', {
				src: url,
				styles: {
					display: 'none'
				}
			}).injectInside($(this.options.container))
		this.addSlide(img);
	}
});
</pre>
<p>В этом классе нам не нужно заново объявлять функции <strong>addSlide()</strong> или <strong>showSlide()</strong>, так как они наследуются от класса <strong>SlideShow</strong>. <strong>ImageSlideShow</strong> в отличии от <strong>SlideShow</strong> будет принимать в качестве аргументов массив URL-ов изображений и ID контейнера, в который нужно добавлять слайды. В свою очередь слайды будут создаваться и добавляться в контейнер динамически при помощи функции <strong>addImg()</strong>.</p>
<p>Демо этого примера смотрите <a href="http://www.jstoolbox.com/demo/slideshow/imageslideshow.html">здесь</a>.</p>
<p>Ну и наконец последний, более практичный на мой взгляд пример, демонстрирующий создание виджета, который показвает слайдшоу последних новостей, получаемых через RSS. Содержимое ленты новостей будем получать через прокси скрипт <strong>rssproxy.php</strong> посредством AJAX, а слайды будем прокручивать автоматически используя функцию <strong>setInterval()</strong>.</p>
<pre class="prettyprint">
var RssSlideShow = SlideShow.extend({
	options : {
		rssUrl : '',
		container : false
	},

	interval : null,	// интервал слайдшоу (setInterval)

	initialize : function(options){
		this.parent(options);
		this.container = $(this.options.container);
		if (!this.container) {
			return;
		}
		this.initChannel();
	},

	/**
	 * Получение канала rss через прокси rssproxy.php,
	 * в параметре get указываем URL канала
	 */
	initChannel : function(){
		if (!this.options.rssUrl || this.options.rssUrl == '') {
			return;
		}

		// получаем содержимое ленты новостей используя AJAX
		var request = new Request({
			url : 'rssproxy.php?get='+encodeURI(this.options.rssUrl),
			method : 'post',
			onSuccess : this.addNews.bind(this)
		}).send();

	},

	/**
	 * Добавление слайдов с новостями в контейнер
	 */
	addNews : function(txt, xml) {
		var items = xml.getElementsByTagName('item');
		for (var i=0, len=items.length; i &lt; len; i++){
			var title = items[i].getElementsByTagName('title')[0];
			var desc = items[i].getElementsByTagName('description')[0];
			var slide = new Element('div', {
					'class': 'rssSlide',
					styles: {
						display: 'none'
					}
				});
			slide.setHTML('&lt;h4>'+title.firstChild.nodeValue+'&lt;/h4>&lt;p>'+desc.firstChild.nodeValue+'&lt;/p>');
			slide.injectInside(this.container)
			this.addSlide(slide);
		}
		this.start();
	},

	/**
	 * Запуск слайдшоу
	 */
	start : function(){
		this.showSlide(this.options.startIndex);
		var that = this;
		this.interval = setInterval(function(){that.cycleForward()}, 10000);
	},

	/**
	 * Остановка слайдшоу
	 */
	stop : function(){
		clearInterval(this.interval);
	}
});
</pre>
<p>Здесь, вместо свойства <strong>Extends</strong> я использую функцию <strong>SlideShow.extends()</strong>, просто чтобы показать еще один способ наследования классов. Класс <strong>RssSlideShow</strong> принимает два аргумента &#8211; URL ленты новостей и ID контейнера для слайдов. Автопрокрутку слайдов обеспечиваем при помощи двух простых функций <strong>start()</strong> и <strong>stop()</strong>, которые используют <strong>setInterval()</strong> с параметром задержки равным 10 секунд. Функция <strong>initChannel()</strong>, которая вызывается из конструктора, выполняет AJAX запрос к серверу, а полученный ответ адресует в функцию <strong>addNews()</strong>, которая парсит полученную RSS ленту, создаёт слайды и добавляет их в контейнер.</p>
<p>Демо RssSlideShow доступно <a href="http://www.jstoolbox.com/demo/slideshow/rssslideshow.html">здесь</a>.</p>
<h4>Заключение</h4>
<p>Из представленных выше примеров хорошо видно, насколько просто и удобно работать с классами в Mootools. Самое главное &#8211; это определиться со свойствами и методами, общими для всех классов в иерархии, а дальнейшее их наследование чрезвычайно просто выполняется посредством функции <strong>extend()</strong>. Использование же свойства <strong>Implements</strong> (или функции <strong>implement</strong>), позволяет наделить ваши классы множеством полезных функций и свойств, доступных в богатой коллекции библиотеки Mootools.</p>
<p><a href="http://www.jstoolbox.com/download/slideshow.zip" class="download">скачать примеры</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2008/06/09/rabota-s-klassami-v-mootools/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
