Angular 自定义切换在移动设备上不起作用

Angular custom toggle not working on mobile

我正在尝试在 Angular 中构建自定义切换。一切都在桌面上按预期工作,但在移动设备上却不行。所以我点击并向右拖动。这就是它应该在桌面上工作的方式,在移动设备上我需要点击并向右滑动。这行不通。

我这里有一个活生生的例子codesandbox

我做错了什么?

import { Component, ViewChild, ElementRef, Renderer2 } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  @ViewChild("theSlider") theSlider: ElementRef;
  @ViewChild("lock") theLock: ElementRef;
  @ViewChild("banText") banText: ElementRef;
  @ViewChild("timerText") timerText: ElementRef;

  myPos = 0;
  posX = 0;
  borderLeft = 2;
  borderRight = 62;
  wasSlide = 0;
  easing = 0;
  step = 0;
  duration = 30;
  repeater;

  mousemoveUnlistener;
  mouseupUnlistener;
  touchstartUnlistener;
  touchendUnlistener;

  constructor(private renderer: Renderer2) {}

  sliderDown(e) {
    if (e.cancelable) {
      e.preventDefault();
      e.stopPropagation();

      e = e || window.event;

      this.posX = e.clientX;
      if (this.wasSlide !== 2) {
        this.wasSlide = 1;
      }

      this.mousemoveUnlistener = this.renderer.listen(
        "document",
        "mousemove",
        (evt) => {
          this.dragSlider(evt);
        }
      );

      this.mouseupUnlistener = this.renderer.listen(
        "document",
        "mouseup",
        (evt) => {
          this.closeDrag();
        }
      );

      this.touchstartUnlistener = this.renderer.listen(
        "document",
        "touchstart",
        (evt) => {
          this.dragSlider(evt);
        }
      );

      this.touchendUnlistener = this.renderer.listen(
        "document",
        "touchend",
        (evt) => {
          this.closeDrag();
        }
      );
    }
  }

  // SLIDER MOUSE DRAG
  dragSlider(e) {
    e = e || window.event;
    e.preventDefault();
    if (this.wasSlide !== 2) {
      this.wasSlide = 0;
    }
    this.myPos = this.posX - e.clientX;
    this.posX = e.clientX;
    if (this.theSlider.nativeElement.offsetLeft < this.borderLeft - 1) {
      this.closeDrag();
    } else if (this.theSlider.nativeElement.offsetLeft > this.borderRight) {
      this.theSlider.nativeElement.style.left = this.borderRight + "px";
    } else {
      this.theSlider.nativeElement.style.left =
        this.theSlider.nativeElement.offsetLeft - this.myPos + "px";
    }
  }

  // SLIDER MOUSE UP
  closeDrag() {
    if (this.theSlider.nativeElement.offsetLeft < this.borderLeft) {
      this.theSlider.nativeElement.style.left = this.borderLeft + "px";
    } else if (this.theSlider.nativeElement.offsetLeft > this.borderRight - 1) {
      this.theSlider.nativeElement.style.left = this.borderRight + "px";
      this.expandSliderAnim();
    } else if (
      this.theSlider.nativeElement.offsetLeft < this.borderRight &&
      this.theSlider.nativeElement.offsetLeft > this.borderLeft + 3
    ) {
      // JUMPBACK
      // this.theStartValue = this.theSlider.offsetLeft;
      this.moveMe();
    }

    if (this.mousemoveUnlistener) {
      this.mousemoveUnlistener();
    }

    if (this.mouseupUnlistener) {
      this.mouseupUnlistener();
    }

    if (this.touchstartUnlistener) {
      this.touchstartUnlistener();
    }

    if (this.touchendUnlistener) {
      this.touchendUnlistener();
    }
  }

  // SLIDER EXPAND ANIMATION
  expandSliderAnim() {
    // add animation
    this.theSlider.nativeElement.style.animationName = "sliderExpands";
    this.theSlider.nativeElement.style.animationDuration = "300ms";
    this.theSlider.nativeElement.style.animationFillMode = "forwards";
    // add count down timer

    this.timerText.nativeElement.style.display = "block";
    // this.theSlider.nativeElement.innerHTML =
    // "<span id='timer'>" + /*timer here:*/ '23:59:59' /*///*/ + "</span><div id='lock' #lock></div>";
    this.banText.nativeElement.style.display = "none";
    this.theSlider.nativeElement.style.background =
      "radial-gradient(50% 50% at 50% 50%, #338EFC 0%, #0450AD 100%)";
    // lock icon animation
    // let theLock = document.getElementById('lock');
    this.theLock.nativeElement.style.animationName = "lockFadeIn";
    this.theLock.nativeElement.style.animationDuration = "2s";
    // theLock.style.animationFillMode = "forwards";
    this.theLock.nativeElement.style.animationDirection = "alternate";
    this.theLock.nativeElement.style.animationIterationCount = "infinite";

    // document.getElementById('gameName').style.opacity = String(0.3);
    // document.getElementById('depositButton').style.opacity = String(0.3);
    // document.getElementById('sessionTimer').style.opacity = String(0.3);
    setTimeout(function () {
      this.wasSlide = 2;
    }, 1000);
  }

  explainBanButton() {
    if (this.wasSlide === 2) {
      alert("You are blocked from playing for 23:59:59 hours");
      this.wasSlide = 2;
    } else if (this.wasSlide === 1) {
      this.wasSlide = 0;
    }
  }

  // OPEN MODAL WINDOW (TODO) TO EXPLAIN SESSION TIMER FUNCTIONALITY TO THE USER
  explainSessionTimer() {
    alert(
      "this indicates how much time has past since you start you seesion today"
    );
  }

  moveMe() {
    // using fix values here, because the sliders
    // moves between fix constrains
    this.wasSlide = 0;
    this.easing = this.easeInCubic(this.step, 0, 12, this.duration);
    this.theSlider.nativeElement.style.left = this.easing + "px";
    this.step++;
    if (this.step > this.duration) {
      cancelAnimationFrame(this.repeater);
      this.step = 0;
    } else {
      // bind the context to the func.
      this.repeater = requestAnimationFrame(this.moveMe.bind(this));
    }
  }

  easeInCubic(currentIteration, startValue, changeInValue, totalIterations) {
    return changeInValue / Math.pow(currentIteration, 0.5) + startValue;
  }
}

模板:

<div id="ban_button" (touchstart)="explainBanButton($event)" (mouseup)="explainBanButton($event)">
  <div id="slider" #theSlider (touchend)="sliderDown($event)" (touchstart)="closeDrag($event)" (mousedown)="sliderDown($event)" (mouseup)="closeDrag($event)">
    <span id="ban_text" #banText>Ban</span>
    <div #timerText style="display: none;">
      <span id='timer'>23:59:59</span><div id='lock' #lock></div>
    </div>
  </div>
  <span class="ban_button--time__text">24h</span>
  <div id="h24"></div>
</div>

几件事:

第一

touchstart 和 touchend 应该互换,不是吗?

第二

您用 touchstart 注册了 dragSlider。我认为应该是 touchmove.

第三

至少在桌面浏览器移动仿真中,当我更改第一个和第二个时,我 运行 进入不存在的其他情况。