﻿# 在 Firefox 中使用 影像地圖(Image map) 該注意的事

[之前](/post/2008/08/18/Writing-Marquee-and-Banner-Rotate-with-jQuery-Cycle-Plugin)我介紹過一個 [jQuery Cycle Plugin](http://malsup.com/jquery/cycle/) 套件，非常適合用來做跑馬燈或廣告輪播，但是今天我遇到一個跨瀏覽器的問題。我們有做一個網站用到了 [jQuery](http://jquery.com/) 與 [jQuery Cycle Plugin](http://malsup.com/jquery/cycle/)，為了讓 jQuery Cycle 可以在當滑鼠移進廣告看板的範圍時可以先停止輪播，否則使用者可能才剛想要點選廣告時廣告卻換走了的窘境。

如果你的 jQuery Cycle 這樣子宣告：

```
$('#banners').cycle({
    fx: 'fade',
    timeout: 600
});
```

你只要簡單的多加上一個 pause 參數設定即可，如下：

```
$('#banners').cycle({
    fx: 'fade',
    timeout: 600,
    pause: 1
});
```

雖然一個看似簡單的設定，在 IE 中可以正常運作，但在 Firefox 中卻永遠無法停止輪播！

我看了 [jQuery Cycle Plugin](http://malsup.com/jquery/cycle/) 發現他有一行是負責註冊 jQuery 的 hover 事件 ( 即 onmouseover 與 onmouseout 事件 ) 到放置輪播圖片的 DIV 上，如下：

```
$cont.hover(function(){this.cyclePause++;},function(){this.cyclePause--;});
```

但我發現只要滑鼠移進輪播的圖片是會引發 onmouseover 事件，但卻也會立即觸發 onmouseout 事件，我覺得十分詭異，這樣的狀況只有在 Firefox 中會發生。

我原本還以為跟事件觸發順序([Event order](http://www.quirksmode.org/js/events_order.html))有關，一般來說 W3C 定義兩種事件觸發模式：

1.  **捕獲模式 ( Event capturing )** ： 這是一種由外而內的事件觸發順序  
    ![捕獲模式 ( Event capturing )](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/79dac43d4be3292e9f52-image_3.png)
2.  **冒泡模式 ( Event bubbling )**  ：這是一種由內而外的事件觸發順序  
    ![冒泡模式 ( Event bubbling )](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/a17269db8c31d2ba38f4-image_6.png)

但我怎麼想都覺得這邏輯不太對，因為這件事根本跟事件觸發「順序」無關，而是 onmouseout 事件提早被觸發了！

研究了好一番功夫才發現原來跟 **Image Map** 有關，先列出我所使用的 HTML 定義：

```xml
<div id="banners">
	<div><img src='images/Banners/b1.jpg' usemap='#FPMap1' /></div>
	<div><img src='images/Banners/b2.jpg' usemap='#FPMap2' /></div>
	<div><img src='images/Banners/b3.jpg' usemap='#FPMap3' /></div>
</div>

<map id="FPMap1" name="FPMap1">
	<area coords="0, 210, 359, 227"
          href="http://example.com/" shape="rect" />
</map>
<map id="FPMap2" name="FPMap2">
	<area coords="0, 210, 359, 227" 
          href="http://example.com/" shape="rect" />
</map>
<map id="FPMap3" name="FPMap3">
	<area coords="0, 210, 359, 227"
          href="http://example.com/" shape="rect" />
</map>
```

你可以看到我的輪播圖片是採用 Image Map 的方式設定連結，而這就是重點中的重點！

我的 **<div id="banners">** 定義了 onmouseover 與 onmouseout 事件，但是只要遇到元素內的圖片有使用 Image Map 且剛好滑鼠移到 [<map>](http://www.w3schools.com/TAGS/tag_map.asp) 定義的連結上時，在 Firefox 中就會立即觸發 **<div id="banners">** 定義的 onmouseout 事件，以致於我的 jQuery Cycle 圖片輪播永遠不會停！

我覺得這根本就是個 by design 的 defect，一個小問題耗了我將近兩個小時的時間（包括寫這篇文章），真的很討厭。

以後各位在使用 Image Map 時，一定要特別注意這個差異，否則光除錯就會花你一堆時間。

至於 jQuery Cycle 的 [替代方案](http://zh.wiktionary.org/wiki/Workaround)([Workaround](http://en.wikipedia.org/wiki/Workaround)) 就是多加一段程式碼，將事件多註冊一組事件到到所有會用到 [<map>](http://www.w3schools.com/TAGS/tag_map.asp) 的 [<area>](http://www.w3schools.com/tags/tag_area.asp) 上面，如下程式碼：

```javascript
$('#banners').parent().find('area').hover(
    function() { $('#banners').cycle('pause');  },
    function() { $('#banners').cycle('resume'); }
);
```

原本的 jQuery Cycle 宣告並不需要修改，因為在 IE 下還是可以執行的！
