Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Назначение одного обработчика события для всех экземпляров виджета
Форумы портала PHP.SU » Клиентская разработка » JavaScript & VBScript » Назначение одного обработчика события для всех экземпляров виджета

Страниц (1): [1]
 

1. Pavelbeginner - 22 Января, 2014 - 16:09:15 - перейти к сообщению
например, я создал виджет product с использованием jQuery фабрики виджетов.

в объекте-реализации виджета есть следующий метод, который вызывается сразу после установки виджета на диве:
CODE (javascript):
скопировать код в буфер обмена
  1. {
  2.         findElement : function()
  3.         {
  4.                 this.name = this.find('.product--name');
  5.                 this.cost = this.find('.product--cost');
  6.         }
  7. }


То есть находим элемент с классом product--name внутри виджета и сохраняем в нашем объекте.

вот верстка сего виджета:
CODE (html):
скопировать код в буфер обмена
  1. <div class="product">
  2.         <div class="product--name">
  3.                
  4.         </div>
  5. </div>


на странице 3 продукта

CODE (html):
скопировать код в буфер обмена
  1. <div class="product">
  2.         <div class="product--name">
  3.                
  4.         </div>
  5.         <div class="product--cost">
  6.                
  7.         </div>
  8. </div>
  9. <div class="product">
  10.         <div class="product--name">
  11.                
  12.         </div>
  13.         <div class="product--cost">
  14.                
  15.         </div>
  16. </div>
  17. <div class="product">
  18.         <div class="product--name">
  19.                
  20.         </div>
  21.         <div class="product--cost">
  22.                
  23.         </div>
  24. </div>


вызываю инициализацию виджета
CODE (javascript):
скопировать код в буфер обмена
  1. $('.product').product();


теперь возникла задача: по клику на <div class="product--name"> product--cost должен закрыться.
вот методы, которые это делают:
CODE (javascript):
скопировать код в буфер обмена
  1. {
  2.         onNameClick : function()
  3.         {
  4.                 this.name.on('click', this.handleNameClick);
  5.         },
  6.        
  7.         handleNameClick : function(event)
  8.         {
  9.                 this.product--cost.css({display : 'none'});
  10.         }
  11. }


Естественно product--cost не скроется т.к. устанавливая обработчик клика handleNameClick, он вызывается не как метод объекта, а как обычная ф-ция.

Можно, кончно, было реализовать это так:

CODE (javascript):
скопировать код в буфер обмена
  1. {
  2.         onNameClick : function()
  3.         {
  4.                 this.name.on('click', this.handleNameClick);
  5.         },
  6.        
  7.         handleNameClick : function(event)
  8.         {
  9.                 $(event.currentTarget).parents('.product').find('.product--cost').css({display : 'none'});
  10.         }
  11. }


это будет работать, но вся моя идея заключается в том, что внутри метода findElement я хочу находить все элементы виджета и сохранять ссылки на эти элементы внутри экземпляра виджета, то есть в объекте.
я хочу один раз потратить время, найдя все элементы виджета(product--name, product--cost), а затем манипулировать этими элементами, не тратя времени на их поиск, как я делаю вот в этом куске кода:
$(event.currentTarget).parents('.product').find('.product--cost')

Конечно, можно ещё сделать вот так:
CODE (javascript):
скопировать код в буфер обмена
  1. {
  2.         onNameClick : function()
  3.         {
  4.                 var copyOfThis = this;
  5.                
  6.                 function handleNameClick(event)
  7.                 {
  8.                         copyOfThis.handleNameClick(event);
  9.                 }
  10.                
  11.                 this.name.on('click', handleNameClick);
  12.         },
  13.        
  14.         handleNameClick : function(event)
  15.         {
  16.                 this.cost.css({display : 'none'});
  17.         }
  18. }


Замыкание, здорово, работает. Но есть одно неприятное для меня НО. При таком подходе, если будет, например, 1000 продуктов на странице, то ф-ция handleNameClick внутри метода onNameClick будет создана 1000 раз, то есть в памяти будет 1000 экземпляров
одной и той же ф-ции.

В общем я потратил уже не одну неделю, размышляя как же сделать правильно и максимально удобно, но не смог найти решения, которое бы устроило меня.
Может в фабрике уже давно есть решение данного момента, а я и не знаю о нем? Либо, пожалуйста, может у вас есть идеи на сей счет? Заранее благодарю.
2. nerv - 22 Января, 2014 - 19:29:04 - перейти к сообщению
CODE (javascript):
скопировать код в буфер обмена
  1. this.name.on('click', this.handleNameClick.bind(this));
3. Pavelbeginner - 23 Января, 2014 - 10:16:25 - перейти к сообщению
nerv пишет:
CODE (javascript):
скопировать код в буфер обмена
  1. this.name.on('click', this.handleNameClick.bind(this));


Можете пояснить, что в этом коде происходит? Разве bind это не устаревший аналог on? и что дает вызов .bind на функцие handleNameClick?
4. nerv - 23 Января, 2014 - 15:17:34 - перейти к сообщению
http://learn[dot]javascript[dot]ru/bind

 

Powered by ExBB FM 1.0 RC1