You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:26:07