ul li表格拖拽、吸附功能

前言

最近,面试遇到了一家用ul li做table的,里面有悬浮十字、div拖拽和吸附等一些功能,回到了家里,就想着自己实现一下。

然后,我做的可能比较难看= =,主在功能嘛,谅解谅解

首先,我们先布局,效果如下:


( ‘-ωก̀ )不要太鄙视楼主的审美

**********************************我是华丽的分割线********** *******************************************

其实就是8个ul套装8个li,布局什么的相对简单


下边贴出HTML + CSS的代码:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		* {
			padding: 0;
			margin: 0;
		}

		ul {
			width: 496px;
		}

		ul li {
			list-style: none;
			width: 60px;
			height: 60px;
			border: 1px solid red;
			float: left;
		}
		/*清除浮动*/

		ul::after {
			content: "";
			clear: both;
			display: block;
		}

		.bg {
			background: skyblue;
		}

		.bg2 {
			position: absolute;
			background: red;
			width: 60px;
			height: 60px;
		}
	</style>
</head>

<body>
	<div class="div">
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
	</div>
</body>

</html>

接下来,我们要实现的就是 JavaScript

我们需要的实现是:当鼠标移动到某个li的时候,其所在的同一行(即ul)背景会发生改变,同一列的li的背景也会发生改变,移出去的时候则背景变回原来的样子。

也就是下图这样:



从上述描述就可以知道了,我们需要借助mouseovr、mouseout事件啦,(●´∀`)那我们就开始着手写代码吧

$("ul li").on("mouseover", function () {
	var index = $(this).index()
	$(this).parent().addClass("bg")
	$("ul").each(function () {
		$(this).find("li").eq(index).addClass("bg")
	})
})
$("ul li").on("mouseout", function () {
	var index = $(this).index()
	$(this).parent().removeClass("bg")
	$("ul").each(function () {
		$(this).find("li").eq(index).removeClass("bg")
	})
})
这样子,第一个效果就实现啦 ╭(●`∀´●)╯╰(●’◡’●)╮ (●’◡’●)ノ ヾ(*´▽‘*)ノ


接下来,就是要点击li后,在li上创建一个完全遮罩li的div(也就是数据块),然后实现拖拽啦

先上效果图:


首先,我们需要知道点击了哪个li,然后获取元素距离文档的位置,之后在给div定位

有了这样的思路,那我们就可以着手写我们的JavaScript

ps:div必须是绝对定位(absolute)才可以哦

$("ul li").on("click", function (e) {
	var oDiv = $("<div class='bg2'></div>")
	var disY = 0;
	var disX = 0;
	oDiv.css({
		"left": $(this).offset().left + 1,
		"top": $(this).offset().top + 1
	})
	$(".div").append(oDiv)
	oDiv.mousedown(function (ev) {
		disX = ev.pageX - $(this).offset().left;
		disY = ev.pageY - $(this).offset().top;
		$(document).mousemove(function (ev) {
			oDiv.css('left', ev.pageX - disX);
			oDiv.css('top', ev.pageY - disY);
		})
		$(document).mouseup(function (e) {
			$(document).off();
		})
		return false;
	})
})
这里div的(left和top)+1是因为我给li设置了1px的border

到了这里了,我们就可以发现一个问题,我们的div是不吸附在li上的,这里需要怎么做呢?

聪明的小伙伴们,其实一看就知道了,我们可以获取所有li的坐标,然后判断div的坐标距离哪个li近,那就吸附在哪个li上面

那么,有了这个思路,我们就可以实行我们的想法


**********************************我是华丽的分割线********** *******************************************


首先,我们可以先尝试一下简单的坐标怎么取最近的点。

先规定一下我们坐标的格式,posArr=[{x:1,y:2},x:1,y:2},x:1,y:2}]

点的格式(也就是div的坐标)divPos = {x,y}


