web前端:map area的popover解决方案
最近做一个页面掉到奇怪的坑里,使用bootstrap 2.x的popover插件,可是popover出现的地方不对,而且firefox和chrome、ie各自的表现还不一样,firefox是在父元素img的周围,稍微调调位置还能正常显示,chrome和ie里面就整个页面乱跑了,完全无解。
后来研究了一下,原来是问题出在map area上面,图片热点map area是设计切图以及一些将图片输出为html的常见手段,但是浏览器对area的支持并不完善,无法获取area的位置和尺寸,于是popover自然也不能确定该元素的位置,只能到处乱跑了。
网上有人写了一个用js获取area的位置和尺寸的插件,我将其扩展了一下,现在可以很方便的为area调用bootstrap的popover插件了。
以下是代码:
/* =========================================================== * area-popover.js v1.0.0 * author: pockry * dependent: jQuery 1.x, Bootstrap 2.x(include the tooltip & popover plugin) * ========================================================== */ var getMapAreaBox = function (area) { // parse var ret = { left: 0, top: 0, width: 0, height: 0 }; var shape = area.attr('shape').toLowerCase(), coords = area.attr('coords').split(','); for (var len = coords.length, i = 0; i < len; i++) { coords[i] = parseInt(coords[i], 10); } // generate if (shape === 'rect' || shape === 'rectangle') { ret.left = Math.min(coords[0], coords[2]); ret.top = Math.min(coords[1], coords[3]); ret.width = Math.abs(coords[2] - coords[0]); ret.height = Math.abs(coords[3] - coords[1]); } else if (shape === 'circ' || shape === 'circle') { var radius = coords[2], x = coords[0], y = coords[1]; ret.left = (x - radius); ret.top = (y - radius); ret.width = (radius * 2); ret.height = (radius * 2); } else if (shape === 'poly' || shape === 'polygon') { var x = [], y = []; for (var len = coords.length, i = 0; i < len; i++) { if (i % 2 === 0) { x.push(coords[i]); } else { y.push(coords[i]); } } ret.left = Math.min.apply(null, x); ret.top = Math.min.apply(null, y); ret.width = Math.max.apply(null, x) - ret.left; ret.height = Math.max.apply(null, y) - ret.top; } // fix var map = area.closest('map'); if (map.length > 0) { var img = $('img[usemap~="#' + map.attr('name') + '"]'); if (img.length === 0) { img = $('img[usemap~="#' + map.attr('id') + '"]'); } var pos = img.offset(); if (pos) { ret.top += pos.top; ret.left += pos.left; } } // ret return ret; }; var areaPopover = function(areaClass,place){ var areabox=$("."+areaClass); var box=getMapAreaBox(areabox); switch(place){ case 'top': var boxX=box.left+box.width/2-$('.popover').width()/2; var boxY=box.top-$('.popover').height()-14; $('.popover').offset({top:boxY,left:boxX}); break; case 'left': var boxX=box.left-$('.popover').width()-15; var boxY=box.top+box.height/2-$('.popover').height()/2; $('.popover').offset({top:boxY,left:boxX}); break; case 'bottom': var boxX=box.left+box.width/2-$('.popover').width()/2; var boxY=box.top+box.height+11; $('.popover').offset({top:boxY,left:boxX}); break; case 'right': var boxX=box.left+box.width+11; var boxY=box.top+box.height/2-$('.popover').height()/2; $('.popover').offset({top:boxY,left:boxX}); break; }; };
这个插件依赖于jQuery和Bootstrap,建议用jQuery 1.x和Bootstrap 2.x,Bootstrap需要引入其Tooltip和Popover插件。
然后在页面上就只需要引入该插件并设置一些参数了:
$(function(){ var options={ animation:true, trigger:'hover' }; $('area').popover(options); $('.areaClass').hover(function(){areaPopover("areaClass","place");}); });
这段代码其中上半部分是bootstrap popover的参数,下半部分就是我们的插件,里面有两个参数:
areaClass:你为该area设置的Class;
place:就是popover的四个方向,取值为 top|left|bottom|right
至于area的设置,则和bootstrap的popover一样:
<area shape="circle" coords="46,84,33" href="#7" data-placement="left" title="移动阅读大战" data-content="以网易为代表的传统门户在移动时代也不好过,虽然推出了新闻客户端,但今日头条、Zaker等新闻阅读应用也正在侵蚀它们的生存空间。" class="wangyi" />
插件效果: