Как бы я предотвратить перенаправление href во время сенсорного и мышиного перемещения? - PullRequest
6 голосов
/ 25 марта 2019

У меня проблема, когда я пытаюсь объединить touchstart и mousedown в 1 функцию. Я использовал тег a в качестве целевого элемента функции для перехода к ссылке непосредственно, когда я касался тега или щелкал по нему.

Проблема в том, что когда я touch в середине тега a, ссылка не отвечает. он работает только тогда, когда я click элемент или касаюсь края 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>

========= Обновление прогресса ==========

Я только что добавил функцию move & end, затем мне нужно дважды щелкнуть, чтобы перейти на связанный веб-сайт. Ситуация становится все хуже и не знаю, как решить эту проблему.

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(); 


======== Прогресс обновляется после Bounty (последняя версия) ========

После десятков попыток я наконец-то разобрался и решил предыдущую проблему, но столкнулся с новой проблемой, которую нельзя перетаскивать и перенаправлять мгновенно.

Когда я использую preventDefault в функции запуска, все события работают нормально. Единственная проблема в этом случае - перетаскивание , которое не мешает перенаправлению ссылки из тега a . Он всегда отправляет меня на веб-сайт независимо от того, какие способы вызывать функции, нажимать или перетаскивать.

когда я не использую preventDefault, перетаскивание не работает. это работает только при нажатии элементов.

Моя последняя цель - предотвратить перенаправление ссылки тега a на оба события, touchmove и mousemove. Меня много раз обыскивали в Google, но я ничего не понял.

Я написал пример в 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>

Ответы [ 2 ]

4 голосов
/ 31 марта 2019

Я думаю, что нашел решение по этому поводу. Я добавлю этот код для некоторых людей в будущем, которые изо всех сил пытаются найти ту же проблему, такую ​​как я.

    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>
4 голосов
/ 29 марта 2019

я думаю, что нашел для вас небольшое решение. включите warnDefault, а затем включите перетаскивание для тега. Дайте мне знать, если это работает для вас.

 start(e) {
  e.preventDefault();
  ...//rest of the code
 apply() {
  $el.draggable("enable");
  ...//rest of the code
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...