事件冲突的实例

时间:2015-11-13 01:40:15

标签: javascript

所以我想尝试下拉。它工作正常,除了我点击一个展开然后点击另一个,然后当我选择其中一个都关闭。围绕这个问题的工作是什么以及针对这种情况的最佳实践/方法是什么。

var extend = function(){
		if(!arguments.length)
			return {};
		else if (arguments.length == 1)
			return arguments[0];
			
		var primary = arguments[0];
		for(var v = 1; v < arguments.length; ++v){
			for(prop in arguments[v]){
				primary[prop] = arguments[v][prop];
			}	
		}
		return primary;
	};
	
	var Dropdown = (function(){
		self = undefined;		
		Dropdown.instances = [];
		
		function Dropdown(element, options){
			self = this;
			this.settings = extend(this.defaults, options);
			console.log(this.settings);
			this.element = this.getElement(element);
			
			this.trigger = this.getElement(options.trigger);
			
			if(!this.element)
				throw new Error('No element found.');
				
			if(!this.trigger)
				throw new Error('No trigger found.');
				
			if(!this.settings.optionSelector)
				throw new Error('Option Selector Not Defined.');

			if(this.element.dropdown)
				throw new Error('Dropdown already exists.');
				
				
			this.element.dropdown = this;
			Dropdown.instances.push(this);
			
			
			
			this.attachTriggerListener = function(event, trigger, dropdown){
				trigger.addEventListener(event, function(e){
					e.stopPropagation();
					dropdown.classList.remove('hidden');
					dropdown.classList.add('visible');
				}, false);
				document.addEventListener('click', function(e){		
					dropdown.classList.remove('visible');
					dropdown.classList.add('hidden');
					trigger.innerHTML = e.target.innerHTML;
				}, false);
			};
			
			this.init();
		}
		Dropdown.prototype.defaults = {
			css: '',
			optionSelector: undefined,
			trigger: undefined,
			triggersOn: 'click',
			onShow: function(){},
			onClose: function(){},
		};
		Dropdown.prototype.init = function(){
			this.element.classList.add('g-dropdown');
			this.element.classList.add('hidden');
			
			
			this.attachTriggerListener(this.settings.triggersOn, this.trigger, this.element);		
		};		
		Dropdown.prototype.getElement = function(object){
			if(typeof object == 'object' &&
			object instanceof HTMLElement)
				return object;
			else if(typeof object == 'string')
				return document.querySelector(object);
		};			
		
		return Dropdown;
	}());


	var dropdown = new Dropdown('#select', {
		optionSelector: 'li',
		trigger: '#trigger'
	});
	
	
	var dropdown = new Dropdown('#select2', {
		optionSelector: 'li',
		trigger: '#trigger2'
	});
.g-dropdown{	
	max-height: 100px;
	max-width: 75px;
	
	overflow: scroll;
	
	-webkit-transition: visibility 0.50s, height 0.50s;
	   -moz-transition: visibility 0.50s, height 0.50s;
			transition: visibility 0.50s, height 0.50s;
}
.g-dropdown.visible{
	visibility: visible;
	height: 100px;
}
.g-dropdown.hidden{
	visibility: hidden;
	height: 0px;
}
<button id='trigger'>Click Me</button>
<ul id='select' style='padding: 0; margin: 0;'>
	<li>One-one</li>
	<li>Two-two</li>
	<li>Three-three</li>
	<li>Four-four</li>
	<li>Five-five</li>
</ul>



<br/><br/><br/>

<button id='trigger2'>Click Me</button>
<ul id='select2' style='padding: 0; margin: 0;'>
	<li>One-one</li>
	<li>Two-two</li>
	<li>Three-three</li>
	<li>Four-four</li>
	<li>Five-five</li>
</ul>

2 个答案:

答案 0 :(得分:1)

  

那么我将如何修改它以便关闭下拉列表   在下拉列表外点击?

尝试在e.target.parentElement.nodeName处理程序中的this.element.nodeName条件下检查ifdocument.addEventListener,如果父元素为{{},则添加class dropdown {1}},否则调整点击的ul父元素class的{​​{1}}

li

