Javascript 如何控制 Angular Material 中的 md-select 下拉位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39538534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to control md-select drop down position in Angular Material
提问by Scott Bonner
I need to customize a md-select so that the option list acts more like a traditional select. The options should show up below the select element instead of hovering over top of the element. Does anyone know of something like this that exists, or how to accomplish this?
我需要自定义一个 md-select,以便选项列表的行为更像传统的选择。选项应显示在 select 元素下方,而不是悬停在元素顶部。有谁知道存在这样的事情,或者如何做到这一点?
采纳答案by Scott Bonner
So this turned out to be something I had to do with Javascript and setTimeout, as ugly as the solution is. You can't effectively do this with CSS only as material design uses javascript positioning of the drop down. As a result I had to attach a function to the popup opening inside there I set a 200ms timeout that calculates the desired position of the drop down on the screen and moves it there. I also attached a function in the controller to a window resize event so it will move with a resize.
所以结果证明这是我不得不用 Javascript 和 setTimeout 做的事情,就像解决方案一样丑陋。您不能仅使用 CSS 有效地执行此操作,因为材料设计使用下拉列表的 javascript 定位。结果,我不得不将一个函数附加到里面的弹出窗口,我设置了 200 毫秒的超时时间,用于计算屏幕上下拉菜单的所需位置并将其移动到那里。我还将控制器中的一个函数附加到窗口调整大小事件,因此它会随着调整大小而移动。
Ultimately you have to use a timeout to get material design time to do it's javascript based move of the popover and then move it yourself. I also uses a trick to hide it while the moving is taking place so the user doesn't see the jump. That's the description of what I had to do just in case someone else attempts similar.
最终,您必须使用超时来获得材料设计时间来执行基于 javascript 的弹出窗口移动,然后自己移动它。我还使用了一个技巧来在移动发生时隐藏它,这样用户就看不到跳跃。这就是我必须做的事情的描述,以防万一其他人尝试类似。
回答by stack247
This applies to Material for Angular 2+
这适用于 Angular 2+ 的材质
Use disableOptionCentering
option, such as:
使用disableOptionCentering
选项,例如:
<mat-select disableOptionCentering>
<mat-option *ngFor="let movie of movies" [value]="movie.value">
{{ movie.viewValue }}
</mat-option>
</mat-select>
回答by camden_kid
Here you go - CodePen
给你 - CodePen
Use the md-container-class
attribute. From the docs:
使用md-container-class
属性。从文档:
Markup
标记
<div ng-controller="AppCtrl" class="md-padding" ng-cloak="" ng-app="MyApp">
<md-input-container>
<label>Favorite Number</label>
<md-select ng-model="myModel" md-container-class="mySelect">
<md-option ng-value="myVal" ng-repeat="myVal in values">{{myVal.val}}</md-option>
</md-select>
</md-input-container>
</div>
CSS
CSS
.mySelect md-select-menu {
margin-top: 45px;
}
JS
JS
(function () {
'use strict';
angular
.module('MyApp',['ngMaterial', 'ngMessages', 'material.svgAssetsCache'])
.controller('AppCtrl', function($scope) {
$scope.required = "required";
$scope.values = [
{val:1, des: 'One'},
{val:2, des: 'Two'}
];
});
})();
回答by Jérémy Bouche
Hi maybe try something like this:
嗨,也许尝试这样的事情:
$('.dropdown-button2').dropdown({
inDuration: 300,
outDuration: 225,
constrain_width: false, // Does not change width of dropdown to that of the activator
hover: true, // Activate on hover
gutter: ($('.dropdown-content').width()*3)/2.5 + 5, // Spacing from edge
belowOrigin: false, // Displays dropdown below the button
alignment: 'left' // Displays dropdown with edge aligned to the left of button
}
);
https://jsfiddle.net/fb0c6b5b/
https://jsfiddle.net/fb0c6b5b/
One post seems have the same issue: How can I make the submenu in the MaterializeCSS dropdown?
一篇文章似乎有同样的问题:如何在 MaterializeCSS 下拉菜单中创建子菜单?
回答by Olga
To people who has cdk-overlay (cdk-panel) with md-select.
对于使用 md-select 的 cdk-overlay (cdk-panel) 的人。
Suppose that you use Angular 2, Typescript, Pug and Material Design Lite (MDL) in working environment.
假设您在工作环境中使用 Angular 2、Typescript、Pug 和 Material Design Lite (MDL)。
Function which styles md-select works on click.
样式 md-select 在单击时起作用的函数。
Javascript (TypeScript) in component
组件中的 Javascript (TypeScript)
@Component({
selector: ..,
templateUrl: ..,
styleUrl: ..,
// For re-calculating on resize
host: { '(window:resize)': 'onResize()' }
})
export class MyComponent {
//Function to style md-select BEGIN
public styleSelectDropdown(event) {
var bodyRect = document.body.getBoundingClientRect();
let dropdown = document.getElementsByClassName("cdk-overlay-pane") as HTMLCollectionOf<HTMLElement>;
if (dropdown.length > 0) {
for(var i = 0; i < dropdown.length; i++) {
dropdown[i].style.top = "auto";
dropdown[i].style.bottom = "auto";
dropdown[i].style.left = "auto";
}
for(var i = 0; i < dropdown.length; i++) {
if (dropdown[i].innerHTML != "") {
var getDropdownId = dropdown[i].id;
document.getElementById(getDropdownId).classList.add('pane-styleSelectDropdown');
}
}
}
let target = event.currentTarget;
let selectLine = target.getElementsByClassName("mat-select-underline") as HTMLCollectionOf<HTMLElement>;
if (selectLine.length > 0) {
var selectLineRect = selectLine[0].getBoundingClientRect();
}
let targetPanel = target.getElementsByClassName("mat-select-content") as HTMLCollectionOf<HTMLElement>;
if (targetPanel.length > 0) {
var selectLineRect = selectLine[0].getBoundingClientRect();
}
if (dropdown.length > 0) {
for(var i = 0; i < dropdown.length; i++) {
dropdown[i].style.top = selectLineRect.top + "px";
dropdown[i].style.bottom = 0 + "px";
dropdown[i].style.left = selectLineRect.left + "px";
}
}
var windowHeight = window.outerHeight;
if (targetPanel.length > 0) {
targetPanel[0].style.maxHeight = window.outerHeight - selectLineRect.top + "px";
}
}
public onResize() {
this.styleSelectDropdown(event);
}
//Function to style md-select END
}
HTML (Pug)
HTML(哈巴狗)
.form-container
div.styleSelectDropdown((click)="styleSelectDropdown($event)")
md-select.form-group(md-container-class="my-container", id = '...',
md-option(....)
CSS which overrides Material Design Lite (MDL) css
覆盖 Material Design Lite (MDL) css 的 CSS
.pane-styleSelectDropdown .mat-select-panel {
border: none;
min-width: initial !important;
box-shadow: none !important;
border-top: 2px #3f51b5 solid !important;
position: relative;
overflow: visible !important;
}
.pane-styleSelectDropdown .mat-select-panel::before {
content: "";
position: absolute;
top: -17px;
right: 0;
display: block;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #3f51b5;
margin: 0 4px;
z-index: 1000;
}
.pane-styleSelectDropdown .mat-select-content {
border: 1px solid #e0e0e0;
box-shadow: 0 2px 1px #e0e0e0;
position: relative;
}
@media screen and (max-height: 568px) {
.pane-styleSelectDropdown .mat-select-content {
overflow-y: scroll;
}
}
.pane-styleSelectDropdown.cdk-overlay-pane {
top: 0;
bottom: 0;
left: 0;
overflow: hidden;
padding-bottom: 5px;
z-index: 10000;
}
.pane-styleSelectDropdown .mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple),
.pane-styleSelectDropdown .mat-option:focus:not(.mat-option-disabled),
.pane-styleSelectDropdown .mat-option:hover:not(.mat-option-disabled) {
background: #fff !important;
}
.pane-styleSelectDropdown .mat-option {
line-height: 36px;
height: 36px;
font-size: 14px;
}
回答by Rodrigo Alencar
You must override "top" of the CSS class ".md-select-menu-container".
您必须覆盖CSS 类“ .md-select-menu-container”的“ top”。
To do so, you have to use the attribute md-container-classlike:
为此,您必须使用属性md-container-class,例如:
md-container-class="dropDown"
inside the md-selecttag. then you just have to create a custom css for the class declared:
在md-select标签内。那么你只需要为声明的类创建一个自定义的css:
.md-select-menu-container.dropDown{
top: 147px !important;
}
!importantis the key here! top is the value you want... in this case 147px.
!重要的是这里的关键!top 是你想要的值……在这种情况下是 147px。
here's a CodePen
这是一个CodePen