Reputation: 7527
I have this plugin that handles dragging the mouse (not the content) and in the start drag handler I'm creating another element triggering a drag and stopping the parents but it's not working (the parent is still calling the dragHandler):
(The reason for this is so I can be able to zoom/pan on mouse dragging.)
start is called on mousedown, which also registers listeners for mousemove, etc.
end is called on mouseup, which also removes the listeners.
<svg></svg>
Plugin:
(function($) {
$.fn.ondrag = function(opt) {
//console.log("set drag");
var obj = this;
opt = $.extend({start:null,drag:null,end:null,leave:null,dropElement:document}, opt);
this.data('ondrag',opt);
opt.dragHandler = function(e){ if (opt.drag) opt.drag.call(obj); e.stopPropagation(); };
opt.leaveHandler = function(e){ if (opt.leave) opt.leave.call(obj); e.stopPropagation(); };
opt.startHandler = function(e){
if (opt.start) opt.start.call(obj);
$(document).on("mousemove",opt.dragHandler);
$(document.body).on("mouseleave",opt.leaveHandler);
$(document).on("mouseup",opt.endHandler); e.stopPropagation(); };
opt.endHandler = function(e){
if (opt.end) opt.end.call(obj);
$(document).off("mousemove",opt.dragHandler);
$(document.body).off("mouseleave",opt.leaveHandler);
$(document).off("mouseup",opt.endHandler); e.stopPropagation(); };
this.on("mousedown",opt.startHandler);
opt.stopdrag = function(){ //this should remove the svg listeners to stop dragging
console.log("stop dragging", opt.drag);
if (opt.end) opt.end.call(obj);
$(document).off("mousemove",opt.dragHandler);
$(document.body).off("mouseleave",opt.leaveHandler);
$(document).off("mouseup",opt.endHandler);
};
return this;
};
})(jQuery);
Implementation:
$('svg').ondrag({
start: function(){
if (event.which==1) {//pan on left click
} else { //create new element with drag and svg stop dragging
console.log("started dragging on svg");
$(document).trigger("mouseup"); //not working (svg is still dragging)
this.data('ondrag').stopdrag(); //not working
$(document.createElementNS('http://www.w3.org/2000/svg', 'circle'))
.attr({r:50,fill:"lightgray",cx:"50%",cy:"50%"})
.ondrag({
start:function(){ console.log("started dragging circle"); },
drag:function(){ console.log("dragging circle"); }
}).appendTo(this).trigger("mousedown");
}
}, drag: function(){ console.log("dragging on svg"); }
});
Upvotes: 2
Views: 1188
Reputation: 1289
The problem is you call your start function before you before your bind your mouse handlers, so your stop function has nothing to unbind.
(function($) {
$.fn.ondrag = function(opt) {
//console.log("set drag");
var obj = this;
opt = $.extend({start:null,drag:null,end:null,leave:null,dropElement:document}, opt);
this.data('ondrag',opt);
opt.dragHandler = function(e){ if (opt.drag) opt.drag.call(obj); e.stopPropagation(); };
opt.leaveHandler = function(e){ if (opt.leave) opt.leave.call(obj); e.stopPropagation(); };
opt.startHandler = function(e){
$(document).on("mousemove",opt.dragHandler);
$(document.body).on("mouseleave",opt.leaveHandler);
$(document).on("mouseup",opt.endHandler);
if (opt.start) opt.start.call(obj);
e.stopPropagation();
};
opt.endHandler = function(e){
opt.stopdrag();
e.stopPropagation();
};
this.on("mousedown",opt.startHandler);
opt.stopdrag = function(){
console.log("stop dragging", opt.drag);
$(document).off("mousemove",opt.dragHandler);
$(document.body).off("mouseleave",opt.leaveHandler);
$(document).off("mouseup",opt.endHandler);
if (opt.end) opt.end.call(obj);
};
return this;
};
})(jQuery);
All you need to do is move the callbacks to start/end below the on/off calls.
Upvotes: 1