如何让Image Map弹出框显示在左侧而非右侧?
问题
我正在开发一个基于Image Map的项目,使用JavaScript和CSS实现图片区域弹出框。目前弹出框默认显示在图片区域的右侧,我希望部分位于图片右侧的区域,其弹出框能显示在左侧,请问该如何实现?
解决方案
要实现弹出框根据区域位置自动切换左右显示,需要从位置计算和样式调整两方面入手:
1. 计算区域与视口的位置关系
通过获取点击区域的边界坐标,对比视口宽度判断弹出框的显示方向:
- 获取图片在视口中的实际位置和尺寸
- 解析
<area>标签的coords属性,得到区域的右边界坐标 - 若区域右边界加上弹出框宽度超出视口宽度,则将弹出框显示在左侧
2. 动态调整弹出框位置和箭头样式
- 根据位置判断结果,切换弹出框的
left/right定位属性 - 通过额外的CSS类,切换弹出框的箭头方向(左侧箭头/右侧箭头)
修改后的JavaScript代码
$(function() { $('.map').maphilight(); }); var myData = { "left-eye": { "title": "", "image":"", "description": "Lorem ipsum A dolor sin amet. ." }, "mouth": { "title": "", "description": "Lorem ipsum B dolor sin amet. Lorem ipsum B dolor sin amet.Lorem ipsum B dolor sin amet.Lorem ipsum B dolor sin amet.Lorem ipsum B dolor sin amet.Lorem ipsum B dolor sin amet.Lorem ipsum B dolor sin amet.Lorem ipsum B dolor sin amet.vLorem ipsum B dolor sin amet.vLorem ipsum B dolor sin amet.Lorem ipsum B dolor sin amet.</p>Lorem ipsum B dolor sin amet." }, }; var areas = document.getElementsByTagName('area'), bubble = document.getElementById('myBubble'), bubbleContent = document.getElementById('myBubbleContent'), bubbleClose = document.getElementById('myBubbleCloseButton'), imageEl = document.getElementById('myImage'); // 绑定区域点击事件 for(var i=0, l=areas.length; i<l; i++) { areas[i].addEventListener('click', openBubble, false); } // 绑定关闭按钮事件 bubbleClose.addEventListener('click', closeBubble, false); function openBubble(event) { var content = myData[this.id]; bubbleContent.innerHTML = '<h3>' + content.title + '</h3>' + '<img src="' + content.image + '" alt="" />' + '<p>' + content.description + '</p>'; // 获取图片的视口位置信息 const imageRect = imageEl.getBoundingClientRect(); // 解析area的坐标,获取区域右边界 const coords = this.coords.split(',').map(Number); const areaRight = imageRect.left + coords[2]; // 弹出框宽度(默认值兼容未渲染的情况) const bubbleWidth = bubble.offsetWidth || 300; const viewportWidth = window.innerWidth; // 判断是否需要显示在左侧 const showOnLeft = (areaRight + bubbleWidth) > viewportWidth; // 切换弹出框样式类 bubble.className = showOnLeft ? 'shown left' : 'shown'; // 设置垂直位置 bubble.style.top = (event.clientY + 10) + "px"; if (showOnLeft) { // 左侧显示:弹出框右边界对齐点击位置左侧 bubble.style.right = (viewportWidth - event.clientX + 10) + "px"; bubble.style.left = 'auto'; } else { // 默认右侧显示 bubble.style.left = (event.clientX + 10) + "px"; bubble.style.right = 'auto'; } } function closeBubble() { bubble.className = ''; bubble.style.left = ''; bubble.style.right = ''; } // 响应式图片地图 imageMapResize(); $.fn.maphilight.defaults = { fill: true, fillColor: '1A8782', fillOpacity: 1, stroke: true, strokeColor: '#1A8782', strokeOpacity: 1, strokeWidth: 1, fade: true, alwaysOn: false, neverOn: false, groupBy: false, wrapClass: true, shadow: false, shadowX: 0, shadowY: 0, shadowRadius: 6, shadowColor: '000000', shadowOpacity: 0.8, shadowPosition: 'outside', shadowFrom: false }
修改后的CSS代码
#myWrapper{ position: relative; font-family: Arial, Helvetica, sans-serif; } #myImage{ display: block; } #myBubble{ background: #fff; border: 1px solid #aaa; padding: .5rem 1rem; display: none; top: 1.5rem; left: 1.5rem; } #myBubble.shown{ position: fixed; display: block; cursor: pointer; font-size: 0.8rem; margin-top: 0.2rem; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.5)); width:70%; } /* 默认右侧弹出的箭头 */ #myBubble.shown:before{ content: ""; position: absolute; top: 20px; left:-30px; z-index: 1; border: solid 15px transparent; border-right-color: #FFF; } /* 左侧弹出的箭头 */ #myBubble.shown.left:before{ left: auto; right: -30px; border-right-color: transparent; border-left-color: #FFF; } #myBubble img{ display: block; width: 100%; } #myBubbleCloseButton{ position: absolute; top: 0; right: 0; padding: .5rem; line-height: 1; cursor: pointer; color: #1A8782; } #myBubbleCloseButton:hover{ color: #1A8782; }
修改后的HTML代码
<script src="https://cdn.rawgit.com/davidjbradshaw/image-map-resizer/master/js/imageMapResizer.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/maphilight/1.4.0/jquery.maphilight.min.js"></script> <div id="myWrapper"> <img id="myImage" src="http://tinypic.com/images/goodbye.jpg" usemap="#myMap" alt="" class="map" /> <map name="myMap" id="myMap"> <area id="left-eye" coords="118,36,148,80" shape="rect" href="javascript:void(0);"> <area id="mouth" coords="121,84,198,118" shape="rect"> </map> <div id="myBubble"> <div id="myBubbleContent"></div> <div id="myBubbleCloseButton">✕</div> </div> </div>
内容的提问来源于stack exchange,提问作者newuser
相关产品推荐
相关产品推荐

