SVG элементы событий - PullRequest
       4

SVG элементы событий

0 голосов
/ 04 декабря 2018

У меня есть div с несколькими элементами SVG, выступающими в качестве кнопок, div и его элементы все добавляются после загрузки страницы, а пользователь выполняет некоторые действия.Я хочу добавить события к элементам SVG, поэтому, используя делегирование события, я получаю событие, а затем проверяю его цель.Проблема в том, что когда я пытаюсь это все работает просто отлично.но когда я нажимаю на элемент:

e.target свойство иногда возвращает элемент SVG, а иногда возвращает элемент пути.

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

Если я использовал тег <i> для своих значков, возникнет ли у меня такая же проблема?

РЕДАКТИРОВАТЬ:

var secondCondition = (e.target.tagName === 'path' && e.target.parentElement.id === 'icon-circle-with-minus');
if (e.target.matches('.servingsDecrease *, .servingsDecrease') || secondCondition) {
     console.log('dec');
}

этот код работает нормально.

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Используйте свойство currentTarget события вместо target.currentTarget - это элемент, к которому прикреплено событие.Запустите фрагмент ниже и нажмите на различные элементы, чтобы увидеть его в действии.

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

function clickHandler(e){
  console.log('target: ', e.target.tagName);
  console.log('currentTarget: ',e.currentTarget.tagName);
}
<svg width="80px" height="80px" viewBox="0 0 80 80" style="background:green;" onclick="clickHandler(event)">
  <path d="M0,0 L20,0 L20,20 L0,20 Z" fill="red"/>
  <circle cx="40" cy="40" r="15" fill="blue"/>
</svg>
0 голосов
/ 04 декабря 2018

Свойство e.target иногда возвращает элемент SVG, а иногда возвращает элемент пути.

Именно так оно и должно работать.e.target представляет элемент, который »получил« событие, и в большинстве случаев является вложенным дочерним элементом элемента, к которому подключен слушатель события.

Посмотрите здесь для получения более подробной информации о пузырях / захвате событий, чтобы получить представление о том, как такие события работают.

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

window.addEventListener('click', e => console.log(e.target));

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

образец HTML

<div class="btns">
  <div data-click-handler="btn">
    <span>
      <p>some sample content</p>
    </span>
  </div>
  <div data-click-handler="btn2">
   <ul>
    <li>…</li>
   </ul>
  </div>
</div>

JS

const handlers = {
  btn: e => alert('btn clicked'),
  btn2: e => alert('btn2 clicked')
}

window.addEventListener('click', e => {
  let 
    c = e.target,
    //that could be an array as well
    //if you want all the handlers on
    //»way upwards« to be called
    handler = null
  ;

  //as long as there is a Node
  while (c && c.hasAttribute) {
    //check if it should listen to events
    if (c.hasAttribute('data-click-handler')) {
      //get the handler if it exists
      let key = c.getAttribute('data-click-handler');
      if (handlers.hasOwnProperty(key)) {
        handler = handlers[key];
        //break the loop to keep the reference to
        //»desired target«
        break;
      }
    }
    //go upwards in the tree
    c = c.parentNode;
  }

  //finally call the handler, if any
  if (handler !== null) handler(c);
});

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

В принципе, существует множество способов сделать такую ​​вещь, другой с помощью <element>.matches() API описано здесь .

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