在debounced函数中d3.event为null

jos*_*arr 6 javascript svg dom-events d3.js

尝试使用去抖动版本的mousemove事件处理程序时,d3.eventnull.我想d3.mouse在这个debounced处理程序中使用该对象,但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 );
  });
Run Code Online (Sandbox Code Playgroud)

一个的jsfiddle如果你愿意看到它在行动.尝试鼠标移动rect元素.

Mon*_*lon 8

发生这种情况是因为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;
    }

  };
}
Run Code Online (Sandbox Code Playgroud)