Запустить функцию mootools для каждого элемента, кроме одного

У меня есть две карты:

var map1 = document.id('map1');
var map2 = document.id('map2');

Вторая карта скрыта.

map2.setStyle('display','none');

На первой карте есть элемент (ссылка) с уникальным идентификатором - я бы хотел запустить другую функцию при нажатии на этот элемент (скрыть первую карту и показать вторую).

Я имею:

  var links = document.id('map1').getElements('a');     

  links.each(function(link) { 
  link.addEvent('click', function(e) {
   e.stop();
    //do something with links
  });

Я пытаюсь таким образом:

var unique_link = document.id('my_unique_id').getElements('a');

unique_link.addEvent("click", function(){
links.removeEvent('click');
map1.setStyle('display','none');
map2.setStyle('display','block');
var links = document.id('map2').getElements('a'); 
});

но когда я щелкаю этот уникальный элемент, первая функция все еще работает.

2 ответа

Насколько я понимаю, ваша проблема заключается в том, что вы пытаетесь переключаться между картами, и когда вы переключаетесь, обработчики событий щелчка прикрепляются к ссылкам карт.

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

var unique_link = $$('#my_unique_id a'),
    // keep track of which map is visible
    currentMap = map1;

unique_link.addEvent('click', function(e){
    // Prevent the default behavior, but still allow bubbling of events
    e.preventDefault();

    // Hide the current map
    currentMap.setStyle('display', 'none');

    // store the correct map by comparing the two maps and making it visible
    currentMap = (currentMap == map1 ? map2 : map1).setStyle('display', 'block');

});

Чтобы уточнить, currentMap = (currentMap == map1 ? map2 : map1) называется троичной операцией. Это сокращение для if/else, которое можно переписать так:

if (currentMap == map1) {
    currentMap = map2;
} else {
    currentMap = map1;
}

currentMap.setStyle('display', 'block');

Далее, зачем вам удалять события по ссылкам на каждой карте? Разве они не могут оставаться на связи, когда вы переключаетесь между картами?

Наконец, вы спросили о делегировании события и доступе к значениям по клику. Вот пример того, как это работает в MooTools:

// We pass an array of map1 and map2 through $$ to make sure that the returned value is an element collection
// So we can use addEvent on both elements.

// The event "type" we would have passed to addEvent has changed, using a psuedo event called "relay", which handles event delegation
// It takes a selector for matching elements

// The function that is passed to addEvent has two arugments, e, which is the event object, and element, which is the element that the
// event is being delegated to.
$$([map1, map2]).addEvent('click:relay(a)', function(e, element){
    // Prevent the default behavior of the anchors
    e.preventDefault();

    // element argument is the anchor. So you can access it this way.
   element.get('href');

   // or "this" can also be used.
   this.get('href');

});

Element.removeEvent не работает таким образом. Требуется передать как имя события (щелчок), так и функцию, которая его обрабатывает. Это потому, что может быть несколько функций, которые вызываются, когда click уволен. Ты можешь использовать Element.removeEvents удалить все функции обработки кликов, но это может быть не то, что вы действительно хотите (хотя это, вероятно, хорошо). Чтобы сделать это лучше всего, вы должны сделать это:

var handler = function(e) { e.stop(); /* do something with links */ }),
    links = document.id('map1').getElements('a');

links.addEvent('click', handler);

document.id('my_unique_id').getElements('a').addEvent('click', function() {
    links.removeEvent('click', handler);
    /* Other stuff */
});

Да, и, кстати, это:

document.id('some_id').getElements('.some-selector');

можно написать так:

$$('#some_id .some-selector');
Другие вопросы по тегам