js实现拖拽缩放

这篇博客介绍了如何使用JavaScript实现拖拽和缩放功能。参考了jQuery UI的resize代码,通过在div内添加辅助元素来实现右下角的缩放操作,同时确保拖拽过程中滚动条正常工作且不会选中其他元素。在mouseup事件中移除所有事件,以及在点击特定控件如INPUT时阻止事件传播,防止意外行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近需要用到拖拽,前端人员找了个拖拽代码,主要都是从网上下的,代码如下:

$.fn.extend({
            Drag: function() {
                $(this).attr("isDrag", 1);
                $(this).mousedown(function(e) {
                    if ($(this).attr("isDrag") == 0) return;
                    $(this).attr("drag", 1);
                    $(this).css("position", "absolute");
                    $(this).css("cursor", "default");
                    var currentTarget = $(this);
                    var currentDisX = e.pageX - $(this).offset().left;
                    var currentDisY = e.pageY - $(this).offset().top;
                    $(document).mousemove(function(event) {
                        if ($(currentTarget).attr("drag") == 0 || $(currentTarget).attr("mode") == "re") return;
                        var currentX = event.clientX;
                        var currentY = event.clientY;
                        var cursorX = event.pageX - currentDisX; // $(this).offset().left;
                        var cursorY = event.pageY - currentDisY; //-$(this).offset().top;
                        $(currentTarget).css("top", cursorY   "px").css("left", cursorX   "px");
                    });
                    $(document).mouseup(function() {
                        $(currentTarget).attr("drag", 0);
                    });
                });
            },
            DisDrag: function() {
                $(this).attr("isDrag", 0);
                $(this).attr("drag", 0);
            },
            Resize: function() {
                var currentDisTance = 5;
                var resizeMode = 0;
                var isResize=false;
                var isStartResize=false;
                $(this).mousemove(function(e) {
                    var currentDisX = e.pageX - $(this).offset().left;
                    var currentDisY = e.pageY - $(this).offset().top;
                    if ($(this).width() - currentDisX < currentDisTance && ($(this).height() - currentDisY) < currentDisTance) {
                        $(this).css("cursor", "nw-resize");
                     
                    } else if ($(this).width() - currentDisX < currentDisTance) {
                        $(this).css("cursor", "e-resize");
                         
                    } else if ($(this).height() - currentDisY < currentDisTance) {
                        $(this).css("cursor", "n-resize");
                     
                    } else {
                        if(isStartResize==true)return;
                        $(this).css("cursor", "default");
                    }
                });
                $(this).mousedown(function(e) {
                    isResize=true;
                    var currentDisX = e.pageX - $(this).offset().left;
                    var currentDisY = e.pageY - $(this).offset().top;
                    if ($(this).width() - currentDisX < currentDisTance && ($(this).height() - currentDisY) < currentDisTance) {
                        $(this).css("cursor", "nw-resize");
                        $(this).attr("mode", "re");
                        resizeMode = 0;
                    } else if ($(this).width() - currentDisX < currentDisTance ) {
                        $(this).css("cursor", "e-resize");
                        $(this).attr("mode", "re");
                        resizeMode = 1;
                    } else if ($(this).height() - currentDisY < currentDisTance) {
                        $(this).css("cursor", "n-resize");
                        $(this).attr("mode", "re");
                        resizeMode = 2;
                    } else {
                        if(isStartResize==true)return;
                        $(this).css("cursor", "default");
                        $(this).attr("mode", "me");
                    }
                    var currentTarget = $(this);
                     
                    var offsetWidth=$(this).width()-$(currentTarget).offset().left;
                    var offsetHeight=$(this).height()-$(currentTarget).offset().top;
                    //$(this).css("width",currentWidth currentDisX);
                    $(document).mousemove(function(event) {
                        if ($(currentTarget).attr("mode") == "me"||isResize==false) return;
                        isStartResize=true;
                        var currentX = event.clientX;
                        var currentY = event.clientY;
                        var cursorX = event.pageX - currentDisX; // $(this).offset().left;
                        var cursorY = event.pageY - currentDisY; //-$(this).offset().top;
                        if (resizeMode == 0) $(currentTarget).css("height", cursorY offsetHeight   "px").css("width", cursorX offsetWidth   "px");
                        else if (resizeMode == 1) $(currentTarget).css("width", cursorX offsetWidth   "px");
                        else $(currentTarget).css("height", cursorY offsetHeight   "px");
                    });
                });
                $(document).mouseup(function() {
                        isResize=false;
                        isStartResize=false;
                    });
            }
        });
   在这里的代码有如下几个问题,resize上绑定move事件,效率太低,而且碰到滚动条时move事件失效,而且事件绑定后没有移除,随着点击次数越多,执行的次数将越多,所以讲代码改成如下:

