0

所以我有一个提交照片的表格(总共 8 张),我正在尝试应用一个小效果:一旦你选择了一张照片,按钮就会隐藏,文件名会显示出来,并带有一个要删除的“X”它的选择。

但是,当我添加多张照片并尝试删除一张照片时,该事件会被多次调用,并且我点击的次数越多,就会触发更多的多个事件,所有这些事件都来自同一个元素。

任何人都可以弄清楚吗?

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

2 回答 2

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该类(使其与过滤器不匹配)。

于 2012-08-08T16:49:30.730 回答
2

你做了很多: Upload.bindEvents();

在再次绑定它们之前,您需要取消绑定这些 'li's 的事件。否则,您将添加更多点击事件。这就是为什么您会看到越来越多的点击被触发。

于 2012-08-08T16:46:42.107 回答