d3.event在反跳函数内部为null

d3.event is null inside of debounced function

本文关键字:内部 null 函数 event d3      更新时间:2024-06-20

当尝试使用鼠标移动事件处理程序的去抖动版本时,d3.event就是null。我想在这个反反弹处理程序中使用d3.mouse对象,但d3.event返回null并抛出错误。我如何访问以下代码中的d3.event

// a simple debounce function
function debounce(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
      timeout = null;
      if (!immediate) {
        func.apply(context, args);
      }
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) {
      func.apply(context, args);
    }
  };
}
// the function to handle the mouse move
function handleMousemove ( context ) {
  var mouse = d3.mouse( context );
  console.log( mouse );
}
// create a debounced version
var debouncedHandleMousemove = debounce(handleMousemove, 250);
// set up the svg elements and call the debounced version on the mousemove event
d3.select('body')
    .append('svg')
    .append('g')
  .append('rect')
    .attr('width', 200)
    .attr('height', 200)
  .on('mousemove', function () {
      debouncedHandleMousemove( this );
  });

如果你想看看它的动作,那就是一把小提琴。正在尝试将鼠标移到rect元素上。

之所以会发生这种情况,是因为D3在事件完成后删除了事件变量,因为debounce在被调用时会使用超时。

要解决此问题,您可以使用debounce函数的修改版本来保存当前事件,并在调用之前将其替换。

function debounceD3Event(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this;
    var args = arguments;
    var evt  = d3.event;
    var later = function() {
      timeout = null;
      if (!immediate) {
        var tmpEvent = d3.event;
        d3.event = evt;
        func.apply(context, args);
        d3.event = tmpEvent;
      }
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) {
      var tmpEvent = d3.event;
      d3.event = evt;
      func.apply(context, args);
      d3.event = tmpEvent;
    }
  };
}