jquery - 图像映射异常

标签 jquery imagemap

这是一个棘手的问题,我感觉它缺少关于这些图像映射如何工作的知识。无论如何..

问题可见http://luff.redlinestaging.com/index.php?option=com_content&view=article&id=35

JS 代码:

jQuery(document).ready( function() {
    jQuery.get('map.php?country=canada', function(output) {
        jQuery('#map').html( output );
        addClickMap();
    });
}); 

function showState(e) {
    //console.log( jQuery(this).is(':hidden' ) );
    var title = jQuery(this).attr( 'title' );
    var stateClass = '.' + title;
    jQuery(stateClass).addClass( 'hover' );
}

function hideState(e) {
    //console.log( jQuery(this).is(':hidden' ) );
    var title = jQuery(this).attr( 'title' );
    var stateClass = '.' + title;
    jQuery(stateClass).removeClass( 'hover' );
}

function addClickMap() {
    if( jQuery('#canada') ) {       
        jQuery('#canada area').each( function() {
            //jQuery(this).hoverIntent( showState, hideNav );
            jQuery(this).mouseenter( showState );
            jQuery(this).mouseleave( hideState );
            jQuery(this).click( function( e ) {
                e.preventDefault();
            });
        });
    }
}

CSS 代码:

#map {
    width:100%;
}

.map {
    width:100%;
    height:100%;
    position:relative;
}

area {
    position:absolute;
    top:0px;
    left:0px;
    z-index: 1001;
    display:block;
    visibility:visible;
}

.canada {
    background-image:url(/map/map_canada.png);
    background-repeat:no-repeat;
}

.hover {
    display:block !important;
}   

.state {
    position:absolute;
    z-index:2;
    top:0px;
    left:0px;
    display:none;
}

.AB {
    top:375px;
    left:342px; 
}

.BC {
    top: 308px;
    left: 236px;
}

.SK {
    top: 394px;
    left: 406px;
}

.NB {
    top: 550px;
    left: 784px;
}

.MB {
    top: 405px;
    left: 486px;
}

.NT {
    top:198px;
    left: 321px; 
}

.NL {
    top: 380px; 
    left: 765px;
}  

.NU {
    top:-4px;
    left: 397px;
} 

.ON {
    top: 456px;
    left: 535px;
} 

.PE { 
    top: 532px;
    left: 820px;
}

.NS {
    top: 551px;
    left: 811px;
}

.QC {
    top: 364px; 
    left: 655px;
}

.YT {
    top:180px;
    left:243px;
}

Generated HTML dump from PHP for Canada:



    <div class="map canada"> 
        <img src="/map/map_canada.png" usemap="#canada" class="map_canada"/>
                <div class="state AB" style="background-image:url(/map/icons/AB.png); width:107px; height:182px; background-repeat:no-repeat;">
        </div>
            <div class="state BC" style="background-image:url(/map/icons/BC.png); width:143px; height:239px; background-repeat:no-repeat;">
        </div>
            <div class="state MB" style="background-image:url(/map/icons/MB.png); width:112px; height:170px; background-repeat:no-repeat;">
        </div>
            <div class="state NB" style="background-image:url(/map/icons/NB.png); width:56px; height:55px; background-repeat:no-repeat;">
        </div>
            <div class="state NL" style="background-image:url(/map/icons/NL.png); width:170px; height:164px; background-repeat:no-repeat;">
        </div>
            <div class="state NT" style="background-image:url(/map/icons/NT.png); width:189px; height:218px; background-repeat:no-repeat;">
        </div>
            <div class="state NS" style="background-image:url(/map/icons/NS.png); width:83px; height:68px; background-repeat:no-repeat;">
        </div>
            <div class="state NU" style="background-image:url(/map/icons/NU.png); width:372px; height:425px; background-repeat:no-repeat;">
        </div>
            <div class="state ON" style="background-image:url(/map/icons/ON.png); width:207px; height:217px; background-repeat:no-repeat;">
        </div>
            <div class="state PE" style="background-image:url(/map/icons/PE.png); width:39px; height:42px; background-repeat:no-repeat;">
        </div>
            <div class="state QC" style="background-image:url(/map/icons/QC.png); width:216px; height:259px; background-repeat:no-repeat;">
        </div>
            <div class="state SK" style="background-image:url(/map/icons/SK.png); width:97px; height:176px; background-repeat:no-repeat;">
        </div>
            <div class="state YT" style="background-image:url(/map/icons/YT.png); width:118px; height:189px; background-repeat:no-repeat;">
        </div>
        </div>
    <map id="canada" name="canada">
        <area shape="poly" coords="410,552,446,401,500,413,485,568," href="#" title="SK" />
        <area shape="poly" coords="488,568,503,413,552,419,596,463,545,519,542,572," href="#" alt="" title="MB" />
        <area shape="poly" coords="597,466,548,524,546,569,590,589,608,575,641,599,687,629,666,668,700,651,738,619,673,642,691,602,686,589,680,535,655,515,653,485,627,481," href="#" alt="" title="ON" />
    </map>

