老师,我的代码点击空白处,下拉框不会隐藏;请老师帮忙看看

来源:3-4 代码优化--数据缓存

qq_勿忘初心_H

2020-05-10 18:35:19

index.js

		// header search
		var $headerSearch=$('#header-search');
		var html='',
			maxNum=10;	//最大显示的条数
		$headerSearch.on('search-getData',function(e,data){	
			var $this=$(this);
			html=createHeaderSearchLayer(data,maxNum);
			// $layer.html(html);
			// 自己来控制变量的改变,提供一个方法来往layer里面加东西
			$this.search('appendLayer',html);
			
			if (html) {		//html有值的情况下
				$this.search('showLayer');
			}else{
				$this.search('hideLayer');
			}

		}).on('search-noData',function(e){
			$(this).search('hideLayer').search('appendLayer','');
		}).on('click','.search-layer-item',function(){	//使用事件代理
			$headerSearch.search('setInputValue',$(this).html());
			$headerSearch.search('submit');
		});
		
		$headerSearch.search({
			autocomplete:true,
			css3:true,
			js:false,
			animation:'slideUpDown',
			getInterval:0
		})

		function createHeaderSearchLayer(data,maxNum){
			var html='',
				dataNum=data['result'].length;

			if (dataNum===0){
					return '';
				}

				for (var i = 0; i < dataNum; i++) {
					if (i>=maxNum) break;
					html+='<li class="search-layer-item text-ellipsis">'+data['result'][i][0]+'</li>';
				}
				return html;
		}

search.js

(function($){
		'use strict';
	// 数据缓存
		var cache={
			data:{},	//存放数据
			count:0,	//data中有多少个数据
			addData:function(key,data){
				if (!this.data[key]) {	//如果data中没有数据,就往data里面添加数据
					this.data[key]=data;
					this.count++;
				}
			},
			readData:function(key){
				return this.data[key];
			},
			deleteDataByKey:function(key){
				delete this.data[key];
				this.count--;
			},
			deleteDataByOrder:function(num){ //传进来的数据条数
				var count=0;	//记录删了多少条数据
				for (var p in this.data) {
						if (count>=num) {
							break;
						}
					count++;
					this.deleteDataByKey(p);
				}
			}
		};

	function Search($elem,options){
		this.$elem=$elem;
		this.options=options;

		this.$input=this.$elem.find('.search-inputbox');
		this.$form=this.$elem.find('.search-form');
		this.$layer=this.$elem.find('.search-layer');

		// 判断下拉层的东西是否加载
		this.loaded=false;

		this.$elem.on('click','.search-btn',$.proxy(this.submit,this));
		if (this.options.autocomplete) {
			this.autocomplete();
		}
	};
	Search.DEFAULTS={
		autocomplete:false, //是否实现自动完成搜索
		url:'https://suggest.taobao.com/sug?code=utf-8&_ksTS=1484204931352_18291&callback=jsonp18292&k=1&area=c2c&bucketid=6&q=',
		css3:false,
		js:false,
		animation:'fade',
		getInterval:200
	};
	Search.prototype.submit=function(){
			if (this.getInputValue()==='') {
				return false;
			}
			this.$form.submit();
	};
	Search.prototype.autocomplete=function(){
		var timer=null,self=this;
		this.$input
		.on('input',function(){
			if (self.options.getInterval) {
				clearTimeout(timer);
				timer=setTimeout(function(){
					self.getData();
			},self.options.getInterval); //在200毫秒内又输入了一个字符,那么就中断前面字符的计时器,200毫秒内无其他字符输入才发送ajax请求
			}else{
				self.getData();  //getInterval为0的时候,返回false,立即执行getData函数
			}
		})
		.on('focus',$.proxy(this.showLayer,this))
		.on('click',function(){
			return false;  //阻止冒泡
		});
		this.$layer.showHide(this.options);

		$(document).on('click',$.proxy(this.hideLayer,this));
		
	};
	Search.prototype.getData=function(){

		var self=this;
		var inputVal=this.getInputValue(); 
		if (inputVal==='') return self.$elem.trigger('search-noData');

		//读取缓存,缓存里面有就直接返回,下面代码不再执行
		if (cache.readData(inputVal)) return self.$elem.trigger('search-getData',[cache.readData(inputVal)]);

		// 当上一次请求没有完成就开始了下一次请求时,
		// 我们应该在每次开始请求之前,中断上一次的请求
		// this.jqXHR是jquery封装好的ajax对象
		if (this.jqXHR) {this.jqXHR.abort();}
		this.jqXHR=$.ajax({
				url:this.options.url+inputVal,
				dataType:'jsonp'
			}).done(function(data){	
				console.log(data);
				//向缓存的cache.data中缓存(添加)数据
				cache.addData(inputVal,data);
				console.log(cache.data);
				console.log(cache.count);

				self.$elem.trigger('search-getData',[data]);
			}).fail(function(){
				self.$elem.trigger('search-noData');
			}).always(function(){
				self.jqXHR=null;	//表示这一次的请求做完了(不管是请求失败还是成功)
			});
	};
	Search.prototype.showLayer=function(){
		if(!this.loaded)return;
		this.$layer.showHide('show'); //搜索出现得下拉菜单如何动画显示和隐藏
	};
	Search.prototype.hideLayer=function(){
		this.$layer.showHide('hide');
	};
	Search.prototype.getInputValue=function(){
		return $.trim(this.$input.val());
	};
	Search.prototype.setInputValue=function(val){
		this.$input.val(removeHtmlTags(val));

		function removeHtmlTags(str){
			return str.replace(/<(?:[^>'"]|"[^"]*"|'[^']*')*>/g, '');
		}
	};
	Search.prototype.appendLayer=function(html){
		this.$layer.html(html);
		this.loaded=!!html;  //通过将html转为布尔值的方式赋值给loaded;html有值就是为true,!!就是true
	};

	// 插件的方式来处理
	$.fn.extend({
		search:function(option,value){
			return this.each(function(){
				var $this=$(this);
				var search=$this.data('search');

     			var options=$.extend({},Search.DEFAULTS,$this.data(),typeof option==='object'&&option); //以我们传入的options为主,如果options没有传active:"menu"这个参数,则获取元素上data()的值;再不济,就使用default
     			
     			if (!search) {
     				$this.data('search',search=new Search($this,options));
     			}

     			if (typeof search[option] ==='function') {
     				search[option](value);
     			}
     		});
		}
	});
})(jQuery);


写回答

1回答

好帮手慕言

2020-05-10

同学你好,指的是下方的下拉框吗?

http://img.mukewang.com/climg/5eb7e11009c7ed0102000122.jpg

如果是的话,那么使用同学提供的代码放到源码中测试,点击页面的其他地方,下拉框是可以隐藏的。同学可以清除浏览器的缓存再测试下。

如果我的回答帮到了你,欢迎采纳,祝学习愉快~

0

0 学习 · 14456 问题

查看课程