简体   繁体   English

仅在 iPhone 上拖动网站上的元素时的 WinXP 风格的拖动故障效果

[英]WinXP-style drag-glitch effect when dragging elements on website on iPhone only

As the title specifies, my website presents a weird effect when I am dragging elements.正如标题所指出的,当我拖动元素时,我的网站呈现出一种奇怪的效果。 This only happens on iPhone;这只发生在 iPhone 上; on Desktop and Android browsers it does not happen .在桌面和 Android 浏览器上它不会发生

This is how it looks like:这是它的样子:

拖曳效应

I can paste a snippet containing the code to drag the elements, but I do not think it will help.我可以粘贴一个包含代码的片段来拖动元素,但我认为这不会有帮助。 This seems more of a OS specific thing I am not aware of.这似乎更像是我不知道的操作系统特定的事情。

Does anyone know why this might happen?有谁知道为什么会发生这种情况?


EDIT:编辑:

As an answer requested it, here is the code for the drag (superfluous stuff has been cut out):作为要求的答案,这里是拖动的代码(多余的东西已被删除):


private dragStart(e: UIEvent): void {
    e.preventDefault();
    e.stopPropagation();

    this.dragInitial = Point.extractPagePointFromUiEvent(e);
    this.dragActual = this.dragInitial.clone();

    document.ontouchmove = (e1: TouchEvent) => this.elementDrag(e1);
    document.ontouchend = () => this.dragEnd();
}

private elementDrag(e: UIEvent) {
    const p = Point.extractPagePointFromUiEvent(e);

    const actualX = this.goalTile.offsetLeft - this.dragActual.x + p.x;
    const actualY = this.goalTile.offsetTop - this.dragActual.y + p.y;

    this.goalTile.style.left = actualX + "px";
    this.goalTile.style.top = actualY + "px";
    this.dragActual = p;
}

private dragEnd(): void {
    document.ontouchend = null;
    document.ontouchmove = null;

    if (this.dragInitial.equals(this.dragActual)) return;
    this.updateGoal();
}

A possible source of the problem is changing the style of element(s) within a event handler.问题的一个可能来源是更改事件处理程序中元素的样式。 You can try something like this:你可以尝试这样的事情:

private requestID: long;

private elementDrag(e: UIEvent) {
    const p = Point.extractPagePointFromUiEvent(e);

    const actualX = this.goalTile.offsetLeft - this.dragActual.x + p.x;
    const actualY = this.goalTile.offsetTop - this.dragActual.y + p.y;

    this.dragActual = p;

    if(this.requestID) cancelAnimationFrame(this.requestID);

    this.requestID = requestAnimationFrame(() => {
        this.requestID = null;
        this.goalTile.style.left = actualX + "px";
        this.goalTile.style.top = actualY + "px";
    });
}

Hope this helps.希望这可以帮助。

Edit: I realized a problem of my solution: the event handler will probably be called at a rate much higher than the DOM refresh rate, so we need to clear previously requested animation not yet run.编辑:我意识到我的解决方案的一个问题:事件处理程序可能会以远高于 DOM 刷新率的速率被调用,因此我们需要清除之前请求的 animation 尚未运行。

Edit 2: Code adapted to question edit编辑 2:适用于问题编辑的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM