jquery предотвращать по умолчанию связанный якорь при двойном щелчке - PullRequest
1 голос
/ 11 ноября 2010

Описание
На сайте нашего сообщества ник каждого пользователя - это ссылка на страницу их профиля, но если дважды щелкнуть по нику, под ним появится меню для этого пользователя.Содержимое этого всплывающего меню загружается с помощью вызова ajax.До сих пор мы использовали javascript: в hrefs привязки и ловили одиночные / двойные щелчки, используя JS.Мы хотели очистить ссылки и добавить соответствующие URL-адреса, чтобы пользователи могли открывать ссылки на профили во вкладках и т. Д., Сохраняя при этом меню двойного щелчка.Я понимаю, что это не самый лучший дизайн, это стало своего рода навязчивой идеей, чтобы начать работать.

Проблема
Поэтому я хочу, чтобы отдельные клики работали как обычно (отправьте браузер на href), в то время как двойной щелчок предотвращаетDefault и вызывает вместо нее пользовательскую функцию (событие).Я могу сделать это, используя window.location в одном клике, но это похоже на компромисс / хак, который я хотел улучшить.

Код до настоящего времени
Использование ответа 1067484 из вопроса 1067464 (не разрешено публиковать ссылки) в качестве основы для следующего

    jQuery(document).ready(function($) {
        $("#hello")
            .bind('click', singleClick)
            .bind('dblclick', doubleClick);
    });

    function singleClick(e) {
        e.preventDefault();
        var el = this;
        setTimeout(function() {
        var dblclick = parseInt($(el).data('double'), 10);
            if (dblclick > 0) {
                $(el).data('double', dblclick-1);
            } else {
                $('#result').html('click registered - browser should proceed to url');
                // Attempting to make browser follow original href url:
                $(el).unbind('click', singleClick);
            }
        }, 300);
    }

    function doubleClick(e) {
        $(this).data('double', 2);
        e.preventDefault();
        $('#result').html('double-click registered - browser should stay here');
        // Display dblclick popup-menu here
    }

(Просмотр / редактирование в прямом эфире на http://jsbin.com/iboyo5/2)

Мне не хватает только этой части одним щелчком, я хотел "чище", чем window.location, и этопочему я возился с .unbind (), который тоже не является 100% решением.Функция .unbind () делает то, что я хочу, но она не выгружает обработчик для текущего выполнения кода, поэтому она работает только один раз для каждых двух кликов.Это проблема, которую мне нужно исправить сейчас.

Кстати: я не против, если первый .click приостановлен для установленной задержки.Необходимость подождать 300 мс, прежде чем URL-адрес «запустится», не проблема.
Я собираюсь отказаться от этого и использовать window.location?Можно ли это решить с помощью .live () и .die ()?

Надеюсь, я провёл достаточно хорошее исследование перед моим первым постом здесь.Спасибо!

Ответы [ 2 ]

0 голосов
/ 16 ноября 2010

Публикация того, что мы получили, на тот случай, если другим понадобится такая же функциональность позже.Это использует window.location, чтобы «отменить» действие предотвращение дефолта.Я хотел бы научиться более чистому подходу, но пока оставлю этот вопрос решенным.

jQuery(document).ready(function($) {

  /* Member popup menu - Handle single and double clicks for member-links */
  function singleClick(e) {
    e.preventDefault();
    var url = $(this).attr("href");
    var el = this;
    setTimeout(function() {
      var dblclick = parseInt($(el).data('double'), 10);
      if (dblclick > 0) {
        $(el).data('double', dblclick-1);
      } else {
        $('#result').html('click registered - browser should proceed to url');
        window.location = url;
      }
    }, 300);
  }

  function doubleClick(e) {
    e.preventDefault();
    $('#result').html('double-click registered - browser should stay here');
    $(this).data('double', 2);
    var full_id = $(this).attr("id");
    var ids = full_id.split("_");
    var id = ids[1];
    $.ajax({
      url: "....php",
      data: {
        page: "ajax.getMemberPopup",
        id: id
      },
    });
  }

  $(".profile")
    .bind('click', singleClick)
    .bind('dblclick', doubleClick);
  /* End member popup menu */
});
0 голосов
/ 11 ноября 2010

Следующее решение должно помочь вам получить желаемую функциональность:

Пример разметки:

<a class="profile" href="#">Stewie</a>
<br/>
<a class="profile" href="#">Brian</a>
<br/>
<div id="result"/>

Javascript:

var clickCount = 0;
var clickTimeout;
var currentTarget;

function evaluateClicks(targetElement) {
    if (clickCount === 1) {
        $("#result").text(targetElement.text() + ": clicked once");
    } else if (clickCount > 1) {
        $("#result").text(targetElement.text() + ": clicked twice or more");
    }
    clickCount = 0;
}

$("a.profile").click(function(e) {
    e.preventDefault();
    var targetElement = $(e.target);
    /*check to see if the target's href is the same
    the comparison does not need to be on the href, just something
    so you can differentiate the two elements from each other.
    */
    if (currentTarget && targetElement.attr("href") !== currentTarget.attr("href")) {
        clearTimeout(clickTimeout);
        clickCount = 0;
    }
    currentTarget = targetElement;
    clickCount++;
    var thingToDo = function() {
        evaluateClicks(targetElement);
    };
    //reset the current timeout
    clearTimeout(clickTimeout);
    clickTimeout = setTimeout(thingToDo, 300);
});

Обратите внимание, что сравнение между элементами основано на атрибуте href, предполагая, что они уникальны.

...