2014-04-28 21 views
6

Próbuję coś szalonego, chciałbym wdrożyć funkcję Instagram: dwa razy stuka, aby polubić.Kliknij dwukrotnie konflikt (jQuery and Hammer.js)

Używam najnowszych wersji jQuery i Hammer.js. Nie jestem zaawansowanym profesjonalistą, ale próbowałem napisać kod JavaScript, aby zidentyfikować to wydarzenie.

var postDoubleTapped; 
postDoubleTapped = false; 

Hammer($('.post').get(0)).on('doubletap', function(event) { 
    event.preventDefault(); 
    postDoubleTapped = true; 

    console.log('Double tap!'); 
    return false; 
}); 

$(document).on('click', '.post a', function(event) { 
    event.preventDefault(); 
    console.log(postDoubleTapped); 

    setTimeout((function(_this) { 
    return function() { 
     if (!postDoubleTapped) { 
     location.href = $(_this).attr('href'); 
     } 
     postDoubleTapped = false; 
    }; 
    })(this), 500); 
    return false; 
}); 

Jak widać na przykładzie (http://codepen.io/caio/pen/vqEjc) nie działa. Powraca konsoli:

Console

Jest jeszcze inny problem, nie mogę odtworzyć cel _blank na a tagu.

Czy jest to lepsza metoda? Czy jestem na dobrej drodze? Jak mogę to naprawić?

Odpowiedz

0

Jesteś na właściwej drodze, ale podwójne kliknięcie przypomina kliknięcie dwa razy. Więc użyć młotka w obu przypadkach tak:

var i=0; 
Hammer($('.post').get(0)).on('doubletap', function(event) { 
    i++; 
    console.log('double tap' + i); 
}); 

$(".post a").hammer(); 
$(".post a").on('tap', function (event) { 
    i++; 
    console.log('single tap' + i); 
}); 
0

Zamiast obsługiwać przekierowanie siebie, można wywołać kliknięcie programowo:

fireEvent(_this, 'click'); 

Wewnątrz click obsługi można sprawdzić, czy zdarzenie został zwolniony programowo:

$(document).on('click', '.post a', function(event) { 

    // ignore the handler when the click is fired programmatically 
    if (event.originalEvent.synthetic) { 
     return; 
    } 
    ... 

Oznacza to, że nadal używany jest _blank. To wymaga następującą funkcję do ognia zdarzenia w większości przeglądarek:

/** 
* Fire an event handler to the specified node. Event handlers can detect that the event was fired programatically 
* by testing for a 'synthetic=true' property on the event object 
* @param {HTMLNode} node The node to fire the event handler on. 
* @param {String} eventName The name of the event without the "on" (e.g., "focus") 
*/ 
function fireEvent(node, eventName) { 
    // Make sure we use the ownerDocument from the provided node to avoid cross-window problems 
    var doc; 
    if (node.ownerDocument) { 
     doc = node.ownerDocument; 
    } else if (node.nodeType == 9){ 
     // the node may be the document itself, nodeType 9 = DOCUMENT_NODE 
     doc = node; 
    } else { 
     throw new Error("Invalid node passed to fireEvent: " + node.id); 
    } 

    if (node.dispatchEvent) { 
     // Gecko-style approach (now the standard) takes more work 
     var eventClass = ""; 

     // Different events have different event classes. 
     // If this switch statement can't map an eventName to an eventClass, 
     // the event firing is going to fail. 
     switch (eventName) { 
      case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead. 
      case "mousedown": 
      case "mouseup": 
       eventClass = "MouseEvents"; 
       break; 

      case "focus": 
      case "change": 
      case "blur": 
      case "select": 
       eventClass = "HTMLEvents"; 
       break; 

      default: 
       throw "fireEvent: Couldn't find an event class for event '" + eventName + "'."; 
       break; 
     } 
     var event = doc.createEvent(eventClass); 

     var bubbles = eventName == "change" ? false : true; 
     event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable. 

     event.synthetic = true; // allow detection of synthetic events 
     // The second parameter says go ahead with the default action 
     node.dispatchEvent(event, true); 
    } else if (node.fireEvent) { 
     // IE-old school style 
     var event = doc.createEventObject(); 
     event.synthetic = true; // allow detection of synthetic events 
     node.fireEvent("on" + eventName, event); 
    } 
}; 

Innym problemem w kodzie było to, że czas oczekiwania nie został odwołany. Zmieniłem go:

if (postDoubleClickTimeout) { 
    clearTimeout(postDoubleClickTimeout); 
} 
postDoubleClickTimeout = setTimeout(...); 

Teraz

Zobacz http://codepen.io/anon/pen/fsApG

+0

Chrome blokuje "kliknięcie" –

+0

Tak, nie jestem pewien, czy możesz zapobiec blokowaniu wyskakujących okienek podczas otwierania nowego okna programowo.Myślę, że jest to dozwolone tylko w rzeczywistym onclick łącza, w twoim przypadku 'setInterval' oznacza, że ​​twój kod będzie exe wycięte poza faktycznym onclick. Usuń 'target =" _ blank "', a kliknięcie zostanie wyzwolone. – sroes

0

spróbować („. Post '$() get (0)) off (' DoubleTap ') o (' DoubleTap.. ', function (event) {użyj off click

+0

również zmień $ (dokument) .off ("kliknij"). On ("kliknij", ".post a", funkcja (zdarzenie) { –