2017-01-25 2 views
1

Ich habe eine Dropdown-Komponente mit objektorientiertem Javascript erstellt.Angrenzend positionierte Dropdowns scheinen verschränkt zu sein

Später instanziierte ich 2 Instanzen dieser Dropdown-Komponente und rendert sie nebeneinander.

Das Problem, dem ich derzeit gegenüberstehe, ist: Wenn der Abwärtspfeil angeklickt wird und Elemente im ersten Dropdown-Menü angezeigt werden, ändert sich die Position des zweiten Dropdown-Menüs.

JS Bin: https://jsbin.com/ruluzarixe/3/edit?html,output

Ich bin nicht in der Lage zu verstehen, warum dies geschieht. Schätzen Sie alle Hilfe zur Behebung dieses Problems.

Vielen Dank im Voraus

function Dropdown() { 
 
    this.id = ''; 
 
    this.items = []; 
 

 
    this.settings = { 
 
    isRendered: false, 
 
    isListOpen: false 
 
    }; 
 

 
    this.init = function(componentId) { 
 
    this.id = componentId; 
 
    this.cacheDOM(); 
 
    }; 
 

 
    this.cacheDOM = function() { 
 
    this.$el = $('#' + this.id); 
 

 
    if (this.settings.isRendered) { 
 
     this.$input = this.$el.find('input'); 
 
     this.$dropbox = this.$el.find('div'); 
 
     this.$dropdownicon = this.$el.find('span'); 
 
     this.$ul = this.$el.find('ul'); 
 
    } 
 

 
    this.template = `<div id='` + this.id + `'> 
 
         <div class='dropbox'><input /><span class='material-icons'>expand_more</span></div> 
 
         <ul style='display: none'> 
 
         {{#items}} 
 
         <li><span>{{.}}</span></li> 
 
         {{/items}} 
 
\t \t \t   </ul> 
 
\t \t \t   </div>`; 
 
    }; 
 

 
    this.populateItems = function(items) { 
 
    this.items = items; 
 
    this.render(); 
 
    }; 
 

 
    this.applyStyles = function() { 
 

 
    var elStyle = { 
 
     'display': 'inline-block', 
 
     'position': 'relative' 
 
    }; 
 

 
    var dropboxStyle = { 
 
     'display': 'inline-flex', 
 
     'border': '1px solid #9DD9D2' 
 
    }; 
 

 
    var inputStyle = { 
 
     'font': 'inherit', 
 
     'padding': '3px', 
 
     'border': 'none' 
 
    }; 
 

 
    var inputFocusStyle = { 
 
     'border': 'none', 
 
     'outline': 'none' 
 
    }; 
 

 
    var dropdownIconStyle = { 
 
     'background-color': '', 
 
     'color': '#17BEBB' 
 
    }; 
 

 
    var dropdownIconHoverStyle = { 
 
     'cursor': 'default', 
 
     'background-color': '#9DD9D2', 
 
     'color': 'white' 
 
    }; 
 

 
    this.$el.css(elStyle); 
 
    this.$dropbox.css(dropboxStyle); 
 
    this.$input.css(inputStyle); 
 
    this.$input.on('focus', function() { 
 
     $(this).css(inputFocusStyle); 
 
    }); 
 
    this.$dropdownicon 
 
     .css(dropdownIconStyle) 
 
     .on('mouseenter', function() { 
 
     $(this).css(dropdownIconHoverStyle); 
 
     }) 
 
     .on('mouseleave', function() { 
 
     $(this).css(dropdownIconStyle); 
 
     }); 
 
    }; 
 

 
    this.bindEvents = function() { 
 
    this.$dropdownicon.on('click', this.toggleList.bind(this)); 
 
    } 
 

 
    this.toggleList = function() { 
 
    var listOpenStyle = { 
 
     'display': 'block', 
 
     'list-style-type': 'none', 
 
     'border': '1px solid #9DD9D2', 
 
     'margin': '0' 
 
    } 
 

 
    var listClosedStyle = { 
 
     'display': 'none' 
 
    } 
 

 
    this.settings.isListOpen = !this.settings.isListOpen; 
 

 
    if (this.settings.isListOpen) 
 
     this.$ul.css(listOpenStyle); 
 
    else 
 
     this.$ul.css(listClosedStyle); 
 
    }; 
 

 
    this.render = function() { 
 
    var data = { 
 
     items: this.items 
 
    }; 
 
    this.$el.replaceWith(Mustache.render(this.template, data)); 
 
    this.settings.isRendered = true; 
 
    this.cacheDOM(); 
 
    this.applyStyles(); 
 
    this.bindEvents(); 
 
    }; 
 

 
}; 
 

 
var dropdown = new Dropdown(); 
 
dropdown.init('city'); 
 
dropdown.populateItems(['Munich', 'Oslo', 'Havana']); 
 
dropdown.render(); 
 

 
var dropdown2 = new Dropdown(); 
 
dropdown2.init('city2'); 
 
dropdown2.populateItems(['Los Angeles', 'Miami', 'Edinburg']); 
 
dropdown2.render();
html, 
 
body { 
 
    height: 100%; 
 
    width: 100%; 
 
    overflow: hidden; 
 
    font-size: 1em; 
 
    font-family: 'Lato', sans-serif; 
 
}
<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 
    <meta name="viewport" content="width=device-width"> 
 
    <title>JS Bin</title> 
 
</head> 
 

 
<body> 
 
    <span id='city'></span> 
 
    <span id='city2'></span> 
 

 
    <script src="https://code.jquery.com/jquery-3.1.0.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.js"></script> 
 
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> 
 
    <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet"> 
 

 
