我该如何防止在touchmove和mousemove期间发生href重定向?

7

我在尝试将touchstartmousedown结合在一个函数中时遇到了问题。我使用了a标签作为函数的目标元素,以便当我触摸或点击该标签时直接转到链接。

问题是当我触摸a标签的中间部分时,链接不会响应。只有当我点击元素或触摸a标签的边缘时,它才能正常工作,并且输出触发mousedown

enter image description here

在移动模式下,尽可能像上图中的灰点一样点击a标签的边缘。我创建了一个CodePen示例,以便更好地查看、测试和理解。

我该如何解决这个问题?

class Slider {
  constructor($el, paragraph) {
    this.$el = $el;
    this.paragraph = paragraph;
  }
  start(e) {
    e.preventDefault();
    var type = e.type;
    if (type === 'touchstart' || type === 'mousedown') this.paragraph.text(this.paragraph.text() + ' ' + type);
    return false;
  }
  apply() {
    this.$el.bind('touchstart mousedown', (e) => this.start(e));
  }
}
const setSlider = new Slider($('#anchor'), $('.textbox'), {passive: false});
setSlider.apply();
  a {
    display: block;
    width: 100px;
    height: 100px;
    background-color: orange;
  }
<a id="anchor" href="https://google.co.uk">Tap or Click Me</a>
<p class="textbox"></p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

========= 进展更新 ==========

我刚刚添加了moveend函数,然后我必须点击两次才能跳转到链接的网站。这种情况越来越糟,并不知道如何解决这个问题。

class Slider {
  constructor($el, paragraph) {
    this.$el = $el;
    this.paragraph = paragraph;
  }
  start(e) {
    e.preventDefault();
    var type = e.type;
    if (type === 'touchstart' || type === 'mousedown') this.paragraph.text(this.paragraph.text() + ' ' + type);
    this.$el.bind('touchmove mousemove', (e) => this.move(e));
    this.$el.bind('touchend mouseup', (e) => this.end(e));
    return false;
  }
  move(e) {
    var type = e.type;
    if (type === 'touchstart' || type === 'mousedown') this.paragraph.text(this.paragraph.text() + ' ' + type);
    return false;
  }
  end(e) {
    console.log('test');
    this.$el.on('click');
    this.$el.off('touchstart touchend');
    return false;
  }
  apply() {
    this.$el.bind('touchstart || mousedown', (e) => this.start(e));

  }
}
const setSlider = new Slider($('#anchor'), $('.textbox'));
setSlider.apply(); 


======== 悬赏后的进展更新(最新) ========

经过多次尝试,我终于找到并解决了之前的问题,但是我面临着一个新问题,就是无法实现拖动和立即重定向。

当我在开始函数中使用 preventDefault 时,所有事件都可以正常工作。这种情况下唯一的问题是拖动不会阻止来自a标签的重定向链接。不管是点击还是拖动元素,它总是把我带到网站上。

当我不使用 preventDefault 时,拖动不起作用,只有通过点击元素才能起作用。

我的最终目标是防止在两个事件 touchmovemousemove 中重定向 a 标签的链接。我已经在谷歌上搜索了很多次,但仍没有任何线索。

我在 Codepen 上编写了一个示例,并且目前为止,这就是我所做的。

class Slider {
  constructor($el, paragraph) {
    this.$el = $el;
    this.paragraph = paragraph;
  }
  start(e) {
    var type = e.type;
    if (type === 'touchstart') {
      this.paragraph.text(this.paragraph.text() + ' ' + type);
    } else if (type === 'mousedown') {
      this.paragraph.text(this.paragraph.text() + ' ' + type);
    }
  }
  move(e) {
    var type = e.type;
  }
  end(e) {
    var type = e.type;
    if (type === 'touchend') {
      console.log('touchstart enabled');
    } else if (type === 'mouseup') {
      console.log('mousedown enabled');
    }
  }
  apply() {
    this.$el.bind({
      touchstart: (e) => this.start(e),
      touchmove: (e) => this.move(e),
      touchend: (e) => this.end(e),
      mousedown:(e) => this.start(e),
      onmousemove: (e) => this.move(e),
      mouseup:  (e) => this.end(e)
    });
  }
}
const setSlider = new Slider($('#anchor'), $('.textbox'));
setSlider.apply();
    a {
      display: block;
      width: 100px;
      height: 100px;
      background-color: orange; 
    }
    <a id="anchor" href="https://google.co.uk">Tap or Click Me</a>
    <p class="textbox"></p>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


上面提到的 CodePen 对我来说似乎运行良好。 - varun agarwal
@varunagarwal 当你触摸a标签的中间部分时,它会将你的浏览器更改为谷歌吗? - l3lue
@varunagarwal 你使用Firefox吗?那么我认为你应该使用Chrome来更清楚地了解我的问题。我刚在Firefox中进行了测试,它向我显示了“mousedown”文本。 - l3lue
@varunagarwal 是的,在Firefox中,touchevent正常工作,就像我预期的那样。当我触摸a标签的中间部分时,它会将我带到Google,就像移动语句一样。但在Chrome中,它不起作用。 - l3lue
我正在使用 Chrome。 - varun agarwal
显示剩余4条评论
2个回答

6

我认为我已找到了解决方案。我添加了这段代码,以供将来像我一样努力搜索同样问题的人参考。

    function start(event, etype, condition) {
      console.log(etype); // track the type of event
      if (!condition) event.preventDefault(); // compare etype(eventType). Set preventDefault if condition is falsy.
      items.off('click');
      items.on({
        ['touchmove mousemove']: (event) => move(event, etype, condition),
        ['touchend mouseup']: end
      });
    }

    function move(event, etype, cnd) {
      if (cnd) event.preventDefault();
      console.log(cnd); // track the type of event from the condition
      items.on('click', function(event) {event.preventDefault();});
    }

    function end(event) {
      items.off('touchmove mousemove touchend mouseup');
    }
    var items = $('.item a');
    items.on('touchstart mousedown', function() {
      var eventType = event.type;
      var condition = (eventType === 'touchstart' || eventType === 'mousedown');
      start(event, eventType, condition);
    });
    #anchor {
      display: block;
      width: 100px;
      height: 100px;
      background-color: orange;
    }
    .item {
    background-color: gray;
    }

    .item + .item {
        margin-top: 10px;
    }

    .item a {
        cursor: pointer;
        display: inline-block;
        background-color: blue;
        color: white;
        padding: 9px;
        width: 100%;
        height: 100%;
    }
    <div id="items" class="items">
      <div class="item">
          <a target="_blank" href="https://google.com">Anchor</a>
      </div>
      <div class="item">
          <a target="_blank" href="https://google.com">Anchor</a>
      </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


1
很高兴你找到了解决方案,感谢你的分享。这肯定会帮助寻找类似问题的人们。 - Galzor
@Galzor 不客气,Glazor,或者将来会找到这个解决方案的人。 - l3lue

4

我想我为您找到了一个小解决方案。启用preventDefault,然后启用a标签的draggable属性。如果这对您有用,请告诉我。

 start(e) {
  e.preventDefault();
  ...//rest of the code
 apply() {
  $el.draggable("enable");
  ...//rest of the code

谢谢您的回答,但这对我没有用。 - l3lue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接