2012-05-01 5 views
2

У меня есть две копии одной и той же карты изображений на странице. У них разные идентификаторы, используйте один и тот же файл изображения и информацию о карте.ImageMapster: как синхронизировать две карты изображений?

Теперь только вторая карта работает правильно, если выделить 1 клик на первой карте - изменения применяются только ко второй карте, а не к обоим.

Мне нужно, чтобы обе карты изображений работали синхронно: поэтому выделение и выделение будут работать одновременно с обоими из них, когда вы перемещаете мышь \ щелкните на одной из карт.

Как это сделать?

КОД НА ГОЛОВЕ моей страницы:

<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"> 

ответ

2

Это не сложно, но есть несколько вещей, чтобы отметить. Работа пример здесь:

http://jsfiddle.net/gCTcF/

Update: оригинальный пример работает только в одну сторону, этот пример работает два-пути, обсуждение в конце.

http://jsfiddle.net/UrNsH/

1) Вы не можете связать два изображения одной и той же карты изображения, поскольку ImageMapster рассматривает область уникальный идентификатор. Так просто сделать копию и связать 2-ое изображение на копии:

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 
})); 

Надеюсь, что это поможет.

Update:

Чтобы заставить его работать в обоих направлениях, как вы обнаружили, что вам нужно предотвратить рекурсию.

Обновлен пример: http://jsfiddle.net/UrNsH/

Во-первых, создать ссылку на обоих изображениях в начале:

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

В функции state_change, использовать флаг, чтобы указать, что код в настоящее время в процессе изменение состояния. Таким образом, когда state_change снова срабатывает в результате собственного действия, он не узнает, что не начнет другое событие. Это довольно просто: создайте переменную за пределами функцию, используемую в качестве флага. Первое, что вы делаете, это проверить, если вы сейчас «меняете», если так, просто уходите. Если нет, отметьте «change» как true, прежде чем начать действие на втором изображении.

Другое, что происходит сейчас, это то, что вам нужно выяснить, на каком изображении действовать. Эта логика проста: это то, что событие мыши не было от источника. Вам просто нужно проверить , который является самим изображением, и выберите изображение, которое не является this.

Вы увидите, что я сравниваю this с image1[0]. Это что-то очень много с jQuery. this является фактическим элементом DOM, тогда как image1 и image2 являются объектами jQuery. jQuery objetcs: 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; 
} 

Это должно быть сделано!

0

(Здесь был notcie о проблемах с двухсторонним sinchronization. Это уведомление не имеет больше оснований, после jamietre обновил unswer, так что я удалил его)

+0

Да, я не был уверен, что если вы хотите, чтобы это было 2-way вещь. Вот обновление вашего примера, которое работает в обоих направлениях, я также обновил свой ответ. http://jsfiddle.net/UrNsH/ –

+0

Большое спасибо! Теперь это действительно то, что мне нужно! Надеюсь, что код на jsfiddle.net останется активным навсегда и поможет людям, которые могут справиться с такими же проблемами. – DaneSoul

+0

JsFiddle был скалой до сих пор, у меня есть вещи, которые были там почти два года. –

 Смежные вопросы

  • Нет связанных вопросов^_^