Joomla 1.5 Клики в mootools

Тема в разделе "Создание расширений для Joomla", создана пользователем SindBAD, 18.11.2009.

  1. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Всем привет!
    Пишу компонент и потихоньку осваиваю mootools. При создании своего контекстного меню обнаружились две проблемы:
    1) Следом за моим меню открывается системное, и заслоняет моё.
    2) Не могу понять, как создать событие (что-то вроде onblur), чтобы меню закрывалось после клика где-то за его пределами.
    Код прилагаю.
    Код (PHP):
    1. //показать
    2. window.addEvent('domready', function(){
    3. $ES('a','editcell').addEvent('mousedown', function(event){  //нажата кнопка мыши
    4. if(event.button==2)    //код кнопки- 2 (правая)
    5. $('ddmenu2').setStyles({top: event.pageY+"px", left: event.pageX+"px", display:'block'});
    6. //задать координаты и вывести. ddmenu2 - идентификатор блока меню
    7. return false;  //вроде бы это должно блокировать системное меню?
    8. });
    9. });
    10. //скрыть. Тут была попытка создать onblur, но она не удалась
    11. window.addEvent('domready', function(){
    12. //скрыть меню, если был клик за его пределами
    13. $('ddmenu2').addEvent('blur', function(){$('ddmenu2').setStyles({display:'none'});});
    14. });


    Наверняка здесь есть спецы по mootools. Буду благодарен за любую подсказку.
     
  2.  
  3. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    onBlur - насколько мне известно - это получение фокуса.
    Вам нужно узнать на каком элементы было совершено событие "клик". и если это не ddmenu2, то скрыть его.
     
    SindBAD нравится это.
  4. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Спасибо, буду знать.
    Эта проблема отпала - знакомый помог адаптировать ContextMenu к mootools 1.1.
    Но есть другая: у меня на странице DOM создается динамически, и когда инициализируется класс меню, то он не учитывает элементы, которые появляются позже, и ContextMenu для них не срабатывает. Как лучше выйти из положения? Есть специальное событие?

    P.s. с тултипами получилось просто:
    Код (PHP):
    1. JTooltips = new Tips($$('.hasTip'), { maxTitleChars: 50, fixed: false}); //это после рендеринга страницы,
    2. JTooltips+= new Tips($$('.hasTip'), { maxTitleChars: 50, fixed: false}); //это после создания новых элементов.

    А с ContextMenu так не прокатило: белиберда вышла.
     
  5. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    Дело в том, что вы используете событие domready для навешивания других обработчиков, т.е. после того как страница полностью загрузилась и все дом-элементы известны js навешивает описанные Вами обработчики. Т.о. в результате работы аякса или любого другого скрипта, который добавляет дом-элементы, вновь созданные дом-элементы не будут иметь никаких обработчиков. Вот небольшой пример

    Код (CODE):
    1. window.addEvent('domready', function(){
    2. //добавляем элемент в дом
    3.     $("div0").addEvent('click', function())
    4.      {
    5.           $(this).set('html', '<div id="div1">bla bla bla</div>')
    6.      }
    7.  
    8.     myEvents(); // вешаем на новый элемент обработчик
    9. });
    10.  
    11. function myEvents()
    12. {
    13.     $("div1").addEvent('click', function())
    14.      {
    15.           alert('Hi');
    16.      }
    17. }


    Т.е. после того, как мы добавили новые элементы, на них нужно по вешать обработчики.
     
  6. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Да, я знаю, в чем проблема. Но не понимаю, как её решить, т.е. как правильно переопределить классы, которые вешают события, при изменении дерева. Когда я переопределяю в конце функции, которая добавляет элементы
    Код (PHP):
    1. context = null;
    2.     context = new ContextMenu({
    3.         targets: '.contextElement',
    4.         menu: 'contextmenu',
    5.         actions: {
    6.             copy: function(element,ref) {
    7.                 alert(element.id);
    8.                 return false;
    9.             }
    10.         },
    11.         offsets: { x:0, y:0 }
    12.     });

    то пункты меню при клике (функция copy) срабатывают дважды - alert выводит сначала ID родителя, а потом самого элемента.
    А если включить все дочерние элементы в HTML-код, то выводится только ID элемена, из чего я дклаю вывод, что переопределяю класс как-то не так...
     
    Последнее редактирование: 20.11.2009
  7. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    а зачем вы его определяете два раза ? если событие вам нужно только после того как загрузиться меню ?
     
  8. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Сейчас поясню.

    На странице есть некий список категорий (UL). К каждой из них привязаны некие операции, которые прописаны в контекстном меню. По дабл-клику подгружается содержимое категории, и создается новый вложенный UL (вложенность не ограничена). То есть, контекстное меню используется и для статичных элементов списка и для подгружаемых.
     
  9. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    ну тогда Вам нужно при создании нового дочернего элемента записывать экземпляр класса в новую переменную, например context1, context2 ... contextN . соответственно у вас и target будет меняться на дочерние элементы.
     
  10. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Тогда такой вопрос: как создать переменную с уникальным именем? Сорри, если вопрос нубийский, но я правда не знаю :)

    Да, и еще. Там ведь по идее надо создавать класс только для дочерних элементов, для которых обработчиков пока нет, чтобы не получился говнокод, забивающий память? Верно говорю?
     
  11. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    а где вы достали этот класс ? это плагин или он встроен в мутулс ?
     
  12. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
  13. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    так....во первых - в последней версии плагина, при нажатии левой кнопкой мыши за пределами меню - меню исчезает. во вторых - я не до конца понял суть вопроса - вы создаете динамически элементы и потом хотите повешать на них контекстное меню ?
     
  14. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    1) Так и есть. Просто сначала я хотел написать свой сценарий, а потом взял готовый плагин. Оттуда и вопрос был
    2) Именно так.
     
  15. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    дом-дерево в студию )
     
  16. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Код (html):
    1. <div id="editcell">
    2. <ul>
    3.                 <li class="caregory">
    4.                 <a class="hasTip contextElement" id="category1" title="Категория::Тестовая категория">Категория</a>
    5.             </li>
    6.                     <li class="caregory">
    7.                 <a class="hasTip contextElement" id="category2" title="Лайнтекс::Тестовая категория">Лайнтекс</a>
    8.             </li>
    9.                     <li class="caregory">
    10.                 <a class="hasTip contextElement" id="category3" title="Венера::Тестовая категория">Венера</a>
    11.             </li>
    12.         </ul>
    13. </div>
    14. <ul id="contextmenu">
    15.     <li><a href="#edit" class="edit">Изменить</a></li>
    16.     <li class="separator"><a href="#cut" class="cut">Вырезать</a></li>
    17.     <li><a href="#copy" class="copy">Копировать</a></li>
    18.     <li><a href="#paste" class="paste">Вставить</a></li>
    19.     <li><a href="#delete" class="delete">Удалить</a></li>
    20.     <li class="separator"><a href="#quit" class="quit">Отмена</a></li>
    21. </ul>

    А это скрипт, который им управляет
    Код (CODE):
    1. function createItem(where,html,id,tip){
    2. var newLi = new Element ('li',{'class' : 'caregory'});
    3. var newA = new Element ('a',{'class' : 'hasTip contextElement','id' : id,'title' : tip});
    4. newA.appendText(html);
    5. newLi.appendChild(newA);
    6. where.appendChild(newLi);
    7. }
    8.  
    9. function removeItem(element){
    10. element.parentNode.removeChild(element);
    11. $ES('a','editcell').addEvent('click', selectCategory);
    12. $ES('a','editcell').addEvent('dblclick', openCategory);
    13. }
    14.  
    15. window.addEvent('domready', function(){
    16. JTooltips = new Tips($$('.hasTip'), { maxTitleChars: 50, fixed: false}); }
    17. );
    18.  
    19. window.addEvent('domready', function(){
    20. $ES('a','editcell').addEvent('click', selectCategory);
    21. });
    22. window.addEvent('domready', function(){
    23. $ES('a','editcell').addEvent('dblclick', openCategory);
    24. });
    25.  
    26. window.addEvent('domready', function() {
    27.     //create a context menu
    28.     context = new ContextMenu({
    29.         targets: '.contextElement',
    30.         menu: 'contextmenu',
    31.         actions: {
    32.             copy: function(element,ref) {
    33.                 alert(element.id);
    34.                
    35.                 return false;
    36.             }
    37.         },
    38.         offsets: { x:0, y:0 }
    39.     });
    40. });
    41. function selectCategory(){
    42. var thisUL = this.parentNode;
    43.  
    44. if(thisUL.hasClass('selected')){
    45. thisUL.removeClass('selected');
    46. }else{
    47. thisUL.addClass('selected');
    48. }
    49.  
    50. return false;
    51. }
    52.  
    53. function openCategory(){
    54. var thisUL = this.parentNode;
    55. if(thisUL.hasClass('open')){
    56.  
    57. thisUL.removeClass('open');
    58.  
    59. removeItem(thisUL.getElementsByTagName('UL')[0]);
    60.  
    61. }else{
    62.  
    63. thisUL.addClass('open');
    64.  
    65. var newUl = new Element ('ul');
    66.  
    67. createItem(newUl,'createItem','createItem1','createItem1::Succesfull');
    68. createItem(newUl,'createItem2','createItem2','createItem2::Succesfull');
    69. createItem(newUl,'createItem3','createItem3','createItem3::Succesfull');
    70.  
    71. thisUL.appendChild(newUl);
    72. $ES('a','editcell').addEvent('click', selectCategory);
    73. $ES('a','editcell').addEvent('dblclick', openCategory);
    74. JTooltips+= new Tips(newUl.getElementsByClassName('hasTip'), { maxTitleChars: 50, fixed: false});
    75.     //create a context menu
    76.     context = null;
    77.     context = new ContextMenu({
    78.         targets: '.contextElement',
    79.         menu: 'contextmenu',
    80.         actions: {
    81.             copy: function(element,ref) {
    82.                 alert(element.id);
    83.                
    84.                 return false;
    85.             }
    86.         },
    87.         offsets: { x:0, y:0 }
    88.     });
    89. }
    90. return false;
    91. }
     
  17. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Наверно, придется забить на mootools и на плагин и написать свой обработчик. Этот в опере не работает вообще никак
     
  18. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    у Вас в <div id="editcell"> ... </div> динамически создаются элементы списка и на них вы хотите повешать контекстное меню ?
     
  19. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Ага. Вот так:
    Код (html):
    1. <div id="editcell">
    2. <ul>
    3.                 <li class="caregory">
    4.                 <a class="hasTip contextElement" id="category1" title="Категория::Тестовая категория">Категория</a>
    5. <ul>
    6.                 <li class="caregory">
    7.                 <a class="hasTip contextElement" id="newcategory1" title="Новая1::Тестовая категория">Новая1</a>
    8.             </li>
    9.                     <li class="caregory">
    10.                 <a class="hasTip contextElement" id="newcategory2" title="Новая2::Тестовая категория">Новая2</a>
    11.             </li>
    12.                     <li class="caregory">
    13.                 <a class="hasTip contextElement" id="newcategory3" title="Новая3::Тестовая категория">Новая3</a>
    14.             </li>
    15.         </ul>
    16.             </li>
    17.                     <li class="caregory">
    18.                 <a class="hasTip contextElement" id="category2" title="Лайнтекс::Тестовая категория">Лайнтекс</a>
    19.             </li>
    20.                     <li class="caregory">
    21.                 <a class="hasTip contextElement" id="category3" title="Венера::Тестовая категория">Венера</a>
    22.             </li>
    23.         </ul>
    24. </div>
     
  20. omfgpanda
    Offline

    omfgpanda специалист

    Регистрация:
    22.01.2008
    Сообщения:
    673
    Симпатии:
    53
    Пол:
    Мужской
    Примерно верно вот так ? )))
     
  21. Offline

    SindBAD Недавно здесь

    Регистрация:
    09.06.2009
    Сообщения:
    100
    Симпатии:
    6
    Пол:
    Мужской
    Ну да, типа того. А верно или нет, становится понятно, когда функция, прикрепленная к пунктк меню, работает не с искомым элементом, а с каким-нибудь другим. Например, когда вешал на copy function(element, ref){ alert(element.id); return false; } то выводилась целая куча ID и при этом страница несколько раз перезагружалась ))
     

Поделиться этой страницей

Загрузка...