正如你所看到的,它鼠标悬停得很好,但提前调用了 mouseout 事件,或者提前调用了 mouseleave 事件(任你选择,两者都不起作用)。它有时也不是很敏感,但这与我真正关心的问题是不同的,因为它在鼠标移动时似乎紧接在另一个事件之后触发鼠标悬停和鼠标移出事件。有没有办法让这不那么困惑?

如果无法做到这一点,您认为前进的最佳方法是什么? a)简化设计并使用maphilight b)编写一些非常复杂的函数来根据鼠标位置检测鼠标悬停?将来我们可能希望将自定义图像设计放入每个州/省,因此需要完整的图像显示。

最佳答案

我在您的 hideState 函数中设置了一个断点并查看了这些属性:

  • e.target
  • e.latedTarget

第一个是触发事件的元素。不出所料,这就是这个区域。对于鼠标进入/退出事件,第二个是鼠标移动到的区域。在本例中是:

<div class="state SK hover" 
    style="background-image:url(/map/icons/SK.png); 
     width:97px; height:176px; background-repeat:no-repeat;">
</div>

因此,您在图像映射的顶部覆盖了一系列矩形 DIV。当您显示 DIV 时,在鼠标所在的同一区域中,它会成为最顶层,因此鼠标会退出 area 并进入 div ,从而导致您出现问题正在看到。

为了解决这个问题,您需要确保图像映射始终位于最顶层,但您仍然可以通过它看到 div 元素。您可以通过制作图像的副本并使图像映射透明(但 z-index 高于 div)来实现此目的。基本上,你有 3 层:底部一层是可见图像;第二个是您的 div 元素,顶部一个是图像映射(但完全透明)。标记是这样的:

    <img src="http://luff.redlinestaging.com/map/map_canada.png" 
        class="map_canada" 
        style="position: absolute; left: 0; top: 0">

    <img src="http://luff.redlinestaging.com/map/map_canada.png" 
        usemap="#canada" 
        class="map_canada" 
        style="z-index: 1000; opacity: 0; position: absolute; left: 0; top: 0;">

需要使用position:absolute来将两个图像放在一起。您会注意到第一个没有图像映射。不需要。这只是为了展示:这是您可以看到的背景图像。第二个是图像映射,但 opacity:0 使其不可见,而 z-index:1000 确保它始终位于顶部,即使您稍后将 div 添加为鼠标悬停事件的结果。因此,图像映射仍然具有最高优先级,但它不会隐藏实际图像或将在其后面渲染的 div。

工作示例:

http://jsfiddle.net/eZTV3/

另一种方法是使用ImageMapster这是一个 jquery 插件,可以为您执行此操作,而无需管理每个区域的备用图像。也就是说,您可以为其提供单个替代图像,它将使用每个相应区域的数据来填充高光。网站上的第一个演示就展示了这一点。

关于jquery - 图像映射异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12150932/

相关文章:

javascript - jquery 单击处理程序不关闭菜单中的幻灯片

jQuery ajax/post 响应编码

jQuery 插件 imagemapster 没有做任何事情

jquery - 无法进入图像映射区域

html/javascript : is there a way to dynamically disable/enable image map areas?

jquery - 如何使用图像映射来显示/隐藏特定的 div?

html - 在没有 AJAX 的情况下加载页面的一部分

javascript - 将正确的 jQuery 选择器传递给对象

javascript - 将 JQuery 脚本应用于特定的 GridView

HTML map 和区域未显示