最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - d3.event is null inside of debounced function - Stack Overflow

programmeradmin0浏览0评论

When attempting to use a debounced version of a mousemove event handler, d3.event is null. I'd like to use the d3.mouse object in this de-bounced handler, but d3.event returns null and throws an error. How can I have access to d3.event in the following code:

// 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 );
  });

A jsfiddle if you care to see it in action. Trying mousemoving over the rect element.

When attempting to use a debounced version of a mousemove event handler, d3.event is null. I'd like to use the d3.mouse object in this de-bounced handler, but d3.event returns null and throws an error. How can I have access to d3.event in the following code:

// 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 );
  });

A jsfiddle if you care to see it in action. Trying mousemoving over the rect element.

Share Improve this question edited Oct 5, 2019 at 20:57 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Feb 27, 2015 at 19:48 joshcarrjoshcarr 5135 silver badges7 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

This happens because D3 removes the event variable after the event has finished, since debounce uses a timeout when it gets called its to late and the event its gone.

To solve this you could use a modified version of your debounce function to save the current event and replace it before your call.

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;
    }

  };
}
发布评论

评论列表(0)

  1. 暂无评论