如何修复JavaScript中回车与点击image map的弹窗位置差异问题
解决Image Map回车触发弹窗位置异常的问题
问题核心:点击image map区域时,openBubble依赖鼠标事件的clientX/clientY定位弹窗;但通过Tab聚焦后按回车触发时,事件并非鼠标操作,clientX/clientY值为0,导致弹窗显示在页面左上角。
修复步骤
- 给所有area元素添加
tabindex="0",确保无href的区域也能通过Tab聚焦,保障可访问性。 - 修改
openBubble函数,兼容键盘触发场景:判断事件类型,若为键盘触发,则通过元素的getBoundingClientRect()获取位置,计算弹窗坐标,和鼠标点击时的显示逻辑对齐。 - 补全函数的event参数,确保能正确接收事件对象。
修改后的完整代码
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);" tabindex="0"> <area id="mouth" coords="121,84,198,118" shape="rect" tabindex="0"> </map> <div id="myBubble"> <div id="myBubbleContent"></div> <div id="myBubbleCloseButton">✕</div> </div> </div>
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'); // 绑定点击事件 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>'; let top, left; // 区分鼠标点击和键盘触发 if (event.clientX !== 0 && event.clientY !== 0) { top = event.clientY - 20; left = event.clientX - 200; } else { // 键盘触发时,获取元素位置计算弹窗坐标 const rect = this.getBoundingClientRect(); top = rect.top + (rect.height / 2) - 20; left = rect.right - 200; } bubble.style.top = top + "px"; bubble.style.left = left + "px"; bubble.className = 'shown'; } function closeBubble() { bubble.className = ''; }
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; width: 40%; } #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:20%; } #myBubble.shown:before{ content: ""; position: absolute; top: 20px; left:-30px; z-index: 1; border: solid 15px transparent; border-right-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; }
内容的提问来源于stack exchange,提问作者newuser
相关产品推荐
相关产品推荐