1.参考jquery UI的risize代码,给div里面添加3个div,用来实现右边右下角下边的resize,去除div的move事件,而且滚动条也不会失效,可以继续拖拽。

        2.mouseup事件中移除了所有事件。 

       3.点击div中的一些特殊控件比方说INPUT时阻止事件继续执行。

       4.e.preventDefault(),阻止move事件会选中其他元素

var cancelNodeName = [ "INPUT", "TEXTAREA", "BUTTON" ];
$.fn.extend({
	Drag : function(opts) {
		$(this).mousedown(function(e) {
			if (cancelNodeName.indexOf(e.target.nodeName) >= 0)
				return true;
			if($( e.target ).closest( ".resizable" ).length > 0)
			    return true;
			console.info("Drag");
			var currentTarget = $(this);
			var currentDisX = e.pageX - $(this).offset().left;
			var currentDisY = e.pageY - $(this).offset().top;
			var mousemoveEvent = function(event) {
				if ($(event.target).closest(".resizable").length > 0)
					return true;
				if (opts && opts.beginmove) {
					// beginmove返回true则继续执行,否则不执行
					if (!opts.beginmove(event)) {
						return true;
					}
				}
				currentTarget.attr("moved", 1);
				currentTarget.css("position", "absolute");
				currentTarget.css("cursor", "hand");
				var currentX = event.clientX;
				var currentY = event.clientY;
				var cursorX = event.pageX - currentDisX; // +$(this).offset().left;
				var cursorY = event.pageY - currentDisY; // -$(this).offset().top;
				$(currentTarget).css("top", cursorY + "px").css("left", cursorX + "px");
				if (opts && opts.resize) {
					opts.resize(event, {
						'width' : $(currentTarget).width(),
						'height' : $(currentTarget).height()
					});
				}
			};
			$(document).on("mousemove", mousemoveEvent);
			var mouseupEvent = function() {
				$(document).off("mousemove", mousemoveEvent);
				$(document).off("mouseup", mouseupEvent);
			}
			$(document).on("mouseup", mouseupEvent);
			if (opts && opts.stopDefault) {
				opts.stopDefault(e);
			}
		});
	},
	DisDrag : function() {
		$(this).attr("isDrag", 0);
		$(this).attr("drag", 0);
	},
	Resize : function(opts) {
		var options={
			mode:{"se-resize":0,"e-resize":1,"s-resize":2}
		};
		var currentTarget = $(this);
		var currentDisTance = 5;
		var resizeMode = 0;
		var isResize = false;
		var isStartResize = false;
		// 创建3个div来实现拖动按钮。
		$(this).append("<div  class='resizable'style='cursor:e-resize;width:7px;right:-5px;height:100%;top:0;z-index:99;position:absolute'></div>");
		$(this).append("<div class='resizable' style='cursor:s-resize;height:7px;bottom:-5px;width:100%;left:0;z-index:99;position:absolute'></div>");
		$(this).append("<div class='resizable' style='cursor:se-resize;width:16px;height:16px;z-index:99;right:1px;bottom:1px;position:absolute'></div>");
		$(this).mousedown(function(e) {
			console.info($( e.target ).closest( ".resizable" ).length < 0);
			if (cancelNodeName.indexOf(e.target.nodeName) >= 0)
				return true;
			if($( e.target ).closest( ".resizable" ).length <=0)
				return true;
			console.info("move");
			var currentDisX = e.pageX - $(this).offset().left;
			var currentDisY = e.pageY - $(this).offset().top;

			

			var offsetWidth = $(this).width() - $(currentTarget).offset().left;
			var offsetHeight = $(this).height() - $(currentTarget).offset().top;
			var rmousemoveEvent = function(event) {
				var currentX = event.clientX;
				var currentY = event.clientY;
				var cursorX = event.pageX - currentDisX; // +$(this).offset().left;
				var cursorY = event.pageY - currentDisY; // -$(this).offset().top;
				var resizeMode=options.mode[$(e.target).css("cursor")];
				if (resizeMode == 0)
					$(currentTarget).css("height", cursorY + offsetHeight + "px").css("width", cursorX + offsetWidth + "px");
				else if (resizeMode == 1)
					$(currentTarget).css("width", cursorX + offsetWidth + "px");
				else
					$(currentTarget).css("height", cursorY + offsetHeight + "px");
				if (opts && opts.resize) {
					opts.resize(event, {
						'width' : $(currentTarget).width(),
						'height' : $(currentTarget).height()
					});
				}
			};
			$(document).on("mousemove", rmousemoveEvent);
			var rmouseupEvent = function(event) {
				$(document).off("mousemove", rmousemoveEvent);
				$(document).off("mouseup", rmouseupEvent);
			};
			$(document).on("mouseup", rmouseupEvent);
			e.preventDefault();
		});
	}
});

$(function() {
	$("#dragDiv").Drag();
	$("#dragDiv").Resize();
});


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值