在debounced函数中d3.event为null

时间:2015-02-27 19:48:05

标签: javascript svg d3.js javascript-events

尝试使用deboved版本的mousemove事件处理程序时,d3.eventnull。我想在此debounced处理程序中使用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 );
  });

jsfiddle如果你想看到它的实际效果。尝试对rect元素进行鼠标移动。

1 个答案:

答案 0 :(得分: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;
    }

  };
}