使“材质"选项卡可滚动 [英] Making Material tabs scrollable
问题描述
我在我的应用程序中使用材料"选项卡(mat-tab-group
中的mat-tab
s)
当有更多的翼片相比,可以显示的,两个导航按钮被示为显示其它选项卡:
I'm using Material tabs in my application (mat-tab
s inside mat-tab-group
)
When there are more tabs than can be displayed, two navigation buttons are shown to display the other tabs:
我的要求是使用户能够在标签栏上滚动,以便显示其他标签.
My requirement is to enable the user to scroll on the tab bar so that other tabs are shown.
我尝试进行一些CSS更改,但无法解决.如有任何解决方案或建议,我们将不胜感激.
I tried to do some css changes but couldn't solve it. It's highly appreciated if any solution or suggestion can be given.
推荐答案
[长文本解决方案]我的目标是使mat-tab默认情况下可滚动,不带控件,但当单击部分可见的按钮时具有自动滚动的功能使用mat-tab键将其移至可见的中心视口.
[Long text solution] My goal was to make mat-tabs scrollable by default, without controls, but with the ability to auto-scroll when clicking on partially visible mat-tab to move it to the visible center-ish viewport.
1) This behavior already partially realized in this example "from the box" - https://stackblitz.com/edit/angular-mat-tabs-scrollalble-initial-behavior. The problem is that you can't scroll backward normally - there some buggy behavior to push tabs to the left. So it does not work as I wanted.
2)下一个变体是滚动事件-在mat-tab-group上使用(wheel)="event"
-但它也不适用于移动设备. https://stackblitz.com/edit/angular-mat- tabs-scrollable-by-wheel-event 从上面的上面的很棒评论中得到了它.
2) The next variant was with scrolling event - take a (wheel)="event"
on mat-tab-group - but its also not work with mobile. https://stackblitz.com/edit/angular-mat-tabs-scrollable-by-wheel-event Got it from this awesome comment above.
3)我自己的mat-tab滚动,包括在移动设备上滚动以及在单击选项卡时将单击的选项卡自动滚动到屏幕视口的中心,这并不是太简单,但是可以! :)
3) My own scroll of mat-tabs with scrolling on mobile and autoscrolling clicked tab to center of screen' viewport when you click on the tab was not too simple but it works! :)
首先,您需要在点击标签页和分页按钮时禁用从盒子"滚动:
first, you need to disable "from the box" scrolling when tapping on tabs and pagination buttons:
mat-tabs-override.scss:
mat-tabs-override.scss:
$black: #121212;
@mixin media-query-for-mobile {
@media (max-width: 768px) and (min-width: 1px) {
@content;
}
}
mat-tab-group {
.mat-tab-header {
.mat-tab-header-pagination {
display: none !important; // <== disable pagination
}
.mat-tab-label-container {
left: 0px; // if you need to use it on mobile - set left position to 0
width: 100%;
.mat-tab-list {
overflow-x: auto !important; // <== set horisontal scroll bar imperatively
// below rule prevents sliding of buttons' container - because it not sliding properly - to left it not slide as well
transform: none !important;
.mat-tab-labels {
// some tweaks for tabs - up to you
@include media-query-for-mobile {
justify-content: unset !important;
}
.mat-tab-label {
// min-width: 20% !important;
padding: 1.25% !important;
margin: 0px !important;
text-transform: uppercase;
color: $black;
font-weight: 600;
min-width: 140px !important;
}
}
}
}
}
}
在这种情况下,您会看到所有选项卡的宽度都相似并且可以在移动设备上滚动.
in this case you will see that all tabs are similar by width and scrollable on mobile.
接下来,您需要在点击标签时对标签进行自动滚动,然后根据当前视口将它们的位置更改为屏幕中央-让我们开始吧!
Next, you need to make auto-scroll for tabs when you clicking on them and change their position to the center of the screen, based on the current viewport - let's do it!
我们可以创建一个指令,该指令将侦听<mat-tabs-group>
的主容器,检查可滚动容器.mat-tab-labels
的宽度,并通过自动滚动.mat-tabs-labels
容器到所需的方式将选项卡移动到视口中可见的位置:
We can create a directive, which will listen to the main container of <mat-tabs-group>
, check width of scrollable container .mat-tab-labels
and move the tab to be visible in viewport by auto-scrolling .mat-tabs-labels
container to needed way:
模板中的指令:
<mat-tab-group scrollToCenter>
<mat-tab label="tab 1"></mat-tab>
<mat-tab label="tab 2"></mat-tab>
<mat-tab label="tab 3"></mat-tab>
<mat-tab label="tab 4"></mat-tab>
<mat-tab label="tab 5"></mat-tab>
<mat-tab label="tab 6"></mat-tab>
<mat-tab label="tab 7"></mat-tab>
<mat-tab label="tab 8"></mat-tab>
</mat-tab-group>
directive.ts:
directive.ts:
import { Directive, ElementRef, OnDestroy } from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';
interface DOMRectI {
bottom: number;
height: number;
left: number; // position start of element
right: number; // position end of element
top: number;
width: number; // width of element
x?: number;
y?: number;
}
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[scrollToCenter]',
})
export class MatTabScrollToCenterDirective implements OnDestroy {
isMobile: boolean;
subs = new Subscription();
constructor(
private element: ElementRef
) {
this.subs.add(
fromEvent(this.element.nativeElement, 'click').subscribe((clickedContainer: MouseEvent) => {
const scrollContainer = this.element.nativeElement.querySelector('.mat-tab-list');
const currentScrolledContainerPosition: number = scrollContainer.scrollLeft;
const newPositionScrollTo = this.calcScrollToCenterValue(clickedContainer, currentScrolledContainerPosition);
})
);
}
/** calculate scroll position to center of viewport */
calcScrollToCenterValue(clickedContainer, currentScrolledContainerPosition): number {
const scrolledButton: DOMRectI = (clickedContainer.target as HTMLElement).getBoundingClientRect();
const leftXOffset = (window.innerWidth - scrolledButton.width) / 2;
const currentVisibleViewportLeft = scrolledButton.left;
const neededLeftOffset = currentVisibleViewportLeft - leftXOffset;
console.log(scrolledButton);
const newValueToSCroll = currentScrolledContainerPosition + neededLeftOffset;
return newValueToSCroll;
}
ngOnDestroy() {
this.subs.unsubscribe();
}
}
它有效! :0但不是在ios和IE中... 为什么?因为ios和IE不支持Element.scroll()
And it works! :0 But not in ios and IE... Why? Because ios and IE don't support Element.scroll()
解决方案-npm i element-scroll-polyfill
并设置为polyfills.ts
Solution - npm i element-scroll-polyfill
and set to polyfills.ts
/** enable polufill for element.scroll() on IE and ios */
import 'element-scroll-polyfill';
太好了!但是现在滚动不是那么顺畅... IE和ios不支持smooth-scroll-behavior.
Great! but now scroll is not so smooth... IE and ios not support smooth-scroll-behavior.
解决方案-npm i smoothscroll-polyfill
并添加到polyfills.ts
Solution - npm i smoothscroll-polyfill
and add to polyfills.ts
import smoothscroll from 'smoothscroll-polyfill';
// enable polyfill
smoothscroll.polyfill();
最后,它在任何地方都可以使用. 希望它可以帮助某人修复mat-tabs自动滚动的空虚感:)
Finally it works everywhere. Hope it helps somebody to fix mat-tabs autoscrolling emptiness :)
演示 享受它:)
DEMO Enjoy it :)
这篇关于使“材质"选项卡可滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!