2010-07-30 116 views
9

我想知道如果它可能使下面的代碼更簡潔:多個選擇器或多個功能 - 任何效率增益?

$('#americasTrigger').hover(
    function() { 
      $('#americasImg').fadeIn() 
     }, 
    function(){ 
      $('#americasImg').fadeOut() 
    } 
); 

$('#europeTrigger').hover(
    function() { 
     $('#europeImg').fadeIn(); 
    }, 
    function(){ 
     $('#europeImg').fadeOut(); 
    } 
);  

$('#middleEastTrigger').hover(
    function() { 
     $('#middleEastImg').fadeIn(); 
    }, 
    function(){ 
     $('#middleEastImg').fadeOut(); 
    } 
);  

//More etc 

國名保持每個相同的,與「觸發」或「圖」添加到末尾。這裏有很多重複,這表明我不會採用這種最佳方式。

我有想法圍繞:

  • Crearting一個的情況下,或
  • 不知怎的讓選擇被用於選擇,使其成爲一個字符串,分裂它捕捉到該國在使用和應用名稱對於嵌套的淡入/淡出功能,最後使用'Img'。

這是可能的還是我太過幻想?

編輯1:非常感謝所有的答覆,不發佈html的道歉,我把這個波紋管。 總之,我使用bg圖像(地球)上的圖像地圖作爲懸停觸發器來淡入/淡出我絕對定位的懸停圖像。

<div class="mapTub"> 

    <img src="images/transparentPixel.png" class="mapCover" usemap="#worldMap" width="524px" height="273px"/> 

    <map name="worldMap" id="worldMap"> 
    <area id="americasTrigger" shape="poly" coords="1,2,3" href="#americas" /> 
    <area id="europeTrigger" shape="poly" coords="4,5,6" href="#europe" /> 
    <area id="middleEastTrigger" shape="poly" coords="7,8,9" href="#middleEast" /> 
    </map> 

<img src="images/International_americas_dark.png" class="americas" id="americasImg" /> 
<img src="images/International_europe_dark.png" class="europe" id="europeImg" /> 
<img src="images/International_middleEast_dark.png" class="middleEast" id="middleEastImg" /> 

</div> 

Reigel的答案似乎是要走的路在這裏,虐待嘗試一下回來報告,進一步的評論歡迎! :)

+1

html代碼請... – Reigel 2010-07-30 06:24:29

+0

是的,你的HTML看起來像一些例子會有所幫助。 – belugabob 2010-07-30 10:00:53

回答

2

我,沒有HTML知識,表明這...

$('#americasTrigger, #europeTrigger, #middleEastTrigger').hover(
    function() { 
     var id = this.id; 
     $('#'+id.replace('Trigger', 'Img')).fadeIn(); 
     //$('#'+id.slice('0',id.indexOf('Trigger'))+'Img').fadeIn(); 
    }, 
    function(){ 
     var id = this.id; 
     $('#'+id.replace('Trigger', 'Img')).fadeOut(); 
     //$('#'+id.slice('0',id.indexOf('Trigger'))+'Img').fadeOut(); 
    } 
); 

您還可以使用.replace()通過在下面的評論Anurag的建議......


id ='europeTrigger'; 
alert(id.slice('0',id.indexOf('Trigger'))); // alerts 'europe' 
// '#'+id.slice('0',id.indexOf('Trigger'))+'Img' is '#europeImg' 

demo

+0

你可以用'id.replace('Trigger','Img')代替' – Anurag 2010-07-30 06:34:11

+0

@Anurag哈哈很好!等待,更新... – Reigel 2010-07-30 06:37:57

+0

不錯的一個Reigel,這工作得很好,謝謝! – demolish 2010-08-02 04:25:46

2

因爲它看起來像你只訪問unique ids,你最好的選擇是使用一個lookup table國際海事組織。

var lookmeup = [ [$('#americasTrigger'), $('#americasImg')], 
        [$('#europeTrigger'), $('#europeImg')], 
        [$('#middleEastTrigger'), $('#middleEastImg')] 
       ]; 

$.each(lookmeup, function(index, element){ 
    element[0].hover(function(){ 
     element[1].fadeIn(); 
    }, function(){ 
     element[1].fadeOut(); 
    }); 
}); 

幹!全做完了!

另一種更有效的方法是使用event delegation

如果所有hover元素具有相同的TAG,這種方法可能是有用的:

$(document.body).delegate('div', 'mouseenter', function(e){ 
    $('#' + e.target.id.replace(/Trigger/, 'Img')).fadeIn(); 
}); 

