前言
最近,面试遇到了一家用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>