ul
    document.addEventListener('click', function(e){ 
        if (e.target.parentElement.nodeName !== this.element.nodeName) {
          dropdown.classList.remove('visible');
          dropdown.classList.add('hidden');
        } else {              
          e.target.parentElement.classList.remove('visible');
          e.target.parentElement.classList.add('hidden');
        }
        self.settings.onClose(e.target);
    }.bind(this), false); 
var extend = function(){
		if(!arguments.length)
			return {};
		else if (arguments.length == 1)
			return arguments[0];
			
		var primary = arguments[0];
		for(var v = 1; v < arguments.length; ++v){
			for(prop in arguments[v]){
				primary[prop] = arguments[v][prop];
			}	
		}
		return primary;
	};
	
	var Dropdown = (function(){
		self = undefined;		
		Dropdown.instances = [];
		
		function Dropdown(element, options){
			self = this;
			this.settings = extend(this.defaults, options);
			console.log(this.settings);
			this.element = this.getElement(element);
			
			this.trigger = this.getElement(options.trigger);
			
			if(!this.element)
				throw new Error('No element found.');
				
			if(!this.trigger)
				throw new Error('No trigger found.');
		    /*
			if(!this.settings.optionSelector)
				throw new Error('Option Selector Not Defined.');
            */

			if(this.element.dropdown)
				throw new Error('Dropdown already exists.');
				
				
			this.element.dropdown = this;
			Dropdown.instances.push(this);
			
			
			
			this.attachTriggerListener = function(event, trigger, dropdown){
				trigger.addEventListener(event, function(e){                   
					e.stopPropagation();
					dropdown.classList.remove('hidden');
					dropdown.classList.add('visible');
				}, false);
              
				document.addEventListener('click', function(e){	
                    if (e.target.parentElement.nodeName !== this.element.nodeName) {
					  dropdown.classList.remove('visible');
					  dropdown.classList.add('hidden');
					
                    } else {
                                               e.target.parentElement.classList.remove('visible');
					  e.target.parentElement.classList.add('hidden');
                    }
self.settings.onClose(e.target);
				}.bind(this), false);

                
			};
			
			this.init();
		}
		Dropdown.prototype.defaults = {
			css: '',
			optionSelector: undefined,
			trigger: undefined,
			triggersOn: 'click',
			onShow: function(){},
			onClose: function(){},
		};
		Dropdown.prototype.init = function(){
			this.element.classList.add('g-dropdown');
			this.element.classList.add('hidden');
			
			
			this.attachTriggerListener(this.settings.triggersOn, this.trigger, this.element);		
		};		
		Dropdown.prototype.getElement = function(object){
			if(typeof object == 'object' &&
			object instanceof HTMLElement)
				return object;
			else if(typeof object == 'string')
				return document.querySelector(object);
		};			
		
		return Dropdown;
	}());


	var dropdown1 = new Dropdown('#select', {
		optionSe1lector: 'li',
		trigger: '#trigger'
	});
	
	
	var dropdown2 = new Dropdown('#select2', {
		optionSe2lector: 'li',
		trigger: '#trigger2'
	});

答案 1 :(得分:0)

您可以使用event.currentTarget来了解触发事件的元素,从而找到您需要显示此目标的元素,这样您的代码就会更短更简单

尝试这样的事情:

&#13;
&#13;
var btn1 = document.getElementById('btn-1');
var btn2 = document.getElementById('btn-2');

function toggle(event) {
  var nextNode = event.currentTarget.nextElementSibling;
  nextNode.classList.toggle('disable');
  nextNode.classList.toggle('enable');
}

btn1.addEventListener('click', toggle, false);
btn2.addEventListener('click', toggle, false);
&#13;
.disable {
  max-height: 0px;
  overflow: hidden
}

.enable {
  max-height: initial;
  overflow: initial
}
&#13;
<div class="first-container">
  <button id="btn-1">Click Me</button>
  <ul id="list-1" class="disable">
    <li>item-1</li>
    <li>item-2</li>
    <li>item-3</li>
    <li>item-4</li>
    <li>item-5</li>
  </ul>
</div>
<div class="second-container">
  <button id="btn-2">Click Me</button>
  <ul id="list-2" class="disable">
    <li>item-1</li>
    <li>item-2</li>
    <li>item-3</li>
    <li>item-4</li>
    <li>item-5</li>
  </ul>
</div>
&#13;
&#13;
&#13;