有啥方法可以混合 Angular Material mat-sidenav 的“推送”和“过度”模式?

Posted

技术标签:

【中文标题】有啥方法可以混合 Angular Material mat-sidenav 的“推送”和“过度”模式?【英文标题】:Any way to mix 'push' and 'over' modes of Angular Material mat-sidenav?有什么方法可以混合 Angular Material mat-sidenav 的“推送”和“过度”模式? 【发布时间】:2020-11-12 03:31:49 【问题描述】:

请在此处查看代码:https://stackblitz.com/edit/angular-sidenav-mixedpushover

我想设置一个有角度的材质 sidenav,以便它有一个始终可见的切换按钮,并在 sidenav 打开和关闭时滑动。主要内容区域在打开时(即 mode="over")应该被按钮和 sidenav 遮挡。

基本上我希望sidenav在“over”模式下运行,但要“按下”切换它的按钮。

我尝试了几种方法,但没有一种方法完全正确。我当前的实现(不共享,因为很难做一个简单的例子)有两个切换按钮:一个位于屏幕边缘,手动显示/隐藏,另一个按钮是 sidenav 内容本身的一部分.如果你眯着眼睛,它几乎就像一个随 sidenav 滑动的按钮!我还使用了一些动画来尝试将两个按钮融合一点,但是很难匹配 sidenav 的速度。

我正在尝试做的一些图片。

Sidenav 已关闭:

Sidenav 已打开:

有人有什么可行的建议吗?谢谢!

【问题讨论】:

您找到解决问题的方法了吗? @Alexis 很遗憾,没有。 您还在寻找解决方案吗? 仍在寻找解决方案,是的。 好的,让我创建一个 stackblitz 并发布一个解决方案 【参考方案1】:

如果你只是想看结果,请到答案末尾

主要要做的是将切换按钮与sidenav分离。

HTML

<p><button [ngClass]="'button':true,'open':opened" (click)="toggle()">Open</button></p>

<mat-sidenav-container class="sidenav" (backdropClick)="close()">
  <mat-sidenav #sidenav (keydown.escape)="close()" disableClose position="end">
    <p>Sidenav content</p>
  </mat-sidenav>

  <mat-sidenav-content>
    Page content with "over" sidenav
  </mat-sidenav-content>
</mat-sidenav-container>

在这里,您将按钮从 sidenav 中取出,这些类允许您首先将按钮放置在您想要的位置 - 使用 button 类 - 然后在打开或关闭侧导航时移动它 - 使用 @ 987654326@班级。

(backdropClick)="close()"(keydown.escape)="close()" 在这里确保我们移动切换按钮,即使我们不关闭 sidenav

所以这个样式是这样的

CSS

.button
  position:absolute;
  width:40px;
  height:40px;
  background-color: green;
  color:black;
  border-top-left-radius:5px;
  border-bottom-left-radius:5px;
  top: 50%;
  right:0;
  z-index: 2;
  transform: translate3d(0,0,0);
  transition:0.4s cubic-bezier(0.25, 0.8, 0.25, 1);


.open
  transform: translate3d(-200px,0,0);
  transition:0.4s cubic-bezier(0.25, 0.8, 0.25, 1);

transition 效果中,您会看到cubic-bezier(0.25, 0.8, 0.25, 1);,这是sidenav 用来显示其内容的过渡。因此,在我们的按钮中使用这个过渡,它将完美地适应 sidenav 的移动。

最后在你的打字稿文件上,你只需要切换sidenav的函数

TS

@ViewChild('sidenav') sidenav: MatSidenav;

opened: boolean = false;

toggle()
  this.opened = !this.opened
  if(this.opened)
      this.sidenav.open();
    else
      this.sidenav.close();
    


close() 
  this.opened = false;
  this.sidenav.close();

Here 你可以看到正在运行的堆栈闪电战。

【讨论】:

非常感谢!这看起来完全符合我的需要,一旦我有机会自己尝试(几天后,很可能),我将通过将其标记为答案来确认成功 不客气,如果出现问题,请随时告诉我 我刚试过,效果很好!三次贝塞尔过渡是完美的匹配。我之前尝试过一个移动按钮,但无法让它与 sidenav 正确匹配,所以我放弃了这种方法。事实证明,我走在了正确的轨道上,但需要适当的过渡。你的解决方案很完美@Alexis,谢谢!! 是的,这是sidenav使用的过渡,下次如果您想知道它是如何工作的,只需右键单击浏览器并单击“检查元素”,这样您就可以访问当前页面的 html、css 和 javascript,但我相信你已经知道了 ^^。所以有了这个,很容易找到过渡;)很高兴它可以帮助你。 我确实在渲染的 html 和 css 中进行了挖掘,但找不到确切的过渡,所以我不确定它是否在做一些奇怪的角度动画技巧或什么的。很高兴知道转换是纯 CSS,如果我进一步看的话我可以找到它 :-) 再次感谢!

以上是关于有啥方法可以混合 Angular Material mat-sidenav 的“推送”和“过度”模式?的主要内容,如果未能解决你的问题,请参考以下文章

Angular Material 7 使用带有拖放功能的网格

Angular 6 Material mat-select 更改方法已删除

有啥方法可以在 Angular2 中测试 EventEmitter?

在Angular 2+项目中使用AngularJS Material组件

Angular Material 教程之布局篇 : 布局简介

有啥方法可以避免 axios 中的 linkpreview.net 出现 CORS 错误,例如 Angular 中的 trustAsResourceUrl()?