javascript通过构造函数new出来的对象为什么会出现重复多次的现象?

问题可能有些难描述,我大概说一下,现在我们的项目有一个功能,这是一个弹出框,它是动态生成的
图片描述

现在需要在这个基础上加一个搜素功能,不能修改源代码,像这样
图片描述

在搜索框发生changes事件以后,在下方弹出一个列表显示搜索结果,暂时不考虑其他逻辑,目前,需要在动态生成出来的弹出框上增加搜索功能的dom结构,然后实现搜索,于是我想到了用一个构造函数实现,代码如下:

var DirectorSearchModule = (function(){
        
    function DirectorSearch($element, ok){
        var $element = this.$element = $element;  
        this.ok = ok || false;
        this.list = [];
        this.copyData = []
    }

    DirectorSearch.prototype = {
        bind: function(){
            var _this = this;
            if(this.$element.find('a[data-direSearch-Btn]').length>0){
                console.log(111);
                return;
            }
            _this.ulInit();
            _this.ulEvent();
        },
        ulInit: function(){
            var _this = this;
            var direSearchBtnHtml = '<a href="###" data-direSearch-Btn><i class="fa fa-search"></i></a>';
            var direSearchInputHtml = '<section class="direSerachInput" data-direSearch-Input><input class="up" type="text" autofocus="autofocus" placeholder="要搜索的人名" /></section>';
            var direSearchListHTml = '<div class="direSearchList" data-direSearch-List>'
                                        +'<section class="direloading none"><b class="scale1"></b><b class="scale2"></b><b class="scale3"></b><p>正在搜索</p></section>'
                                        +'<ul></ul>'
                                     +'</div>';
            this.$element.find('.modal-title').append(direSearchBtnHtml);
            this.$element.find('.modal-header').append(direSearchInputHtml);
            this.$element.find('.modal-content').append(direSearchListHTml);
        },
        ulEvent: function(){
            var _this = this;
            
            this.$element.find('a[data-direSearch-Btn]').on('click', function(){
                $(this).parents('.modal-title').siblings('.direSerachInput').addClass('active');
            });
            this.$element.find('[data-direSearch-Input] input').on('keyup',function(){
                $(this).removeClass('up');
                _this.$element.find('[data-direSearch-List]').find('ul').html('');
            });
            this.$element.find('[data-direSearch-Input] input').on('blur',function(){
                $(this).addClass('up');
            });
        },
        appendList: function(list){  //这里是出问题的地方
            var _this = this;
            this.list = list;
            
            this.$element.find('[data-diresearch-list]').addClass('active');
            if(this.ok){
                _this.returnOkList();
            }else{
                _this.direLoading();
            } 
        },
        direLoading: function(){
            var _this = this;
            this.$element.find('.direloading').addClass('aniload').removeClass('none');
        },
        returnOkList: function(){
            var _this = this;
            
            //console.log('return list: ' + this.list);
            //console.log('return copyData: ' + this.copyData);
            
            //_this.copyDataFn();  
            this.addUlDataHtml(_this.list);
            console.log('t1');
            
            
            this.$element.find('.direloading').addClass('none').removeClass('aniload');

            //var listlen = this.list.length;
            //var dataList = [];
            
        },
        addUlDataHtml: function(data){
            var _this = this;
            for(var i=0; i<data.length; i++){
                _this.littleAppendList(data[i].name, data[i].job, data[i].department);  
            }
        },
        littleAppendList: function(name, job, department){
            var _this = this;
            this.$element.find('[data-direSearch-List]').find('ul').append('<li>'
                                +'<section class="row">'
                                    +'<div class="col-xs-3">'
                                        +'<label>'
                                            +'<span><input type="checkbox" /></span>'
                                            +'<section>'
                                                +'<h5>'+name+'</h5>'
                                                +'<h6>'+job+'</h6>'
                                            +'</section>'
                                        +'</label>'
                                    +'</div>'
                                    +'<div class="col-xs-9 diredepart">'
                                        +'<a href="###">'+department+'</a>'
                                    +'</div>'
                                +'</section>'   
                            +'</li>');
        },
        isUpDown: function(){
            var _this = this;
            var posHeight = this.$element.find('[data-direSearch-List]').scrollTop();
            var cilHeight = this.$element.find('[data-direSearch-List]').height();
            var domHeight = this.$element.find('[data-direSearch-List]').find('ul').height();
            if(domHeight-posHeight-cilHeight<=30){
                return true;
            }
        },
        copyDataFn: function(){
            var _this = this;
            if(this.copyData.length === 0){
                var len = this.list.length;
                this.copyData = this.list.concat();
            }
        },
        setok: function(){
           var _this = this;
           this.ok = !this.ok;
        },
        remove: function(){
            var _this = this;
            this.$element.find('[data-diresearch-input]').removeClass('active');
            this.$element.find('[data-diresearch-input] input').val('');
            this.$element.find('[data-diresearch-input] input').addClass('up');
            this.$element.find('.direloading').addClass('none').removeClass('aniload');
            this.$element.find('[data-diresearch-list] ul').html('');
            this.$element.find('[data-diresearch-list]').removeClass('active');
        }
    }
    
    var direct;
    
    function DirectFn($element, ok){
        
        if(direct === undefined){
            direct = new DirectorSearch($element, ok);
        }
        
        direct.bind();
            
        function setok(){
            direct.setok();
        }

        function appendList(list){
            direct.appendList(list);
        }

        function remove(){
            direct.remove();
        }

        return {
            setok: setok,
            appendList: appendList,
            remove: remove
        }
        
    }
    
    return {
        DirectFn: DirectFn
    }
   
})();

使用的方法如下:

if($('#manSecetorModal').length === 1){ //判断是否有弹出框
                
                var directTest = DirectorSearchModule.DirectFn($('#manSecetorModal'), true);  //创建对象  
                
                
                $('#manSecetorModal').on('change', '[data-direSearch-Input] input', function(){
                    directTest.appendList(direlist); //当发生change事件时添加伪搜索结果 direlist是测试json
                    $('body').on('click', '#manSecetorModal [data-diresearch-list] li', function(){
                        directTest.remove();
                    });
                });

                $('body').on('hidden.bs.modal', '#manSecetorModal', function (e) {
                    directTest.remove();
                    console.log(directTest);
                })
                
            }

现在的问题是,第一次执行的时候,添加搜索结构执行了一次,关闭弹出框,再次打开会执行两次,再次关闭再次打开会执行三次,以此类推。
图片描述

这样导致的问题是搜出来的的列表回重复累加多次,就像这个样子

图片描述

我初步想到的原因可能是我在每次出现弹出框后多次new出新的对象,但是我不知道怎么修改,望各位大神相助,谢谢了。

回复
阅读 2.7k
1 个回答

感觉像是使用On的时候多次绑定了,改成这样的代码试试。


if($('#manSecetorModal').length === 1){ 
                
                var directTest = DirectorSearchModule.DirectFn($('#manSecetorModal'), true); 
                //绑定之前先解绑一次                   
                $('#manSecetorModal').off().on('change', '[data-direSearch-Input] input', function(){
                    directTest.appendList(direlist); //当发生change事件时添加伪搜索结果 direlist是测试json
                    $('body').on('click', '#manSecetorModal [data-diresearch-list] li', function(){
                        directTest.remove();
                    });
                });

                $('body').on('hidden.bs.modal', '#manSecetorModal', function (e) {
                    directTest.remove();
                    console.log(directTest);
                })
                
            }
                
               
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