var posArr = [{
    x: 0,
    y: 0
}, {
    x: 10,
    y: 20
}, {
    x: 20,
    y: 30
}]

var divPos  = {
    x: 1,
    y: 2
}

var result = {
    index: 0 //数组索引
}

for (var i = 0; i < posArr.length; i++) {
    var x = posArr[i].x - divPos .x;
    var y = posArr[i].y - divPos .y;
    x = x > 0 ? x : -x;
    y = y > 0 ? y : -y;
    var temp = x + y;
    //第一次进来赋值
    if (i == 0) { 
        result.x = i;
        result.y = temp;

    } else {
        if (result.y > temp) {
            result.index = i;
            result.y = temp;
        }
    }
}
console.log(arr[result.index].x);
console.log(arr[result.index].y);

从这里,我们可以获取到这个点的x坐标和y坐标,这样子,就可以实现我们上面的想法了


整个代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		* {
			padding: 0;
			margin: 0;
		}

		ul {
			width: 496px;
		}

		ul li {
			list-style: none;
			width: 60px;
			height: 60px;
			border: 1px solid red;
			float: left;
		}
		/*清除浮动*/

		ul::after {
			content: "";
			clear: both;
			display: block;
		}

		.bg {
			background: skyblue;
		}

		.bg2 {
			position: absolute;
			background: red;
			width: 60px;
			height: 60px;
		}
	</style>
	<script src="https://cdn.bootcss.com/jquery/2.2.1/jquery.min.js"></script>

</head>

<body>
	<div class="div">
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
	</div>

	<script>
		var posArr = []
		for (var i = 0; i < $("ul li").length; i++) {
			posArr.push({
				x: $("ul li").eq(i).offset().left,
				y: $("ul li").eq(i).offset().top
			})
		}


		$("ul li").on("mouseover", function () {
			var index = $(this).index()
			$(this).parent().addClass("bg")
			$("ul").each(function () {
				$(this).find("li").eq(index).addClass("bg")
			})
		})
		$("ul li").on("mouseout", function () {
			var index = $(this).index()
			$(this).parent().removeClass("bg")
			$("ul").each(function () {
				$(this).find("li").eq(index).removeClass("bg")
			})
		})
		$("ul li").on("click", function (e) {
			var oDiv = $("<div class='bg2'></div>")

			oDiv.css({
				"left": $(this).offset().left + 1,
				"top": $(this).offset().top + 1
			})
			$(".div").append(oDiv)
			var disY = 0;
			var disX = 0;
			oDiv.mousedown(function (ev) {
				var result = {
					index: 0
				}
				disX = ev.pageX - $(this).offset().left;
				disY = ev.pageY - $(this).offset().top;
				$(document).mousemove(function (ev) {
					oDiv.css('left', ev.pageX - disX);
					oDiv.css('top', ev.pageY - disY);
				})
				$(document).mouseup(function (e) {

					for (var i = 0; i < posArr.length; i++) {
						var x = posArr[i].x - oDiv.offset().left;
						var y = posArr[i].y - oDiv.offset().top;
						x = x > 0 ? x : -x;
						y = y > 0 ? y : -y;
						var temp = x + y;
						if (i == 0) { //第一次进来赋值
							result.x = i;
							result.y = temp;
						} else {
							if (result.y > temp) {
								result.index = i;
								result.y = temp;
							}
						}
					}
					oDiv.css('left', posArr[result.index].x + 1);
					oDiv.css('top', posArr[result.index].y + 1);
					$(document).off();
				})
				return false;
			})
		})

	</script>
		
</body>

</html>

后记

这里用了jquery也是为了方便操作DOM,里面有些样式也是为了方便(图做个笔记),写的相当不规范,请各位观众老爷谅解
写的不好,请各位大神见谅,有什么错误也忘指出 ε٩ (๑> 灬 <)۶з

另外这里没有做边界检测,有兴趣的小伙伴可以自己尝试做一下,也是相对简单

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值