Javascript - 事件处理程序中的箭头函数?

2022-01-30 00:00:00 jquery javascript ecmascript-6

I'm new to ES6, and can't quite get this to work:

$(this) returns undefined on click?

dom.videoLinks.click((e) => {
            e.preventDefault();
            console.log($(this));
            var self = $(this),
                url = self.attr(configuration.attribute);

            eventHandlers.showVideo(url);

            // Deactivate any active video thumbs
            dom.videoLinks.filter('.video-selected').removeClass('video-selected');

            // Activate selected video thumb
            self.addClass('video-selected');
        });

However if I change it so not be an arrow function like so, it works as expected?:

dom.videoLinks.click(function(e) {
            e.preventDefault();
            console.log(this);
            console.log($(this));
            var self = e.this,
                url = self.attr(configuration.attribute);

            eventHandlers.showVideo(url);

            // Deactivate any active video thumbs
            dom.videoLinks.filter('.video-selected').removeClass('video-selected');

            // Activate selected video thumb
            self.addClass('video-selected');
        });

So how would I go about it if I use an arrow function in the callback?

解决方案

With arrow function as a callback, instead of using this to get the element to which the handler is bound, you should use event.currentTarget.
Value of this inside an arrow function is determined by where the arrow function is defined, not where it is used.
So from now on, keep in mind that event.currentTarget always refers to the DOM element whose EventListeners are currently being processed.


.currentTarget vs .target

Use event.currentTarget instead of event.target because of event bubbling/capturing:

  • event.currentTarget- is the element that has the event listener attached to.
  • event.target- is the element that triggered the event.

From the documentation:

currentTarget of type EventTarget, readonly Used to indicate the EventTarget whose EventListeners are currently being processed. This is particularly useful during capturing and bubbling.

Check the basic example in the below snippet

var parent = document.getElementById('parent');
parent.addEventListener('click', function(e) {
  
  document.getElementById('msg').innerHTML = "this: " + this.id +
    "<br> currentTarget: " + e.currentTarget.id +
    "<br>target: " + e.target.id;
});

$('#parent').on('click', function(e) {

  $('#jQmsg').html("*jQuery<br>this: " + $(this).prop('id')
                   + "<br>currenTarget: " + $(e.currentTarget).prop('id') 
                   + "<br>target: " + $(e.target).prop('id'));
});

$('#parent').on('click', e => $('#arrmsg').html('*Arrow function <br> currentTarget: ' + e.currentTarget.id));

#parent {background-color:red; width:250px; height:220px;}
#child {background-color:yellow;height:120px;width:120px;margin:0 auto;}
#grand-child {background-color:blue;height:50px;width:50px;margin:0 auto;}
#msg, #jQmsg, #arrmsg {font-size:16px;font-weight:600;background-color:#eee;font-family:sans-serif;color:navy;}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  <div id="parent">Parent-(attached event handler)<br><br>
    <div id="child"> Child<br><br>
      <p id="grand-child">Grand Child</p>
    </div>
  </div>
 
  <div id="msg"></div><br>
  <div id="jQmsg"></div><br>
  <div id="arrmsg"></div>

相关文章