我编写了一些对 svg 元素使用拖动事件的代码。该代码运行良好,我想为其编写一些测试。我不想手动移动鼠标,而是想以编程方式触发dragstart
and drag
事件与选择.调度 https://github.com/d3/d3-selection#selection_dispatch:
svgSelection.dispatch('dragstart',{bubbles:true});
svgSelection.dispatch('drag',{bubbles:true});
然而,这些事件似乎并没有被解雇。也许我使用了错误的事件键或需要包含一些附加选项?
我还尝试使用以下没有帮助的变体:
svgElement.dispatchEvent(new Event('drag', {bubbles:true}));
svgSelection.dispatch('mousedown.drag',{bubbles:true});
If I try
svgElement.on('mousedown.drag')()
我收到一个错误
Uncaught TypeError: Cannot read property 'ctrlKey' of null
at defaultFilter (drag.js?009f:10)
at mousedowned (drag.js?009f:51)
触发以下代码中使用的事件“开始”和“拖动”的正确方法是什么?
let offset = [0,0];
let drag = d3.drag()
.on('start', () => this.__dragStarted(d3, svgSelection, offset))
.on('drag', ()=> this.__dragged(d3, svgSelection, offset));
svgSelection.call(drag);
我的测试示例:
it('enableDragAndDrop', ()=>{
let element = document.createElement('svg');
let svgSelection = d3.select(element);
spyOn(sut, '__dragStarted');
spyOn(sut, '__dragged');
sut.enableDragAndDrop(svgSelection);
svgSelection.dispatch('dragstart',{bubbles:true});
svgSelection.dispatch('drag',{bubbles:true});
expect(sut.__dragStarted).toHaveBeenCalled();
expect(sut.__dragged).toHaveBeenCalled();
});
我的代码示例:
enableDragAndDrop(svgSelection){
let offset = [0,0];
let drag = d3.drag()
.on('start', () => this.__dragStarted(d3, svgSelection, offset))
.on('drag', ()=> this.__dragged(d3, svgSelection, offset));
svgSelection.call(drag);
}
__dragStarted(d3, svgSelection, offset){
if(!svgSelection.attr('transform')){
svgSelection.attr('transform','translate(0,0)');
}
let transform = svgSelection.attr('transform');
let translate = this.__extractTranslate(transform);
offset[0] = translate[0] - d3.event.x;
offset[1] = translate[1] - d3.event.y;
}
__dragged(d3, svgSelection, offset){
let x = d3.event.x + offset[0];
let y = d3.event.y + offset[1];
svgSelection
.attr('transform', 'translate(' + x + ', ' + y + ')');
}
__extractTranslate(transformString){
let stripped = transformString;
stripped = stripped.replace('translate(','');
stripped = stripped.replace(')','');
let numberStrings = stripped.split(',');
return numberStrings.map(numberString=>parseFloat(numberString));
}
相关问题:
如何外部触发d3事件 https://stackoverflow.com/questions/40415144/how-to-externally-trigger-d3-events
JavaScript中如何触发事件? https://stackoverflow.com/questions/2490825/how-to-trigger-event-in-javascript
以编程方式创建拖动事件时 dataTransfer 为 null https://stackoverflow.com/questions/20867245/datatransfer-is-null-when-creating-drag-event-programmatically