2011-04-25 35 views
5

我有一個簡單的照片庫的代碼已與jquery寫,但我認爲這是一個這麼簡單的事情加載整個庫的矯枉過正。我想在原始的JavaScript。轉換一個簡單的jQuery代碼爲javascript

$('#thumbs').delegate('img','click', function(){ 
    $('#largeImage').attr('src',$(this).attr('src').replace('thumb','large')); 
    $('#description').html($(this).attr('alt')); 
}); 

此外,我想知道我怎麼附加載荷微調這個代碼。謝謝。

jsfiddle

+10

jQuery的座右銘是*寫少,多做*:與您的摘錄等價的簡單Javascript代碼可能會減少至少幾十行,如果希望它跨瀏覽器,則更多。我建議你避免重新發明輪子,包括圖書館,這不是重量級。 – 2011-04-25 12:32:50

+10

快速回答:加載jQuery並不是矯枉過正。 較長的答案:您粘貼的代碼是使用事件委託將單個事件綁定到作用於其所有子img元素的#thumbs。這正是圖書館所擅長的,它不需要編寫大量的樣板代碼來執行此操作。如果你用原生JS寫出它,這4行代碼片段最終可能會超過50。我甚至不知道從哪裏開始。 – 2011-04-25 12:33:20

+1

這些是有效的答案;)爲什麼不發佈它們? – Nix 2011-04-25 12:35:32

回答

9

不使用任何庫,它看起來有點像這樣,當然,還有其他方法來寫:

(function() { 
    var largeImage = document.getElementById('largeImage'), 
     description = document.getElementById('description'); 

    document.getElementById('thumbs').onclick = handleGalleryClick; 

    function handleGalleryClick(event) { 
     var target; 

     event = event || window.event;    // Handle IE difference 
     target = event.target || event.srcElement; // Another one 
     if (target && target.tagName.toUpperCase() === "IMG") { 
      largeImage.src = target.src.replace('thumb', 'large'); 
      description.innerHTML = target.getAttribute('alt'); 
     } 
    } 
})(); 

確保腳本出現在頁面的底部(在關閉body元素之前)或將其包裝在window.onload中,儘管您不會對發生多長時間感到滿意,因爲window.onload在加載所有圖像之後發生。

:我與弗雷德裏克的和約翰的意見同意:這不是矯枉過正加載庫對於這一點,並在jQuery的(和Prototype和YUI)的情況下,你可以load via the Google CDN和使用的東西,你的頁面訪問者可能無論如何已經在他們的緩存中。


更新:在下面的意見,scunliffe指出了一個IE瀏覽器的bug I've blogged in the past可能影響上面,這是奇蹟般地工作圍繞你的jQuery。所以我想這可能是有用的標誌了各種併發症,這個簡單的小腳本有一個好的圖書館會理清你:

  • addEventListenerattachEvent:IE6通過IE8不支持DOM2標準addEventListener,使用微軟自己的attachEvent代替。其實,我在上面踢在此爲簡單起見,只是使用的DOM0 onclick = ...風格,但有一個很好的理由做到這一點:隨着DOM0風格,你只能有每件事件的單個事件偵聽器,並附加另一個將分離前一個。所以我上面的代碼不能很好地與其他人玩,因爲它會移除任何以前的DOM0 click處理程序(並且在上面的代碼運行之後,將被附加的DOM0 click處理程序刪除)。
  • 訪問event對象DOM standard表示event對象作爲其第一個參數傳遞給事件處理程序。相反,IE使用全局的window.event對象。這就是我上面第一個「IE區別」的原因。
  • event對象上的屬性:...與此類似,DOM standard says事件被觸發的實際元素將是target屬性。 IE6到IE8使用srcElement代替。 (還有其他的不同。)因此,我的「另一個」評論。
  • 錯誤解決:這是conflation事情scunliffe指出。上述依靠document.getElementById正常工作,但在IE6和IE7上,它不。它將幾個命名空間混合在一起,而不是僅僅使用id值。

...所以這一切的一切,這個簡單的小腳本,使點相當好,在一般  —和良好庫特別  —庫可以爲您節省時間,讓您的網站廣泛兼容,而且一般都值得他們少花錢。我不知道其他人,但是例如jQuery爲您解決了合作問題,但另一個知名且備受尊敬的庫Prototype則沒有。

(旁註:在我們敲微軟太多了,讓我們記住:attachEventsrcElement可能早於DOM2規範;微軟做了很多在IE5.5和IE6創新的[。他們發明ajax,例如] IE6通過爲  —遠   —在2001年提供最好的瀏覽器,由於對不住歌劇院。這就是說,IE6出來的標準做了之後,在這一點上,從而增加了標準的東西,或者IE7,數年後可能一直是一件值得做的事情!但IE9修復了很多這些東西。)

+0

點擊事件實際上是否會在#thumbs的子img元素上?...並且它也不會對所有未來的子元素img元素...不僅僅是現有的? – scunliffe 2011-04-25 12:46:08

+0

@scunliffe - 實行'delegate',你要聽的根容器,並檢查,看看是否該事件的目標是一個''(因此事件適用於當前和_future_元素)。 – Matt 2011-04-25 12:48:55

+1

@scunliffe:從子元素通過父母等點擊「氣泡」,直到根(除非停止)。因此,通過在'thumbs'容器上鉤住'click',我們就可以處理其中的所有'img'元素(現在和將來添加其他元素時)。這就是jQuery的'delegate'工作原理,這對於標準事件委託來說只是(方便的)語法糖,這正是我上面所做的。 – 2011-04-25 12:49:05

4

你稱之爲簡單,但它做了一些先進的事情。要模擬delegate,您必須在根容器上附加點擊偵聽器,然後檢查是否有任何<img>標記的點擊。

更何況,你必須做的事情一樣使用attachEvent在IE瀏覽器,而不是addEventListener

的代碼看起來是這樣的(未經測試):

function listen(root, callback) { 
    var addEvent = 'attachEvent'; 
    if (typeof window.addEventListener === 'function') { 
     addEvent = 'addEventListener'; 
    } 

    root[addEvent](function (e) { 
     if (/img/i.test(e.target.tagName)) { 
      callback.apply(e.target); 
     } 
    }, false); 
} 

listen(document.getElementById('thumbs'), function() { 
    document.getElementById('largeImage').src = this.src.replace(/thumb/ig, 'large'); 
    document.getElementById('description').src = this.alt; 
}); 

事實上,隨着TJ的帖子下方顯示,我甚至沒有處理所有的IE特性。考慮到它爲你解決的所有瀏覽器問題,jQuery並不過分。