Уроки Mootools – Урок 3 – Массивы


А если вы еще не в курсе, во нашем втором уроке о Mootools, мы говорили об основах этой библиотеки, о селекторах в Mootools. Мы также обсуждали селекторы, которые в своих результатах возвращали массивы данных (если кто не знает, в чем я конечно сомневаюсь, массивы – это специальные списки данных, организованные таким образом, чтобы давать пользователю обширные возможности по их управлению). Сегодня мы рассмотрим то, как использовать массивы, чтобы манипулировать элементами DOM-а.

Основы

.each();

.each(); – это ваш лучший друг при работе с массивами; это лучший способ применять любую функцию к каждому элементу массива. Например, скажем существует необходимость создать предупреждение alert(); для каждого div-а на странице:

$$('div').each(function() {
	alert('ДИВик');
});

А с таким кодом HTML предыдущий код показал бы два предупреждения, по одному на каждый div.

<div>Один</div>
<div>Два</div>

.each(); не обязывает к использованию $$. Другой метод создания массива (как мы и говорили на прошлом уроке), это использование .getElements();.

$('body_wrap').getElements('div').each(function() {
	alert('ДИВик');
});

<div id="body_wrap">
	<div>Первый</div>
	<div>Второй</div>
</div>

Еще одни способ выполнить ту же задачу, это назначить массив переменной, после чего применить к ней метод .each();

//вначале следует объявить переменную с помощью ключевого слова var:
//"var ИМЯ_ПЕРЕМЕННОЙ_ЛАТИНСКИМИ_БУКВАМИ"
//за которым последует символ "=", который и определяет данные объявленной переменной,
//в нашем случае, это массив элементов div
 
var myArray = $('body_wrap').getElements('div');
//теперь можно использовать эту переменную с массивом также,
//как и селектор массивов, рассмотренный ранее
 
myArray.each(function() {
	alert('ДИВик');
});

После всего этого, может потребоваться отделить вашу функцию от селектора и от метода .each();. Для этого, мы рассмотрим более детально создание функции в следующем уроке, а пока будет достаточно и той простенькой, которую мы сейчас создадим:

var myArray = $('body_wrap').getElements('div');
 
//чтобы создать новую функцию, нужно, также, как и в случае с переменными,
// объявить переменную, дав ей имя
//а после знака равно, нужно ввести ключевое слово "function()",
//чтобы объявить, что переменная – это функция
//после чего нужно поместить код функции в фигурные скобки ("{...}")
 
var myFunction = function() {
	alert('ДИВик');
};
//а далее нужно просто вызвать функцию внутри метода .each();.
 
myArray.each(myFunction);

Примечание: При вызове функции так, как мы это сделали в методе .each();, имя функции заключать в кавычки не нужно!

Копирование массива

$A

Библиотека Mootools предоставляет разработчикам простой способ копирования массивов с помощью функции $A. Давайте назначим массив переменной, как мы это сделали выше:

//создайте свою переменную с массивом
 
var myArray = $('body_wrap').getElements('div');

Для копирования массива нужно:

//создать новую переменную и скопировать в нее массив "myArray"
 
var myCopy = $A(myArray);

Теперь переменная myCopy содержит теже элементы, что и переменная myArray.

Выбор определенного элемента в массиве

.getLast();

.getLast(); вернет последний элемент массива. После создания массива:

var myArray = $('body_wrap').getElements('div');

можно выбрать его последний элемент.

var lastElement = myArray.getLast();

Переменная lastElement теперь является последним элементом массива myArray.

.getRandom();

Работает аналогично методу .getLast();, за исключением того, что произвольно выбирает элемент массива.

var randomElement = myArray.getRandom();

Переменная randomElement теперь является произвольно выбранный элемент массива myArray.

Добавить элемент к массиву

.include();

С помощью этого метода можно легко добавлять элементы в массив. Все, что нужно сделать, это вставить необходимый элемент в скобки метода .include(); и присоединить всю конструкцию к массиву. С помощью следующего HTML кода

<div id="body_wrap">
	<div>первый</div>
	<div>второй</div>
   	<span id="add_to_array">добавить в массив</span>
</div>

можно создать такой же массив, как мы создавали и чуть выше, вызвав все divы, находящиеся в элементе ‘body_wrap’.

var myArray = $('body_wrap').getElements('div');

