JavaScript动态图片热区(绘制多个矩形并分别跳转
前言
不知道大家有没有遇到一张图片上面有很多个商品展示图,需要给每个商品添加一个链接,点击跳转到各自商品详情页。
这个需求在前端其实有一个专业的术语“图像地图”,大家先看看w3c简单示例
<img src="planets.jpg" border="0" usemap="#planetmap" alt="Planets" />
<map name="planetmap" id="planetmap">
<area shape="circle" coords="180,139,14" href ="venus.html" alt="Venus" />
<area shape="circle" coords="129,161,10" href ="mercur.html" alt="Mercury" />
<area shape="rect" coords="0,0,110,260" href ="sun.html" alt="Sun" />
</map>
上图,点击各个星球,会做不同跳转。
基础知识
代码主要是img
标签上的usemap
属性,关联下方的map
标签。map
有多个area
,area
就是点击的区域,coords
是坐标(如矩形x1,y1,x2,y2),shape
是区域类型:
1、圆形(circ 或 circle)
shape=“circle”,coords="x,y,z"
这里的 x 和 y 定义了圆心的位置(“0,0” 是图像左上角的坐标),r 是以像素为单位的圆形半径。
2、多边形(poly 或 polygon)
每一对 “x,y” 坐标都定义了多边形的一个顶点(“0,0” 是图像左上角的坐标)。定义三角形至少需要三组坐标;高纬多边形则需要更多数量的顶点。
多边形会自动封闭,因此在列表的结尾不需要重复第一个坐标来闭合整个区域。
3、矩形(rect 或 rectangle)
shape=“rectangle”,coords="x1,y1,x2,y2"
第一个坐标是矩形的一个角的顶点坐标,另一对坐标是对角的顶点坐标,“0,0” 是图像左上角的坐标。请注意,定义矩形实际上是定义带有四个顶点的多边形的一种简化方法。
进阶
想法
下面我们回到正题:“一张图片上面有很多个商品展示图,需要给每个商品添加一个链接,点击跳转到各自商品详情页”,这个需求上面。
想法:
1、监听鼠标事件,点击记录起点位置,也就是coords
左上角的坐标
2、鼠标移动至松开鼠标,记住最后位置,也就是coords
右下角的坐标
3、这样2个点就是构成一个矩形,然后坐标生成img
标签的map
,实现点击链接
ok,有了想法,开始我们的表演
简单实现
html部分
<body>
<ul id="map-list"></ul>
<img id="img" src="../images/timg.jpg" border="0" usemap="#planetmap" alt="Planets" />
<div id="maparea"></div>
</body>
css部分
* {
padding: 0;
margin: 0;
}
.hot_div {
border: 1px dashed blue;
background: #5a72f8;
position: absolute;
width: 0;
height: 0;
opacity: 0.1;
z-index: 9;
}
#map-list{
position: absolute;
top:0;
z-index: 100;
background: #fff;
cursor: pointer;
}
#maparea{
position: relative;
z-index: 10;
}
js部分
var pointList = []; // 记录所有矩形坐标
window.onload = function() {
document.onmousedown = function(e) {
// 按下鼠标,我们得到起点位置
var posx = e.clientX;
var posy = e.clientY;
// 我们创建一个hot_div来观察框选区域
var div = document.createElement("div");
div.className = "hot_div";
div.id = "hot_div" + pointList.length;
div.style.left = e.clientX + "px";
div.style.top = e.clientY + "px";
document.onmousemove = function(ev) {
// 移动时监听鼠标位置,向hot_div添加left,top,width,height
div.style.left = Math.min(ev.clientX, posx) + "px";
div.style.top = Math.min(ev.clientY, posy) + "px";
// Math.abs是取绝对值
div.style.width = Math.abs(posx - ev.clientX) + "px";
div.style.height = Math.abs(posy - ev.clientY) + "px";
document.onmouseup = function() {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
})
记录矩形坐标
document.onmouseup = function() {
// 选择区域后移除div(不删除点击不了,点击都在这个div上面)
div.parentNode.removeChild(div);
// left,top构成左上角坐标点,left+width,top+height构成右下角坐标点
var point = {
x1: parseInt(div.style.left),
y1: parseInt(div.style.top),
x2: parseInt(div.style.left) + parseInt(div.style.width),
y2: parseInt(div.style.top) + parseInt(div.style.height),
host: 'http://www.baidu.com'
}
// 都记录存起来
pointList.push(point);
// 创建map
createMap();
document.onmousemove = null;
document.onmouseup = null;
}
生成map
function createMap(){
var li = '';
var areaTpl = '';
// 遍历生成模板
pointList.forEach((item, index)=> {
// li主要是生成一个list,用来管理map的
// 可以操作修改链接和删除
li += '<li class="pointli" data-index="'+index+'"> '+
'我是第'+index+'个热区('+(item.host)+'), 点击修改链接 '+
'<span class="delPoint" data-index="'+index+'">删除</span></li>';
// map area模板
areaTpl += '<area '+
'shape="rectangle" '+
'coords="'+item.x1+','+item.y1+','+item.x2+','+item.y2+'" '+
'href ="'+(item.host)+'" '+
'target ="_blank" '+
'alt="web秀" />';
})
// 模板添加到网页中(map和area要同时添加)
$('#map-list').html(li);
$('#maparea').html('<map name="planetmap" id="planetmap">'+areaTpl+'</map>');
}
删除矩形坐标
// 简单“删除”点击事件
$(document).on('click', '.delPoint', function(e){
// status状态主要是用来阻止鼠标按下事件的
status = true;
document.onmousemove = null;
document.onmouseup = null;
// 获取下标
var index = $(this).data('index');
// 删除数组某个对象
pointList.splice(index, 1);
// 重新生成map
createMap();
// 1s后状态重置
setTimeout(function(){
status = false;
}, 1000)
return false;
})
所以需要在onmousedown
添加一行代码
document.onmousedown = function(e) {
// 阻止事件
if (status) {
return;
}
...
...
}
修改热点链接
$(document).on('click', '.pointli', function(e){
status = true;
document.onmousemove = null;
document.onmouseup = null;
var index = $(this).data('index');
let point = pointList[index];
// 弹框提示输入新的链接
var host = prompt("请输入新的链接", point.host);
if (host) {
// 更新数组
point.host = host;
pointList.splice(index, 1, point);
// 重新渲染
createMap();
}
setTimeout(function(){
status = false;
}, 1000)
})
最终演示效果
注意看地址栏地址变化
具体演示地址:Jquery动态图片热区(绘制多个矩形并分别跳转)
共同学习,写下你的评论
评论加载中...
作者其他优质文章