【问题标题】:ImageMapster: how to synchronize two image maps?ImageMapster:如何同步两个图像映射?
【发布时间】:2012-05-01 20:56:17
【问题描述】:

我在页面上有两个相同图像映射的副本。 它们有不同的 ID,使用相同的图像文件和地图信息。

现在只有第二张地图可以正常工作,如果我突出显示\单击第一张地图 - 更改仅适用于第二张地图,而不是两者。

我需要两个图像地图同步工作:因此当您移动鼠标\单击其中一个地图时,突出显示和选择将同时在它们上工作。

我该怎么做?

代码在我的页面头部:

<script src="jquery-1.6.2.min.js" type="text/javascript"></script>
<script src="jquery.imagemapster.min.js" type="text/javascript"></script>

<script type="text/javascript">
$(document).ready(function() {

    function state_change(data) {   }

    $("#map_mini,#map_full").mapster({
        singleSelect: true,
        isDeselectable: false,

        fill: true,
        fillColor: 'ff0000',
        fillOpacity: 0.5,       

    //  onStateChange: state_change,
    });
});
</script>

代码在我的页面的正文中:

<map name="map">
  <area shape="rect" group="rect" alt="" coords="25,38,102,104" href="#" /-->
  <area shape="circle" group="circle" alt="" coords="185,160,30" href="#" /-->
  <area shape="poly" group="poly" alt="" coords="230,62,237,25,276,20,291,55,264,80,230,62" href="#" /-->
</map> 

<h1>MAP1</h1>
<img src='map.png' width='320' height='240' id='map_full' usemap="#map">
<h1>MAP2</h1>
<img src='map.png' width='320' height='240' id='map_mini' usemap="#map">

【问题讨论】:

    标签: jquery imagemap synchronize imagemapster


    【解决方案1】:

    这并不难,但有几点需要注意。工作示例在这里:

    http://jsfiddle.net/gCTcF/

    更新:原始示例仅适用于一种方式,此示例适用于两种方式,最后讨论。

    http://jsfiddle.net/UrNsH/

    1) 您不能将两个图像绑定到同一个图像映射,因为 ImageMapster 将区域视为唯一标识符。所以只需制作一个副本并将第二张图像绑定到副本:

    var map = $('map[name="map"]'),
        clone = map.clone().attr('name', 'map2'),
        image2 = $('#map_mini');
    
    map.after(clone);
    image2.attr('usemap', '#map2');
    

    2) 您的方向正确,您需要使用stateChange 来同步地图。从该事件发送的数据并不能完全转换为您需要在另一个地图上调用的代码,因此请根据事件使用一些逻辑来进行正确的调用:

    function state_change(data) {
        if (data.state=='highlight')
        {   
            // add or remove a highlight to the alternate image. the syntax to add vs.
            // remove a highlight is a little different (you don't need to specify where
            // you're removing - there can be only one highlight) so easiest to use two
            // different statements for add vs. remove.
    
            if (data.selected) {
                image2.mapster('highlight',data.key,true);
            } else {
                image2.mapster('highlight',false);
            }
    
        } else if (data.state=='select') {
    
             // add or remove the "selected" state to the alternate image.
             // the syntax is the same to add and remove (unlike highlight) so you
             // just need one statement.
    
             image2.mapster('set', 
                       data.selected,
                           data.key);
        }
    }
    

    3) 创建两个地图将共享的选项的变量,并使用控制另一个地图的stateChange 事件扩展它。这将进行单向同步。如果您希望它以两种方式同步,则需要复制 stateChange 函数,或者添加一个参数,以便它知道应该对哪个映射进行操作。 (如果您只是将两个地图绑定到同一个事件,则在从它所针对的同一个地图执行操作时会导致无限循环。

    var options = {
        singleSelect: true,
        isDeselectable: false,
    
        fill: true,
        fillColor: 'ff0000',
        fillOpacity: 0.5
    };
    $('#map_mini').mapster(options);
    $("#map_full").mapster(
    $.extend({}, options, {
        onStateChange: state_change
    }));
    

    希望对您有所帮助。

    更新:

    要让它像您发现的那样双向工作,您必须防止递归。

    更新示例:http://jsfiddle.net/UrNsH/

    首先,在开头创建对两个图像的引用:

    var image1 = $('#map_full'),image2 = $('#map_mini');
    

    state_change函数中,使用一个标志来表示代码当前正在改变状态。这样,当state_change 由于它自己的操作而再次触发时,它将知道不会启动另一个事件。这非常简单:在函数外部创建一个变量以用作标志。您要做的第一件事是检查您当前是否正在“改变”,如果是,请退出。如果不是,请在开始对第二张图片执行操作之前将“更改”标记为 true。

    现在发生的另一件事是您需要确定要对哪个图像进行操作。这个逻辑很简单:它是鼠标事件不是的来源。您只需要检查this 是图像本身并选择不是this 的图像。

    您会注意到我将thisimage1[0] 进行比较。这是 jQuery 经常出现的问题。 this 是一个实际的 DOM 元素,而 image1image2 是 jQuery 对象。 jQuery 对象是array-like。因此,要访问作为选择器一部分的实际 DOM 元素,您必须使用索引。 image1[0]image1 的第一个(也是唯一一个)成员,当第一个图像是事件的源时,它将匹配 this

    var changing = false;
    
    function state_change(data) {
    
        // prevent recursion: exit if already inside this function  
    
        if (changing) return;
    
        // set the flag that work is in progress so if something calls this while 
        // we're busy syncing, it won't try to start again (creating endless recursion)
    
        changing = true;
    
        // switch the image that's not this one.
    
        var target = this===image1[0] ? 
                         image2 : 
                         image1;
    
        // this part is the same as before
    
        if (data.state=='highlight'){
            if (data.selected) {
                target.mapster('highlight',data.key,true);
            } else {
                target.mapster('highlight',false);
            }
        } else if (data.state=='select') {
             target.mapster('set', data.selected, data.key);
        }
    
        changing=false;
    }
    

    应该这样做!

    【讨论】:

      【解决方案2】:

      (这里是关于双向同步问题的通知。 这个通知已经没有理由了,jamietre更新了他的unswer之后,所以我删除了它)

      【讨论】:

      • 是的,我不确定您是否希望它是双向的。这是您的示例的更新,它可以双向工作,我也更新了我的答案。 jsfiddle.net/UrNsH
      • 非常感谢!现在它真的是我需要的!希望 jsfiddle.net 上的代码永远保持活跃,并帮助遇到同样问题的人。
      • JsFiddle 到目前为止一直很成功,我的东西已经存在了将近两年。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2021-10-28
      • 1970-01-01
      相关资源
      最近更新 更多