$(document.body).delegate('div', 'mouseleave', function(e){ 
    $('#' + e.target.id.replace(/Trigger/, 'Img')).fadeOut(); 
}); 

假設所有的「hoverable」元素爲DIV秒。你仍然應該給這些元素classname,以便只有這些特定的元素是針對性的。

root element限制爲delegate()是很有意義的。在這裏我使用document.body這將.live()做。關於.delegate()的好處是,如果您的懸停元素共享一個父節點,則可以在該節點上應用delegate()。以這種方式減少綁定的事件處理程序的數量

(2而不是6)。

+0

嘿jAndy,這看起來也不錯,我剛剛在原始操作中發佈了html代碼,你有沒有關於你的取消方法vs Reigal的slice/replace方法在性能方面有什麼想法? – demolish 2010-08-02 01:33:20

0

哈哈,看起來像這可能是大約相同的尺寸或比你的代碼更長,但絕對乾燥。

感謝@Andy使用$(..).each指出以前版本的性能損失。

var regions = ['americas', 'europe', 'middleEast']; 

$.each(regions, function(region) { 
    var trigger = id(region, 'Trigger'); 
    var image = id(region, 'Image'); 

    $(trigger).hover(
     effect(image, 'fadeIn'), 
     effect(image, 'fadeOut'), 
    ); 
}); 

function effect(selector, method) { 
    return function() { 
     $(selector)[method](); 
    }; 
} 

function id(prefix, suffix) { 
    return '#' + prefix + suffix; 
} 

如果你可以改變HTML,我將編碼所有的知識到頁面中,僅僅使用jQuery設置懸停事件。

<div class='trigger' data-image='#americasImg'> 
    .. 
</div> 
<div class='trigger' data-image='#europeImg'> 
    .. 
</div> 

的Javascript

function imageId(elem) { 
    return $(elem).attr('data-image'); 
} 

// Using the fade function from before 
$('.trigger').hover(
    effect(imageId(this), 'fadeIn'), 
    effect(imageId(this), 'fadeOut') 
); 
+0

我會使用'$ .each()',不需要額外的jQuery構造函數。作爲第一個參數的下劃線是非常特殊的技巧還是錯字? :) – jAndy 2010-07-30 07:01:25

+0

@jAndy - 感謝您的提示。我從來沒有意識到性能的損失。 (只是不喜歡'$ .each'的外觀,但我想它是一個必要的邪惡:)。下劃線只是表示參數無用的信號。 – Anurag 2010-07-30 07:05:01

0

或者,爲了讓事情簡單得多,添加標記類,稱爲「fadingImage」例如,在每個圖像,然後使用此代碼...

$('.fadingImage').hover( 
    function() { 
     $(this).fadeIn() 
    }, 
    function(){ 
     $(this).fadeOut() 
    } 
); 

這是有效的,因爲所有的圖像,不管他們的id,都以相同的方式處理,你真的需要做的是識別你的頁面上的哪些圖像需要懸停處理程序連接, s是用標記類完成的。如果它們不用於其他任何事情,你甚至可以完全免除這些ID。

更新: 沒有,我已經醒了(感謝jAndy & Reigel!),我將修改我的職位,以應付的事實,該元件爲懸停不是正在消失的一個。

沒有任何樣本標記,我將不得不作出一些假設,但原始海報可能想要提供真正的標記,以便將事物置於上下文中。

<div> 
    <span class="fadingTrigger">first text to hover over<span> 
    <img class="fadingImage" src="..." alt="first image to be faded"/> 
<div> 
<div> 
    <span class="fadingTrigger">second text to hover over<span> 
    <img class="fadingImage" src="..." alt="second image to be faded"/> 
<div> 

$('.fadingTrigger').hover( 
    function() { 
     $(this).parent().find(".fadingImage").fadeIn() 
    }, 
    function(){ 
     $(this).parent().find(".fadingImage").fadeOut() 
    } 
); 

取決於標記結構,發現與fadingTrigger相關聯的可具有改變的,但通過具有一些明確定義的結構的fadingImage的方法中,它應該是可靠的。

爲什麼我更喜歡這種方法,而不是使用ID數組來查找元素,因爲對標記的任何添加都需要對javascript進行更改 - 如果標記是動態生成的,這會特別有問題。 JavaScript也可以動態生成,以包含適當的值數組,但會違反DRY主體。

+0

+1更簡化=) – 2010-07-30 08:09:30

+0

這是行不通的,因爲OP使用不同的元素/ ids來懸停。 – jAndy 2010-07-30 08:25:28

+0

是的,但他沒有必要這樣做 - 他甚至承認,他的代碼是非常重複的。 – belugabob 2010-07-30 08:36:36