</body> 
 

 
</html>

Antwort

0

hinzufügen position, left und right Werte Ihren ul s

function Dropdown() { 
 
    this.id = ''; 
 
    this.items = []; 
 

 
    this.settings = { 
 
    isRendered: false, 
 
    isListOpen: false 
 
    }; 
 

 
    this.init = function(componentId) { 
 
    this.id = componentId; 
 
    this.cacheDOM(); 
 
    }; 
 

 
    this.cacheDOM = function() { 
 
    this.$el = $('#' + this.id); 
 

 
    if (this.settings.isRendered) { 
 
     this.$input = this.$el.find('input'); 
 
     this.$dropbox = this.$el.find('div'); 
 
     this.$dropdownicon = this.$el.find('span'); 
 
     this.$ul = this.$el.find('ul'); 
 
    } 
 

 
    this.template = `<div id='` + this.id + `'> 
 
         <div class='dropbox'><input /><span class='material-icons'>expand_more</span></div> 
 
         <ul style='display: none'> 
 
         {{#items}} 
 
         <li><span>{{.}}</span></li> 
 
         {{/items}} 
 
\t \t \t   </ul> 
 
\t \t \t   </div>`; 
 
    }; 
 

 
    this.populateItems = function(items) { 
 
    this.items = items; 
 
    this.render(); 
 
    }; 
 

 
    this.applyStyles = function() { 
 

 
    var elStyle = { 
 
     'display': 'inline-block', 
 
     'position': 'relative' 
 
    }; 
 

 
    var dropboxStyle = { 
 
     'display': 'inline-flex', 
 
     'border': '1px solid #9DD9D2' 
 
    }; 
 

 
    var inputStyle = { 
 
     'font': 'inherit', 
 
     'padding': '3px', 
 
     'border': 'none' 
 
    }; 
 

 
    var inputFocusStyle = { 
 
     'border': 'none', 
 
     'outline': 'none' 
 
    }; 
 

 
    var dropdownIconStyle = { 
 
     'background-color': '', 
 
     'color': '#17BEBB' 
 
    }; 
 

 
    var dropdownIconHoverStyle = { 
 
     'cursor': 'default', 
 
     'background-color': '#9DD9D2', 
 
     'color': 'white' 
 
    }; 
 

 
    this.$el.css(elStyle); 
 
    this.$dropbox.css(dropboxStyle); 
 
    this.$input.css(inputStyle); 
 
    this.$input.on('focus', function() { 
 
     $(this).css(inputFocusStyle); 
 
    }); 
 
    this.$dropdownicon 
 
     .css(dropdownIconStyle) 
 
     .on('mouseenter', function() { 
 
     $(this).css(dropdownIconHoverStyle); 
 
     }) 
 
     .on('mouseleave', function() { 
 
     $(this).css(dropdownIconStyle); 
 
     }); 
 
    }; 
 

 
    this.bindEvents = function() { 
 
    this.$dropdownicon.on('click', this.toggleList.bind(this)); 
 
    } 
 

 
    this.toggleList = function() { 
 
    var listOpenStyle = { 
 
     'display': 'block', 
 
     'list-style-type': 'none', 
 
     'border': '1px solid #9DD9D2', 
 
     'margin': '0', 
 
     'position' : 'absolute', 
 
     'left': '0', 
 
     'right': '0' 
 
    } 
 

 
    var listClosedStyle = { 
 
     'display': 'none' 
 
    } 
 

 
    this.settings.isListOpen = !this.settings.isListOpen; 
 

 
    if (this.settings.isListOpen) 
 
     this.$ul.css(listOpenStyle); 
 
    else 
 
     this.$ul.css(listClosedStyle); 
 
    }; 
 

 
    this.render = function() { 
 
    var data = { 
 
     items: this.items 
 
    }; 
 
    this.$el.replaceWith(Mustache.render(this.template, data)); 
 
    this.settings.isRendered = true; 
 
    this.cacheDOM(); 
 
    this.applyStyles(); 
 
    this.bindEvents(); 
 
    }; 
 

 
}; 
 

 
var dropdown = new Dropdown(); 
 
dropdown.init('city'); 
 
dropdown.populateItems(['Munich', 'Oslo', 'Havana']); 
 
dropdown.render(); 
 

 
var dropdown2 = new Dropdown(); 
 
dropdown2.init('city2'); 
 
dropdown2.populateItems(['Los Angeles', 'Miami', 'Edinburg']); 
 
dropdown2.render();
html, 
 
body { 
 
    height: 100%; 
 
    width: 100%; 
 
    overflow: hidden; 
 
    font-size: 1em; 
 
    font-family: 'Lato', sans-serif; 
 
}
<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 
    <meta name="viewport" content="width=device-width"> 
 
    <title>JS Bin</title> 
 
</head> 
 

 
<body> 
 
    <span id='city'></span> 
 
    <span id='city2'></span> 
 

 
    <script src="https://code.jquery.com/jquery-3.1.0.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.js"></script> 
 
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> 
 
    <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet"> 
 

 
</body> 
 

 
</html>

0

Ändern der position Eigenschaft der beiden divs (#city, #city2) zu absolute.

0

Verwendung vertical-align: top; wie unten im Code

var elStyle = { 
      'display': 'inline-block', 
      'position': 'relative', 
      'vertical-align': 'top' 
      }; 
+0

"vertical-align: top" Hinzufügen auch löst das Problem. Aber ich akzeptiere die Antwort von @HerrSerker. Danke für die Antwort. – vrn

Verwandte Themen