Как получить событие НЕ запускать в родительских элементах - PullRequest
0 голосов
/ 03 мая 2018

Предположим, у меня есть HTML-документ только с элементами h1 и div. Div - это простой квадрат, видимый цветом фона.

Если я использую обычный способ присоединения события щелчка, используя только код JS (используя addEventListener), функция fOnClick корректно выполняется при ТОЛЬКО щелчке по элементу Div. При нажатии на H1 или документ в другом месте, функция НЕ выполняется, как и ожидалось.

Но при комментировании строки dDragger.addEventListener .. и раскомментировании строки MyStuff.Events.bOn .. (для включения модуля обработки событий) функция fOnClick также корректно выполняется при щелчке по элементу Div, но также ALSO ( Неправильно!) Выполняется при нажатии на H1 или в другом месте документа!

Я что-то упустил? Есть ли прицел, который не пойман?

<!DOCTYPE html>
 <html>
  <head></head>
    <body>
        <h1>Events</h1>
        <div id="dragger" style="width:50px; height:50px; background-color: #444;"></div>

        <script>

var MyStuff = MyStuff || {};
MyStuff.Events = (function (oEvents) {

    oEvents.bOn = function (oElement, sEventName, fCallback) {
        var fListenerMethod = oElement.addEventListener || oElement.attachEvent,
            sEventName = oElement.addEventListener ? sEventName : 'on' + sEventName;
        return fListenerMethod(sEventName, fCallback) ? true : false;
    };

    return oEvents;
}(MyStuff.Events || {}));

var fOnClick = function(e) {
    e.preventDefault();
    console.log("fOnClick");
    return false;
};

dDragger = document.getElementById("dragger");

//dDragger.addEventListener("click", fOnClick);
MyStuff.Events.bOn(dDragger, "click", fOnClick);

        </script>
    </body>
</html>

1 Ответ

0 голосов
/ 03 мая 2018

Проблема здесь:

return fListenerMethod(sEventName, fCallback) ? true : false;

Возвращенный как есть, fListenerMethod там (который является функцией addEventListener в современных браузерах) не привязан к элементу, переданному в bOn. Таким образом, он предполагает глобальный контекст вызова, что означает, что любой щелчок в любом месте документа вызовет событие:

addEventListener('click', () => console.log('clicked'))

Вместо этого следует вызывать функцию с соответствующим контекстом вызова (oElement):

return fListenerMethod.call(oElement, sEventName, fCallback) ? true : false;

<h1>Events</h1>
<div id="dragger" style="width:50px; height:50px; background-color: #444;"></div>

<script>
  var MyStuff = MyStuff || {};
  MyStuff.Events = (function(oEvents) {

    oEvents.bOn = function(oElement, sEventName, fCallback) {
      var fListenerMethod = oElement.addEventListener || oElement.attachEvent,
        sEventName = oElement.addEventListener ? sEventName : 'on' + sEventName;
      return fListenerMethod.call(oElement, sEventName, fCallback) ? true : false;
    };

    return oEvents;
  }(MyStuff.Events || {}));

  var fOnClick = function(e) {
    e.preventDefault();
    console.log("fOnClick");
    return false;
  };

  dDragger = document.getElementById("dragger");

  //dDragger.addEventListener("click", fOnClick);
  MyStuff.Events.bOn(dDragger, "click", fOnClick);
</script>
...