Чтобы добавить элемент в уже соществующий массив, вначале нужно назначить для этого элемента переменную, а потом уже использовать метод .include();.

//вначале определяем переменную для элемента, который хотим добавить в массив
 
var newToArray = $('add_to_array');
 
//после чего добавляем переменную в массив
 
myArray.include(newToArray);

А теперь в нашем массиве находятся все элементы div и span.

.combine();

Этот метод работает также, как и .include();, с тем исключением, что позволяет добавить данные одного массива в другой, без того, исключая при этом дуплирование информации. Стоит также отметить, что метод .combine(); является чувствительным к регистру, поэтому нужно быть внимательным при ее использовании. Предположим, у нас было создано 2 массива из следующего HTML кода:

<div id="body_wrap">
	<div>первый</div>
	<div>второй</div>
    <span class="class_name">добавляем в массив</span>
    <span class="class_name">и это туда же</span>
    <span class="class_name">снова туда же</span>
</div>

После чего мы может создать следующие два массива:

//создаем массив, так же, как мы это делали и ранее
 
var myArray = $('body_wrap').getElements('div');
 
//потом, создаем массив из всех элементов с классом .class_name
 
var newArrayToArray = $$('.class_name');

Теперь мы можем использовать .combine(); чтобы комбинировать два созданных массива. Этот метод также исключит дубликаты информации.

//а потом комбинируйте переменную newArrayToArray c myArray
 
myArray.combine(newArrayToArray);

Теперь массив myArray содержит все элементы массива newArraytoArray.

Примеры

Массивы позволяют вам производить какое-либо действие с целым списком элементов. В следующем примере видно, как можно использовать ключ. слово “item” как своего рода “местоимение” текущего элемента.

//создает массив всех жлементов в элементе #body_wrap классом .class_name
 
var myArray = $('body_wrap').getElements('.class_name');
 
//вначале создадим новый элемент, который потом добавим к нашему массиву 
 
var addSpan = $('addtoarray');
 
//а теперь создадим новый массив, который скомбинируем с нашим массивом
 
var addMany = $$('.addMany');
 
//теперь можно добавить в массив элемент span
 
myArray.include(addSpan);
 
//и комбинировать массив addMany с массивом myArray myArray.combine(addMany);
//теперь создадим функцию, которая пройдется по всем элементам (ITEM) массива
 
var myArrayFunction = function(item) {
 
//ключевое слово item теперь относится к текущему элементу в массиве,
//к которому применяется функция
	item.setStyle('background-color', '#eee');
}
 
//теперь вызовем созданную функцию myArrayFunction для каждого элемента в массиве
//с помощью метода EACH
 
myArray.each(myArrayFunction);

<div id="body_wrap"> 
	<div class="class_name">первый</div>
    <div>второй</div> 
    <div class="class_name">третий</div>
    <span id="addtoarray">добавить в массив</span>
    <span class="addMany">один из нескольких</span>
    <span class="addMany">второй из нескольких</span></div>

Закругляемся…

Ну что ж, вроде как все! Этот урок не претендует на то, чтобы показать вам все прелести того, что библиотека Mootools может делать с массивами, но, надеюсь, он дал вам идею того, что Mootools может предложить по этому поводу.

А что будет завтра?

В следующем уроке мы поговорим о функциях: о том как их создавать, как их использовать и для чего они вообще нужны.

В следующих нескольких уроках мы продолжим говорить об основах Mootools, нов дальнейшем перейдем к более сложным проектам, так что не забывайте все то, что уже знаете ;-) .

Я пока все еще работаю над pdf-изацией всех документов на docs.mootools.net, но все равно рекомендую там иногда появляться и просматривать предназначения тех многочисленных функций и методов, которые предоставили нам разработчики Mootools. Я это тоже иногда делаю. Кстати, несмотря на полное отсутствие внимания к деталям, я недавно сделал небольшой скриптик, написанный на чистом Mootools, который заменяет цены на странице, в соответствии с введенным курсом обмена валют по ЦБ. Еще планирую автоматизировать этот процесс, что б скрипт сам откуда то брал нынешний курс валют… Если кому-то это интересно, могу выложить код, хотя, я уверен, все уже и так продвинулись дальше меня в этом всем ;-) .

Как всегда, всем удачи в начинаниях!

