2015-02-27 2 views
6

При попытке использовать дебютную версию обработчика события mousemove d3.event - null. Я хотел бы использовать объект d3.mouse в этом обработанном обработчике, но d3.event возвращает null и выдает ошибку. Как я могу иметь доступ к d3.event в следующем коде: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, если вы заботитесь, чтобы увидеть его в действии. Попытка mousemoving над элементом rect.

ответ

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

    }; 
} 
+0

Отличный ответ! Это решило мою проблему, большое спасибо – Rustam

Смежные вопросы