Пример JavaScript-компонента с использованием ООП
Автор: Анна Черножукова
После того, как мы ознакомились с классами в Motools, можно (и нужно) рассмотреть конкретный пример.
Пусть на странице есть div, внутри него текст, который не должен превышать 20px в высоту. Если текст не умещается в эту высоту, то его нужно скрыть до нужной высоты и в конце видимой части текста добавить ссылку «…more». Щелкаем по ссылке — видим текст целиком.
Итак, на странице есть нужный div:
<div id="detlongDescription" style="width:500px">За последние десятилетия интерес к артистам, практикующим искусство голодания, сильно упал. И если раньше было очень даже выгодно устраивать крупные представления подобного рода за собственные средства, то сегодня это совершенно невозможно. Тогда были другие времена.</div>
Напишем mootools-класс, который будет получать в конструктор id того блока, в котором находится текст и обрабатывать его.
Приступим теперь к реализации компонента. Создаем свой класс, назовем его SLDescription. Как это будет работать:
1. Создается экземпляр класса: вызывается конструктор initialize, куда передаем id блока с нужным текстом. Так же в конструкторе инициализируются дополнительные свойства класса: высота блока (у нас это 20px), которую не должен превышать div с текстом, и текст ссылки на полный вариант текста.
2. На загрузку страницы у созданного объекта вызывается метод start(). Здесь происходит следующее:
— определяются координаты блока с текстом на странице и проверяется, превышает ли он допустимую высоту (ту, что определили в конструкторе);
— если не превышает, то ничего не делаем;
— если блок превышает указанную высоту, то сохраняем полный текст в некоторое поле объекта, также разбиваем текст внутри блока на слова и храним эти слова в виде массива. Затем содержимое блока очищается. Далее сокращенный вариант текста собирается по одному слову до достижения нужной высоты. Здесь есть одна особенность. Нам нужно, чтобы в нужную высоту вписался часть текста вместе со ссылкой на полный вариант, поэтому вначале к div’у добавляется новое слово + название ссылки. Затем проверяется, не достигли ли мы нужной высоты. Если достигли, то на этом выходим из цикла по массиву слов, а если не достигли, то добавляем только слово из массива к сокращенному тексту (не забываем, что кроме слов нужно восстанавливать пробелы между ними).
Выйдя из цикла, помещаем внутрь div’a сокращенный текст + ссылку.
Реализуем сначала упрощенный вариант нашего алгоритма. Считаем, что не нужна нам пока никакая ссылка и никакой полный вариант текста тоже пока не нужен, а будем добавлять в конце сокращенного текста только надпись «…more». Итак, приступаем к написанию класса:
var SLDescription = new Class({
initialize: function(divId) {
//задаем свойства объекта
this.divId=divId;
//задаем высоту блока с текстом
this.baseHeight=20;
this.moreText = "...more";
},
start:function() {
var coordinates=null;
//получаем фактические координаты div'а
coordinates= $(this.divId).getCoordinates();
//разделяем текст на массив слов
var splitText=$(this.divId).innerHTML.split(' ');
$(this.divId).innerHTML='';
var limit=true;
var i=0; //количество показанных слов
var text="";
this.shortText="";
//собираем сокращенный вариант текста по словам
for( i=0; ithis.baseHeight){
limit=false;
// превысили высоту div'а, поэтому заканчиваем цикл
}
else {
this.shortText=text;
}
}
// помещаем сокращенный текст внутрь элемента
$(this.divId).innerHTML=this.shortText;
// если закончили текст раньше,
// чем закончились слова в массиве,
// то добавляем к тексту еще надпись
if (i<splitText.length)
$(this.divId).innerHTML+=this.moreText;
}
}).
До сих пор нигде не встречалась конструкция $(...). На самом деле выражение $('elemId') в Mootools возвращает ссылку на элемент в DOM, у которого id='elemId'. Это тоже самое, что и document.getElementById('elemId'). Кроме того, еще мы вызываем такие методы у элемента, как getStyle(...) и getCoordinates(...), но останавливаться подробно на них не будем, т.к. очевидно, что они делают. Более подробные сведения и описание вообще всех методов элементов в Mootools можно найти на сайте с документацией по Mootools.
Теперь усложним наш класс. Будем теперь добавлять в конце текста именно ссылку, при щелчке по которой будет появляться весь текст целиком. В предыдущем варианте мы нигде не сохраняли первоначальный текст, т.к. не требовалось его показывать на странице. Теперь же прежде, чем разбивать текст на слова и выполнять дальнейшие действие, необходимо сохранить текст в его первоначальном виде. Для этого немного исправим метод start, заменив
...
var splitText=$(this.divId).innerHTML.split(' ');
...
на
...
this.longText=$(this.divId).innerHTML;
var splitText=this.lingText.split(' ');
...
Также вместо
...
if (i<splitText.length)
$(this.divId).innerHTML+=this.moreText;
...
появится
...
if (i<splitText.length)
this.addMore();
...
Теперь вместо того, чтобы просто добавить в конце текста только надпист «…more», будет вызываться метод, добавляющий ссылку «…more» на полный текст. Дописываем к нашему классу метод addMore:
...
addMore:function(){
//создаем новый элемент в DOM
var a = new Element('a', {
href: "javascript:;"
});
//добавляем событие к элементу
a.addEvent('click', this.more.bind(this));
//добавляем название ссылки
a.appendText(this.moreText);
//вставляем элемент внурь div'а
a.injectInside($(this.divId));
},
...
Здесь поясним несколько моментов. Сначала мы с помощью специального объекта Mootools создаем новый элемент в DOM — ссылку, и указываем ее атрибут href. Затем, также с помощью функций Mootools, мы добавляем к созданному элементу событие onclick. Вообще метод addEvent принимает 2 параметра: тип события — строка с названием события без приставки on, и функция, вызываемая на это событие. В нашем случае, при нажатии на ссылку будет вызываться функция more() (её описание см. ниже), в которой переменная this будет ссылаться не на ссылку, а на экземпляр нашего класса SLDescription.
Поясним еще как работает метод injectInside(element). В нашем случае этот метод вставляет ссылку внутрь элемента с указанным id. Ссылка при этом допишется в конец содержимого element.
Наконец добавляем последний метод, который возвращает первоначальный текст (та самая функция, которая вызывается по щелчку на ссылке)
...
more:function(){
$(this.divId).innerHTML=this.longText;
}
}) //закрывающие скобки для всего класса
Замечание: Рассмотрим такую ситуацию
element.addEvent('click', fn1);
...
element.addEvent('click', fn2);
Возникает вопрос, какая функция вызовется на событие onclick. Правильный ответ — обе, т.к. события addEvent добавляет функцию к уже имеющимся, которые будут вызываться на обработку события.
Добавляем на страницу ссылку на скрипт, создание объекта и SLDescription и вызов у него метода start():
<script type="text/javascript" src="mootools.js"></script>
<script type="text/javascript" src="text_description.js"></script>
<script type="text/javascript">
var desc=new SLDescription("detlongDescription");
window.addEvent('load', function(){
desc.start();
});
</script>
Готово. Теперь все заработает так, как задумали вначале.
Полный текст скрипта text_description.js.
Метки: JavaScript


Copyright © 19992010 LAR