, , ,

  1. #1 by MuKeXa on 29.11.2010 - 6:27 pm

    Помогите пожалуйста в такой ситуации:
    window.addEvent(‘domready’, function()
    {
    $$(‘.pagination_’).addEvent(‘click’, pagination_upd);
    });
    Как в функции “pagination_upd” применить:
    setProperty(‘text’,'Новый_Текст’);
    элементу на который я нажал.
    Заранее благодарен )
    Массив с класом “pagination_” – это ссылки на страницы.

    • #2 by proglammer on 29.11.2010 - 8:05 pm

      ух… не мало я обжигался этим делом :) MuKeXa, дело в том, что селектор $$ работает с множеством элементов, соответственно, результатом его работы является массив элементов, тогда как addEvent можно применить только одному элементу… понимаешь, к чему я :) попробуй использоваться функцию each:

      $$('.pagination_').each(function(i){
         i.addEvent('click', function(e){
            //если нужно отменить реакцию ссылки по умолчанию делаем так:
            e.stop();
      //не уверен, что нужно использовать
      //именно setProperty, т.к. относится к атрибутам,
      //как href, alt, src и т.д.
            i.set('text', 'новый текст')
        });
      })

      надеюсь это поможет. Удачи! ;)
      Спасибо, что поделился проблемой и опытом!

      • #3 by MuKeXa on 30.11.2010 - 5:33 pm

        Да я вот тоже что-то разобраться пока не могу.
        Пробовал так:

        window.addEvent('domready', function()
        {
        	$$('.pagination_').each(
        		function(i) //на сколько я понял "i" это и есть элемент по которому я кликнул
        		{
        		i.addEvent('click',function(e){ //зачем тогда "е"?
        			 new Event(e).stop(); // e.stop();  не сработал. Может потому, что в Joomla старая версия фрэймворка.
        			i.set('text', 'новый текст'); //тут я и "е" подставлял. Ничего не получилось (((
        				});
        			});
        });
        

        Ну и то, что я раньше делал:
        “$$(‘.pagination_’).addEvent(‘click’, pagination_upd);”
        я думал, что эта функция будет вызываться если событие прошло на любом элементе с классом “pagination_”, что в принципе мне и нужно. А в функции я бы оперировал элементом который возбудил событие:

        var pagination_upd = function(item)
        	 {
        		new Event(item).stop();
        		item.set('text', 'новый текст');
        }
        

        Но пока ни один из вариантов не сработал ((( Может где еще ошибся )
        setProperty – как-раз потому, что мне нужно поймать “href” и немножко видоизменить его ) А тренируюсь на тексте, потому как нагляднее заметить его изменение нежели ссылки )
        Спасибо за понимание и помощь ))) Жду советов и продолжаю разбираться )

        • #4 by proglammer on 30.11.2010 - 11:08 pm

          так, попробую по порядку. например:
          массив.each(function(элемент, индекс){ … }) //именно такой порядок
          массив – ну понятно, массив;
          элемент – не важно, как назовешь, все равно переменная удалится после окончания работы функции. я называю как можно короче, чтобы не путаться (часто используется еще item). по сути, это переменная this в контексте текущего массива;
          индекс – порядковый номер элемента в массиве

          далее: при работе с элемент.addEvent(событие, …) есть два варианта развития событий:
          1) передаёшь функцию, определенную ранее, но, тогда, у меня, по крайней мере, не получилось передать переменную события:

          window.addEvent('domready', function(){
          	var p = function(el){
          		el.set('href', 'http://www.www');
          		}
          	$$('.pagination').each(function(i){
          		i.addEvent('click', p(i);
          			i.set('href', 'http://www.www');
          			});
          		})
          	})
          

          2) определяешь функцию прямо тут, тогда можно передать переменную текущего события:

          window.addEvent('domready', function(){
          	$$('.pagination').each(function(i){
          		i.addEvent('click', function(e){
          			e.stop();
          			i.set('href', 'http://www.www');
          			});
          		})
          	})
          

          второй вариант у меня работает, вроде бы, как тебе нужно: при клике меняет href, но далее событие не срабатывает. если убрать e.stop();, то произойдет переход на адрес, который указан в set(‘href’, url). только прикол в том, что тогда ссылка теперь вообще не будет работать. если нужно, чтобы после смены href-a ссылка все-таки сработала, нужно убрать текущее событие через элемент.removeEvent(‘click’).

          вот, как-то так :)
          надеюсь чем-нибудь тебе помог. если что пиши!

      • #5 by MuKeXa on 30.11.2010 - 5:40 pm

        Забыл сказать, что переход оно таки блокирует ,а вот текст…
        Ну и подскажи как вставлять код в сообщения, а то я не в курсе )))

        • #6 by proglammer on 30.11.2010 - 11:12 pm

          MuKeXa :
          Ну и подскажи как вставлять код в сообщения, а то я не в курсе )))

          с кодом у меня проблема :) wordpress ведет жесткую борьбу против спама и за безопасность, потому блокирует весь код напрочь. Но, так как ты уже комментировал, тебя может пропустить. Если тебе нужно будет вставить яваскрипт, вставляй его в <pre>код</pre>

  2. #7 by MuKeXa on 01.12.2010 - 5:10 pm

    Напишу без цитаты, а то на моём 15″ в каждой строчке, нашей многотомной беседы, по два слова только вмещается )))
    Спасибо тебе за терпение и практику.
    Получилось таки сделать, но немного видоизменив:

    var pagination_upd = function(i)
    {
    
    i.addEvent('click', function(e){
    
    	new Event(e).stop(); // ну никак не хочет e.stop();
    	i.setProperty('href', 'http://www.www'); // ну и i.set() тоже обленилось, тобишь ничего не делало. Видать таки версия mootools-a старенькая.
    				}
    );
    
    window.addEvent('domready', function()
    {
    	$$('.pagination_').each(pagination_upd);
    });
    

    Подведя итоги:
    i – это элемент массива, который вызвал событие
    e – собственно событие )))
    Разобрался )
    Ну а по поводу продолжения с новой ссылкой, мне повезло. Не нужно мне такого. Еще раз спасибо.

    • #8 by proglammer on 01.12.2010 - 9:13 pm

      у меня тоже 15”, но вроде все нормально видно :) хотя уже задумался сегодня на работе, что нужно было бы сократить немного эти отступы, а то действительно нормального разговора не получится :)

      “немного видоизменить” – это слабо сказано :) все основные моменты моего кода тебе пришлось переписывать… так что чем именно помог, не понятно.. видимо, как Др. хаус – ему бредовые идеи говорят, а его потом осеняет. а какая версия mootools у тебя? это в самом файле mootools.js, или подобном, узнать можно. интересно стало, в чем же, все-таки различие.

      • #9 by MuKeXa on 02.12.2010 - 9:16 am

        Я компонент для CMS:”Joomla” пишу. В каталоге имеются два файла, в разных папках. У одного version:”1.2.4″. У второго version:’1.12′. Какой из них оно хватает, мне как-то безразлично. Главное чтобы работало )))
        По поводу двух слов в строчке приврал конечно(4-5), но читабельность конечно падает. Особенно если код не заключать в теги. )))
        Ну а помог разобраться это 100%. Я никак не мог понять: как добраться до свойств вызываемого элемента . Так что при встрече с меня пиво )))

  3. #10 by Роман on 19.12.2011 - 4:03 pm

    Здравствуйте.
    Вот уже пол инета перерыл, нигде ничего найти не могу. Может быть вы подскажете?
    У меня меню на сайте реализовано на библиотеке mootools. Весрия 1.12 помоему. Стандартная библиотека которая идет в сборке MODx.
    Мне понадобился ротатор баннеров на главной. Не долго думая я устанавливаю Nivo Slider на jQuery через noconflict. И тут до меня доходит, что это не ротатор, а всего лишь обычный слайдер. После этого я устанавливаю SlidetMoo на mootools и обнаруживается конфликт библиотек. Подскажите пожалуйста есть ли выход из этой ситуации. Хочется ротатор с красивыми переходами, а альтернативы найти не могу. Ну или как освместить две разные версии библиотек.
    Спасибо.

    • #11 by proglammer on 19.12.2011 - 5:21 pm

      Честно говоря, не совсем понял вопроса. У вас уже есть мутулз на сайте. понадобился ротатор, но поставили плагин jQuery. Плагин оказался не ротатор, вы нашли ротатор на мутулз. Так? Если да, то что мешает снести jquery? или это конфликт версий mootools, ведь 1.12 – старовата версия, по-моему? Может скиньте url (можно через форму), попробуем разобраться, хотя ничего не могу обещать :)

(никто не узнает)

Код на картинке: