简体   繁体   English

事件冲突的实例

[英]Instances conflicting on events

So I am trying to make a dropdown. 所以我想尝试下拉。 It works fine except for when I click on one to expand and then click on the other, then when I make a selection on one of them both close. 它工作正常,除了我点击一个展开然后点击另一个,然后当我选择其中一个都关闭。 What is the work around this as well as well as what is the best practice/approach for this situations. 围绕此问题的工作是什么以及针对这种情况的最佳实践/方法是什么。

 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> 

So how would I have to modify it so it also closes the dropdown on clicking outside the dropdown? 那么我将如何修改它以便在下拉列表外单击时关闭下拉列表?

Try checking e.target.parentElement.nodeName , this.element.nodeName at if condition within document.addEventListener handler , adding , removing class of dropdown if parent element is ul , else adjusting class of clicked li parent element ul 请检查e.target.parentElement.nodeNamethis.element.nodeNameif内条件document.addEventListener处理程序,添加,删除classdropdown ,如果父元素是ul ,否则调整class点击的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' }); 
 .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> 

You could use event.currentTarget to know which element triggers the event and so find the element you need this target to show, that way your code will shorter and simpler 您可以使用event.currentTarget来了解触发事件的元素,从而找到您需要此目标显示的元素,这样您的代码将更短更简单

Try something like this: 尝试这样的事情:

 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); 
 .disable { max-height: 0px; overflow: hidden } .enable { max-height: initial; overflow: initial } 
 <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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM