Вызов функции с несколькими параметрами массива - PullRequest
0 голосов
/ 02 апреля 2019

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

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

for (var i=0; i < anc.length; i++) {
    anc[i].addEventListener('mouseover', function(i,pop,tri) {
       console.log('i=%i', i);    // last value of loop
       pop[i].style.display = 'initial';
       tri[i].style.animation='anim_dpt_tr 0.4s ease-out forwards';
    });
    ...
}

Более полезный код

var pop = document.querySelectorAll('#cities > li > a > .popup');
const anc = document.querySelectorAll('#cities > li > a');
var tri = document.getElementsByClassName('triangle-left');

for (var i=0; i < anc.length; i++) {
    anc[i].addEventListener('mouseover', over(i, tri, pop));
    anc[i].addEventListener('touchmove', over(i, tri, pop));
    anc[i].addEventListener('touchend', out(i, tri, pop));
    anc[i].addEventListener('mouseout', out(i, tri, pop));
}

function over(i,tri,pop) {
    console.log("over_address=%i", pop[i]); // =0
    pop[i].style.display = 'initial';
    tri[i].style.animation='anim_dpt_tr 0.4s ease-out forwards';
}
function out(i,tri,pop) {
    console.log("out_i=%i", i);             // =each index
    pop[i].style.display = 'none';
    tri[i].style.animation='anim_dpt_tr_back 0.3s ease-in forwards';
}

здесь HTML дерево

<ul id="cities">
  <li>
    <a href="">Shoulder
      <span class="triangle-left"></span> <span class="popup">Arm</span> </a>
  </li>
...

Как правильно передать массивы в обработчик событий?

Ответы [ 3 ]

3 голосов
/ 02 апреля 2019

Ваш «более полезный код» неверен, потому что он фактически не назначает никаких обработчиков событий;он просто немедленно вызывает код и возвращает undefined.

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

function over(i,tri,pop) {
  return function(event) {
    console.log("over_address=%i", pop[i]); // =0
    pop[i].style.display = 'initial';
    tri[i].style.animation='anim_dpt_tr 0.4s ease-out forwards';
  }
}
function out(i,tri,pop) {
  return function(event) {
    console.log("out_i=%i", i);             // =each index
    pop[i].style.display = 'none';
    tri[i].style.animation='anim_dpt_tr_back 0.3s ease-in forwards';
  }
}

Это старый способ сделать это.Совсем недавно вы использовали переменную i, которая ограничена блоком цикла for, используя let или const вместо var.


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


Еще одна возможность состоит в создании объекта, реализующего EventListener интерфейс.Затем вы можете просто назначить каждому элементу объект и использовать сам объект вместо функции обработчика событий.

var pop = document.querySelectorAll('#cities > li > a > .popup');
const anc = document.querySelectorAll('#cities > li > a');
var tri = document.getElementsByClassName('triangle-left');

for (var i=0; i < anc.length; i++) {
    // Create a new instance of your object, giving it the data needed
    //   when an event occurs.
    var obj = new MyElements(pop[i], anc[i], tri[i], i);

    // Use the object itself in lieu of an event handler function
    //  (see below)
    anc[i].addEventListener("mouseover", obj);
    anc[i].addEventListener("touchmove", obj);
    anc[i].addEventListener("mouseout", obj);
    anc[i].addEventListener("touchend", obj);
}

// Holds the relevant info for each index
function MyElements(pop, anc, tri, i) {
  this.pop = pop
  this.anc = anc
  this.tri = tri
  this.i = i
}

// Implements the EventListener interface.
// This is what gets invoked when an event occurs.
// It is set up to simply invoke a function on the same object
//   that has been given the same name as the event.
MyElements.prototype.handleEvent = function(event) {
  this[event.type](event)
}

// These are the functions for each event type. For simplicity, I
// gave each handler the name of the event that fires it so that
// you can use event.type to invoke them.
MyElements.prototype.mouseover = 
MyElements.prototype.touchmove = function over(event) {
    console.log("over_address=%i", this.i); // =0
    this.pop.style.display = 'initial';
    this.tri.style.animation='anim_dpt_tr 0.4s ease-out forwards';
}

MyElements.prototype.mouseout =
MyElements.prototype.touchend = function out(event) {
    console.log("out_i=%i",this.i);             // =each index
    pop[i].style.display = 'none';
    tri[i].style.animation='anim_dpt_tr_back 0.3s ease-in forwards';
}
0 голосов
/ 02 апреля 2019

Эта строка anc[i].addEventListener('anyEvent', over(i, tri, pop)) будет пытаться немедленно вызвать функцию. Вместо этого вы можете создать функцию обратного вызова и вызвать over & out из этого. Также вместо передачи нескольких параметров передайте контекст, используя this. Здесь this будет ссылаться на элемент, который запускает событие, которое в данном случае является anchor tag.

Затем внутри функции over/out используйте elem.querySelector('.popup'), которая будет нацелена на элемент с классом popup внутри элемента, который вызывает событие. Затем вы можете добавить свойства стиля

const anc = document.querySelectorAll('#cities > li > a');
for (var i = 0; i < anc.length; i++) {
  anc[i].addEventListener('mouseover', function() {
    over(this)
  });

  anc[i].addEventListener('mouseout', function() {
    out(this)
  });
}

function over(elem) {
  elem.querySelector('.popup').style.display = 'initial';
  elem.querySelector('.triangle-left').style.animation = 'anim_dpt_tr 0.4s ease-out forwards';
}

function out(elem) {
  elem.querySelector('.popup').style.display = 'none';
  elem.querySelector('.triangle-left').style.animation = 'anim_dpt_tr_back 0.3s ease-in forwards';
}
<ul id="cities">
  <li>
    <a href="">Shoulder
      <span class="triangle-left"></span> <span class="popup">Arm</span> </a>
  </li>
  <li>
    <a href="">Shoulder
      <span class="triangle-left"></span> <span class="popup">Leg</span> </a>
  </li>
  <li>
    <a href="">Shoulder
      <span class="triangle-left"></span> <span class="popup">ercerc</span> </a>
  </li>
</ul>
0 голосов
/ 02 апреля 2019

Вы можете использовать .bind (), чтобы сделать это. Все ваши звонки могут выглядеть, например, over.bind(null, i, tri, anc), когда используется как обработчик функций. Обратите внимание, обязательный null в качестве первого аргумента.

Следовательно, это будет преобразовано в:

over.bind(null, i, tri, pop)
out.bind(null, i, tri, pop)

Дайте мне знать, если это работает. Остальное, оставьте мне комментарий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...