Angular2:用于 md-tab-group 的 HammerJS 滑动
Angular2: HammerJS swipe for md-tab-group
我已经在我的 Angular2 webapp 中实现了 HammerJS,并且我还测试了 example 代码。这段代码使用了一个对象数组,并且似乎可以完美地工作。但是,我一直在尝试为@angular2-material/tabs 实现相同的系统。因此我有一个 <md-tab-group>
和多个 <md-tab>
,应该从一个选项卡滑动到另一个选项卡。问题是我什至无法触发滑动功能。
HTML-文件:
<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" (selectedIndexChange)="selectChange()">
<div class="swipe-box" (swipeleft)="swipe(idx, $event.type)" (swiperight)="swipe(idx, $event.type)">
<md-tab>
(...) //Content Tab 1
</md-tab>
<md-tab>
(...) //Content Tab 2
</md-tab>
</div>
</md-tab-group>
在示例中可以看出,*ngFor
与 *ngFor="let avatar of avatars; let idx=index"
一样用于滑动框-<div>
。但是由于我是从 <md-tab-group>
获取索引,所以它似乎没有必要,即使我包含它,我的事件也没有触发,但我的 <md-tab>
-content 被隐藏了。因此,我将其排除在外。我确实在函数中保留了 idx
参数,因为滑动方法需要一个数字(第二个参数是可选的)。 Documentation
对于 TypeScript 文件,我已经实现了以下代码(有些代码可能无法运行,但由于未调用滑动方法,因此无法对其进行测试)。
TS-文件:
export class HomeComponent {
selectedIndex: number = 1;
selectChange(): void{
console.log("event triggered INDEX: " + this.selectedIndex);
}
SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };
// Action triggered when user swipes
swipe(selectedIndex: number, action = this.SWIPE_ACTION.RIGHT) {
console.log("swiped"); //DOES NOT GET TRIGGERD
// Out of range
if (selectedIndex < 0 || selectedIndex > 1 ) return;
let nextIndex = 0;
// Swipe right, next tab
if (action === this.SWIPE_ACTION.RIGHT) {
const isLast = selectedIndex === 1;
nextIndex = isLast ? 0 : selectedIndex + 1;
console.log("swipe right");
}
// Swipe left, previous tab
if (action === this.SWIPE_ACTION.LEFT) {
const isFirst = selectedIndex === 0;
nextIndex = isFirst ? 1 : selectedIndex - 1;
console.log("swipe left");
}
}
}
Live demo of what HammerJS does 是的,我已经实现了index.html[=24中需要的脚本=]
<!-- Hammer JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
您需要在每个选项卡上进行滑动检测,而不是容器。
<div class="swipe-box">
<md-tab (swipeleft)="swipe(1, $event.type)"
(swiperight)="swipe(1, $event.type)">
(...) //Content Tab 1
</md-tab>
<md-tab (swipeleft)="swipe(2, $event.type)"
(swiperight)="swipe(2, $event.type)">
(...) //Content Tab 2
</md-tab>
</div>
问题似乎是滑动事件用错了<div>
。该事件需要在parent<div>
中触发。这是工作代码:
HTML-文件:
<div class="md-content" flex md-scroll-y (swipeleft)="swipe(idx, $event.type)" (swiperight)="swipe(idx, $event.type)">
<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" (selectedIndexChange)="selectChange()">
<md-tab>
(...) //Content Tab 1
</md-tab>
<md-tab>
(...) //Content Tab 2
</md-tab>
</md-tab-group>
</div
TS-文件:
export class HomeComponent {
selectedIndex: number = 1;
selectChange(): void{
console.log("Selected INDEX: " + this.selectedIndex);
}
SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };
// Action triggered when user swipes
swipe(selectedIndex: number, action = this.SWIPE_ACTION.RIGHT) {
// Out of range
if (this.selectedIndex < 0 || this.selectedIndex > 1 ) return;
// Swipe left, next tab
if (action === this.SWIPE_ACTION.LEFT) {
const isLast = this.selectedIndex === 1;
this.selectedIndex = isLast ? 0 : this.selectedIndex + 1;
console.log("Swipe right - INDEX: " + this.selectedIndex);
}
// Swipe right, previous tab
if (action === this.SWIPE_ACTION.RIGHT) {
const isFirst = this.selectedIndex === 0;
this.selectedIndex = isFirst ? 1 : this.selectedIndex - 1;
console.log("Swipe left - INDEX: " + this.selectedIndex);
}
}
}
我写了一个小指令来实现与您的代码相同的效果:
import { Directive, HostListener, EventEmitter, Input, Output } from '@angular/core';
@Directive({
selector: '[swipeTab]'
})
export class SwipeTabDirective {
@HostListener('swipeleft', ['$event'])
onSwipeleft(event) {
if(this.selectedIndex + 1 <= this.tabs - 1) {
this.selectedIndex += 1;
this.selectedIndexChange.emit(this.selectedIndex);
}
}
@HostListener('swiperight', ['$event'])
onSwiperight(event) {
if(this.selectedIndex - 1 >= 0) {
this.selectedIndex -= 1;
this.selectedIndexChange.emit(this.selectedIndex);
}
}
@Input() tabs: number;
@Input() selectedIndex: number;
@Output() selectedIndexChange = new EventEmitter<number>();
}
模板应如下所示:
<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" [(tabs)]="tabs" swipeTab>
<md-tab>
(...) //Content Tab 2
</md-tab>
<md-tab>
(...) //Content Tab 2
</md-tab>
<md-tab>
(...) //Content Tab 3
</md-tab>
</md-tab-group>
并且在组件中您必须声明以下变量:
selectedIndex: number = 0;
tabs: number = 3;
玩得开心。
我已经在我的 Angular2 webapp 中实现了 HammerJS,并且我还测试了 example 代码。这段代码使用了一个对象数组,并且似乎可以完美地工作。但是,我一直在尝试为@angular2-material/tabs 实现相同的系统。因此我有一个 <md-tab-group>
和多个 <md-tab>
,应该从一个选项卡滑动到另一个选项卡。问题是我什至无法触发滑动功能。
HTML-文件:
<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" (selectedIndexChange)="selectChange()">
<div class="swipe-box" (swipeleft)="swipe(idx, $event.type)" (swiperight)="swipe(idx, $event.type)">
<md-tab>
(...) //Content Tab 1
</md-tab>
<md-tab>
(...) //Content Tab 2
</md-tab>
</div>
</md-tab-group>
在示例中可以看出,*ngFor
与 *ngFor="let avatar of avatars; let idx=index"
一样用于滑动框-<div>
。但是由于我是从 <md-tab-group>
获取索引,所以它似乎没有必要,即使我包含它,我的事件也没有触发,但我的 <md-tab>
-content 被隐藏了。因此,我将其排除在外。我确实在函数中保留了 idx
参数,因为滑动方法需要一个数字(第二个参数是可选的)。 Documentation
对于 TypeScript 文件,我已经实现了以下代码(有些代码可能无法运行,但由于未调用滑动方法,因此无法对其进行测试)。
TS-文件:
export class HomeComponent {
selectedIndex: number = 1;
selectChange(): void{
console.log("event triggered INDEX: " + this.selectedIndex);
}
SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };
// Action triggered when user swipes
swipe(selectedIndex: number, action = this.SWIPE_ACTION.RIGHT) {
console.log("swiped"); //DOES NOT GET TRIGGERD
// Out of range
if (selectedIndex < 0 || selectedIndex > 1 ) return;
let nextIndex = 0;
// Swipe right, next tab
if (action === this.SWIPE_ACTION.RIGHT) {
const isLast = selectedIndex === 1;
nextIndex = isLast ? 0 : selectedIndex + 1;
console.log("swipe right");
}
// Swipe left, previous tab
if (action === this.SWIPE_ACTION.LEFT) {
const isFirst = selectedIndex === 0;
nextIndex = isFirst ? 1 : selectedIndex - 1;
console.log("swipe left");
}
}
}
Live demo of what HammerJS does 是的,我已经实现了index.html[=24中需要的脚本=]
<!-- Hammer JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
您需要在每个选项卡上进行滑动检测,而不是容器。
<div class="swipe-box">
<md-tab (swipeleft)="swipe(1, $event.type)"
(swiperight)="swipe(1, $event.type)">
(...) //Content Tab 1
</md-tab>
<md-tab (swipeleft)="swipe(2, $event.type)"
(swiperight)="swipe(2, $event.type)">
(...) //Content Tab 2
</md-tab>
</div>
问题似乎是滑动事件用错了<div>
。该事件需要在parent<div>
中触发。这是工作代码:
HTML-文件:
<div class="md-content" flex md-scroll-y (swipeleft)="swipe(idx, $event.type)" (swiperight)="swipe(idx, $event.type)">
<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" (selectedIndexChange)="selectChange()">
<md-tab>
(...) //Content Tab 1
</md-tab>
<md-tab>
(...) //Content Tab 2
</md-tab>
</md-tab-group>
</div
TS-文件:
export class HomeComponent {
selectedIndex: number = 1;
selectChange(): void{
console.log("Selected INDEX: " + this.selectedIndex);
}
SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };
// Action triggered when user swipes
swipe(selectedIndex: number, action = this.SWIPE_ACTION.RIGHT) {
// Out of range
if (this.selectedIndex < 0 || this.selectedIndex > 1 ) return;
// Swipe left, next tab
if (action === this.SWIPE_ACTION.LEFT) {
const isLast = this.selectedIndex === 1;
this.selectedIndex = isLast ? 0 : this.selectedIndex + 1;
console.log("Swipe right - INDEX: " + this.selectedIndex);
}
// Swipe right, previous tab
if (action === this.SWIPE_ACTION.RIGHT) {
const isFirst = this.selectedIndex === 0;
this.selectedIndex = isFirst ? 1 : this.selectedIndex - 1;
console.log("Swipe left - INDEX: " + this.selectedIndex);
}
}
}
我写了一个小指令来实现与您的代码相同的效果:
import { Directive, HostListener, EventEmitter, Input, Output } from '@angular/core';
@Directive({
selector: '[swipeTab]'
})
export class SwipeTabDirective {
@HostListener('swipeleft', ['$event'])
onSwipeleft(event) {
if(this.selectedIndex + 1 <= this.tabs - 1) {
this.selectedIndex += 1;
this.selectedIndexChange.emit(this.selectedIndex);
}
}
@HostListener('swiperight', ['$event'])
onSwiperight(event) {
if(this.selectedIndex - 1 >= 0) {
this.selectedIndex -= 1;
this.selectedIndexChange.emit(this.selectedIndex);
}
}
@Input() tabs: number;
@Input() selectedIndex: number;
@Output() selectedIndexChange = new EventEmitter<number>();
}
模板应如下所示:
<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" [(tabs)]="tabs" swipeTab>
<md-tab>
(...) //Content Tab 2
</md-tab>
<md-tab>
(...) //Content Tab 2
</md-tab>
<md-tab>
(...) //Content Tab 3
</md-tab>
</md-tab-group>
并且在组件中您必须声明以下变量:
selectedIndex: number = 0;
tabs: number = 3;
玩得开心。