【问题标题】:How to control md-select drop down position in Angular Material如何控制 Angular Material 中的 md-select 下拉位置
【发布时间】:2017-01-25 02:22:11
【问题描述】:

我需要自定义一个 md-select 以便选项列表更像传统的选择。选项应显示在选择元素下方,而不是悬停在元素顶部。有谁知道存在这样的事情,或者如何做到这一点?

【问题讨论】:

  • 只需在框架完成其工作后将select 高度添加到element.style.top?或者在设置 top 的第 1591 行附近的某处更改框架源代码?不过,不知道单独更改 top 是否会弄乱预期的 UI。

标签: javascript css angularjs angular-material


【解决方案1】:

这适用于 Angular 2+ 的材料

使用disableOptionCentering选项,如:

<mat-select disableOptionCentering>
  <mat-option *ngFor="let movie of movies" [value]="movie.value">
    {{ movie.viewValue }}
  </mat-option>
</mat-select>

【讨论】:

    【解决方案2】:

    给你 - CodePen

    使用md-container-class 属性。来自docs

    标记

    <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

    .mySelect md-select-menu {
      margin-top: 45px;
    }
    

    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'}
            ];
          });
    })();
    

    【讨论】:

    • 这并不总是有效。请注意,一旦您选择了值 2,当您再次更改所选值时,现在输入框被部分覆盖。您拥有的选择越多,这一点就越明显。选择一个值后,所选值在列表中的位置越靠下,一旦您再次单击以选择,弹出窗口向上移动的越多。
    【解决方案3】:

    你好,可以试试这样的:

        $('.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/

    一个帖子似乎有同样的问题:How can I make the submenu in the MaterializeCSS dropdown?

    【讨论】:

      【解决方案4】:

      致拥有 cdk-overlay (cdk-panel) 和 md-select 的人。

      假设您在工作环境中使用 Angular 2、Typescript、Pug 和 Material Design Lite (MDL)。

      样式 md-select 在点击时起作用的函数。

      组件中的 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(哈巴狗)

              .form-container
      
                  div.styleSelectDropdown((click)="styleSelectDropdown($event)")
                      md-select.form-group(md-container-class="my-container", id = '...',
                          md-option(....)
      

      覆盖 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;
      }
      

      【讨论】:

        【解决方案5】:

        所以结果证明这是我不得不用 Javascript 和 setTimeout 做的事情,就像解决方案一样丑陋。您不能仅使用 CSS 有效地做到这一点,因为材料设计使用下拉菜单的 javascript 定位。结果,我不得不在里面的弹出窗口上附加一个函数,我设置了一个 200 毫秒的超时,计算屏幕上下拉菜单的所需位置并将其移动到那里。我还将控制器中的一个函数附加到一个窗口调整大小事件,因此它会随着调整大小而移动。

        最终,您必须使用超时来获得材料设计时间来完成基于 javascript 的弹出框移动,然后自己移动它。我还使用了一个技巧来在移动发生时隐藏它,这样用户就看不到跳跃了。这就是我必须做的事情的描述,以防其他人尝试类似的事情。

        【讨论】:

        • 你的解决方案很好,但为什么没有代码示例?
        • 我有同样的问题,如果没有代码,这没有多大帮助。我不知道为什么这被接受为答案。
        【解决方案6】:

        您必须覆盖 CSS 类“.md-select-menu-container”的“top”。

        为此,您必须使用 md-container-class 属性,例如:

        md-container-class="dropDown"
        

        md-select 标签内。那么你只需要为声明的类创建一个自定义 css:

        .md-select-menu-container.dropDown{
            top: 147px !important;
        }
        

        !important 是这里的关键! top 是您想要的值...在本例中为 147px。

        这是CodePen

        【讨论】:

        • 这将不起作用,因为需要动态计算顶部位置
        • 对不起,但这是您在这里唯一的解决方案......当然是固定位置。我相信这个问题没有具体说明。如果你想要动态,你可以使用md-on-open 来获取 md-select 当前位置并使用 javascript 更新 css 属性。
        猜你喜欢
        • 1970-01-01
        • 2015-06-16
        • 2016-12-09
        • 1970-01-01
        • 2016-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-21
        相关资源
        最近更新 更多