2012-08-08 89 views
0

所以我有一個表單提交照片(總共8個),和我想申請一個小的影響:一旦你選擇一張照片,該按鈕可隱藏和文件名與'X'一起顯示以刪除其選擇。jQuery的事件被稱爲多次

然而,當我添加多張照片,並嘗試刪除一個,該事件被稱爲多次,越我點擊,更多的多個事件被觸發,都來自相同的元素。

任何人都可以弄明白嗎?

var Upload = { 
    init: function (config) { 
     this.config = config; 
     this.bindEvents(); 
     this.counter = 1; 
    }, 

    /** 
    * Binds all events triggered by the user. 
    */ 
    bindEvents: function() { 
     this.config.photoContainer.children('li').children('input[name=images]').off(); 
     this.config.photoContainer.children('li').children('input[name=images]').on("change", this.photoAdded); 
     this.config.photoContainer.children('li').children('p').children('a.removePhoto').on('click', this.removePhoto); 
    }, 

    /** 
    * Called when a new photo is selected in the input. 
    */ 
    photoAdded: function (evt) { 
     var self = Upload, 
      file = this.files[0]; 
     $(this).hide(); 
     $(this).parent().append('<p class="photo" style="background-color: gray; color: white;">' + file.name + ' <a class="removePhoto" style="color: red;" href="#">X</a></p>'); 

     if(self.counter < 8) { // Adds another button if needed. 
      Upload.config.photoContainer.append('<li><input type="file" name="images"></li>'); 
      self.counter++; 
     } 
     Upload.bindEvents(); 
    }, 

    /** 
    * Removes the <li> from the list. 
    */ 
    removePhoto: function (evt) { 
     var self = Upload; 
     evt.preventDefault(); 

     $(this).off(); 
     $(this).parent().parent().remove(); 

     if(self.counter == 8) { // Adds a new input, if necessary. 
      Upload.config.photoContainer.append('<li><input type="file" name="images"></li>'); 
     } 
     self.counter--; 
     Upload.bindEvents(); 
    } 
} 

Upload.init({ 
    photoContainer: $('ul#photo-upload') 
}); 
+0

每次點擊按鈕觸發事件時,它是否增加1? – Alfabravo 2012-08-08 16:33:15

+0

看來,在'bindEvents'方法中,您的綁定事件不是需要更改的一個元素,而是所有元素。也許這會導致問題。 – tijs 2012-08-08 16:38:57

+0

它的確增加了1,並且同一個元素一次又一次地被觸發。無論如何謝謝你 – 2012-08-08 16:58:49

回答

2

從我所看到的,你試圖附加/刪除基於用戶選擇什麼樣的事件處理程序。這是低效的,容易出錯。

在你的情況,你在呼喚每次添加照片時間Upload.bindEvents(),不清洗所有以前的處理程序。你可能會調試,直到你不再泄漏事件監聽器,但它不值得。

jQuery.on是非常強大的,可以讓你處理程序附加到尚未在DOM元素。你應該能夠做這樣的事情:

init: function (config) { 
    this.config = config; 
    this.counter = 1; 
    this.config.photoContainer.on('change', 'li > input[name=images]', this.photoAdded); 
    this.config.photoContainer.on('click', 'li > p > a.removePhoto', this.removePhoto); 
}, 

您附加一個處理程序photoContainer,這將捕獲所有事件,從孩子向上冒泡,這與加入時,他們的。如果要禁用其中一個元素的處理程序,則只需刪除removePhoto類(以使其與篩選器不匹配)。

+0

感謝您的回答,解決了問題並改進了代碼。 – 2012-08-08 16:59:44

2

你正在做很多事情:Upload.bindEvents();

您需要先解除綁定這些'li'的事件,再重新綁定它們。否則,您將添加更多點擊事件。這就是爲什麼你看到越來越多的點擊被觸發。

+0

感謝您指出,它確實解決了這個問題。我忘了添加一個,只添加到輸入。 – 2012-08-08 16:59:24