I have the following code which I got from the hammer documentation, however the listener isn't firing for me. I can't figure out why I can't get drag to work.
Also, I attempted to do my own drag like feature using tap, pan, but again how do I get an event for detecting a release? I see examples online with people using: touch.on("release", function(ev) {}); but I get absolutely nothing.
var options = {
dragLockToAxis: true,
dragBlockHorizontal: true
};
//Hammer.js dependency. Setup touch
touch = new Hammer(el, options);
touch.on("dragleft dragright", function(ev) {
console.log("handle released");
});
It's pan not drag (not sure when they changed it)
http://jsbin.com/suleyilejili/2/edit
http://hammerjs.github.io/recognizer-pan/
Related
I'm looking for the best solution to adding both "doubletap" and "longtap" events for use with jQuery's live(), bind() and trigger(). I rolled my own quick solution, but it's a little buggy. Does anyone have plugins they would recommend, or implentations of their own they'd like to share?
It has been reported to jQuery as a bug, but as doubletapping isn't the same as doubleclicking, it does not have a high priority. However, mastermind Raul Sanchez coded a jquery solution for doubletap which you can probably use!
Here's the link, works on mobile Safari.
It's easy to use:
$('selector').doubletap(function() {});
-edit-
And there's a longtap plugin here! You can see a demo on your iPad or iPhone here.
rsplak's answer is good. I checked out that link and it does work well.
However, it only implements a doubletap jQuery function
I needed a custom doubletap event that I could bind/delegate to. i.e.
$('.myelement').bind('doubletap', function(event){
//...
});
This is more important if you're writing a backbone.js style app, where there is a lot of event binding going on.
So I took Raul Sanchez's work, and turned it into a "jQuery special event".
Have a look here: https://gist.github.com/1652946 Might be useful to someone.
Just use a multitouch JavaScript library like Hammer.js. Then you can write code like:
canvas
.hammer({prevent_default: true})
.bind('doubletap', function(e) { // Also fires on double click
// Generate a pony
})
.bind('hold', function(e) {
// Generate a unicorn
});
It supports tap, double tap, swipe, hold, transform (i.e., pinch) and drag. The touch events also fire when equivalent mouse actions happen, so you don't need to write two sets of event handlers. Oh, and you need the jQuery plugin if you want to be able to write in the jQueryish way as I did.
I wrote a very similar answer to this question because it's also very popular but not very well answered.
You can also use jQuery Finger which also supports event delegation:
For longtap:
// direct event
$('selector').on('press', function() { /* handle event */ });
// delegated event
$('ancestor').on('press', 'selector', function() { /* handle event */ });
For double tap:
// direct event
$('selector').on('doubletap', function() { /* handle event */ });
// delegated event
$('ancestor').on('doubletap', 'selector', function() { /* handle event */ });
Here's a pretty basic outline of a function you can extend upon for the longtap:
$('#myDiv').mousedown(function() {
var d = new Date;
a = d.getTime();
});
$('#myDiv').mouseup(function() {
var d = new Date;
b = d.getTime();
if (b-a > 500) {
alert('This has been a longtouch!');
}
});
The length of time can be defined by the if block in the mouseup function. This probably could be beefed up upon a good deal. I have a jsFiddle set up for those who want to play with it.
EDIT: I just realized that this depends on mousedown and mouseup being fired with finger touches. If that isn't the case, then substitute whatever the appropriate method is... I'm not that familiar with mobile development.
based on latest jquery docs i've written doubletap event
https://gist.github.com/attenzione/7098476
function itemTapEvent(event) {
if (event.type == 'touchend') {
var lastTouch = $(this).data('lastTouch') || {lastTime: 0},
now = event.timeStamp,
delta = now - lastTouch.lastTime;
if ( delta > 20 && delta < 250 ) {
if (lastTouch.timerEv)
clearTimeout(lastTouch.timerEv);
return;
} else
$(this).data('lastTouch', {lastTime: now});
$(this).data('lastTouch')['timerEv'] = setTimeout(function() {
$(this).trigger('touchend');
}, 250);
}
}
$('selector').bind('touchend', itemTapEvent);
// Setup map
var polymap = L.map('map').setView([51.932994, 4.509373], 14);
// Setup tilelayer
var mapquestUrl = 'http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png',
subDomains = ['otile1', 'otile2', 'otile3', 'otile4'],
mapquestAttrib = 'Data, imagery and map information provided by MapQuest,'
+ 'OpenStreetMap and contributors.';
var osm = L.tileLayer(mapquestUrl, {
attribution: mapquestAttrib,
subdomains: subDomains
});
polymap.addLayer(osm);
polymap.on('mousedown touchstart', function onMouseDown(event) {
alert("start");
});
JSFiddle
Leaflet should normally fire the touchstart event as it does with the mousedown event, but using a mobile phone, I get no event fired.
Can somebody tell me if there's any mistake in the code, that prevents the touchevent from firing?
I have added touch events to leaflet in a branch https://github.com/lee101/Leaflet/tree/add-mobile-touch-events
There is still a problem with touchend events not getting fired if a touchstart event happens on a map control.
You can build the source with npm install && jake after you clone the repository.
I should hopefully contribute it back after i fix that issue.
It is difficult to get normal touch events working properly with leaflet map because the map itself use touch events to permit zoom & pan function.
To avoid this issue, you may use this
library to catch specific touch event (tap,double tap,press,flick,drag)
<script src="http://domain.ltd/path/jquery.finger.js"></script>
$.Finger = {
pressDuration: 300,
doubleTapInterval: 300,
flickDuration: 150,
motionThreshold: 5
};
polymap.on('tap', function(e) {
alert("start");
});
Best regards
I'm using the HTML5 rabid scratch plugin to achieve a grid of little panels that can be scratched off to reveal images behind.
Demo:
http://jsfiddle.net/CeTR8/2/
Problem:
When you click and drag over a panel, it scratches that panel but you have to mouseup and mousedown for each panel. I'd like scratch from one to another without having to mouseup and mousedown.
I've tried making the following modifications to trigger on mousemove (if mouse button is also down) and it's somewhat working on safari/chrome in Mac but not in IE9 and probably others..
// Bind downHandler to mousemover instead
self.theCanvas.bind('mousemove', $.proxy(self.addDownHandler, self));
// self.theCanvas.bind('mousedown', $.proxy(self.addDownHandler, self));
// self.theCanvas.bind('mouseup', $.proxy(self.addUpHandler, self));
// $(window).bind('mouseup', $.proxy(self.addUpHandler, self));
....
addDownHandler: function (e) {
// only scratch if mouse down
if(e.which == 1){
var self = this;
self.theCanvas.bind('mousemove', $.proxy(self.mouseMoveHandler, self));
}
}
Current
http://jsfiddle.net/CeTR8/3/
Is there a better way to do this that will work across browsers?
http://jsfiddle.net/ericjbasti/CeTR8/5/
Changed
self.theCanvas.bind('mousedown', $.proxy(self.addDownHandler, self));
to
$(window).bind('mousedown', $.proxy(self.addDownHandler, self));
I played around with a webdesign where jQuery is available. There is now a point where I need the opposite Eventwatching, so I realized it already with a jQuery routine which installs an "onnomousemove" event. Yes, you read correct, an NOT HAPPENING EVENT.
(Below) you find my allready working solution in jQuery. The idea is to have control over not happening Events and to react on that via this extra specified jQuery.Event
Hehe, I know most stupid would be to handle "onnoerror" Events with this. But thats not desired. Its working now and I want to go a step forward here. So what is my problem?
Here it comes: How to fire the same behavior with native Javascript EventListening so element.addEventListener(...); can handle the same Events too?
Problem: newer Web browser like Chrome, Firefox have an implemented CustomEvent handling to make this happen, but in older browsers there should be a way with prototype or so.
I'm a bit jQuery blind now, anyway is there somebody out there who knows the freaky trick to generate Custom Events in a traditional way without prototype.js or other libraries? Even a solution with jQuery would be fine, but desired goal is the native listener should be able to handle it.
jQuery:
(function($){
$.fn.extend({
// extends jQuery with the opposite Event Listener
onno:function(eventname,t,fn){
var onnotimer = null;
var jqueryevent = {};
$(this).on( eventname, function(e){
window.clearTimeout(onnotimer);
function OnNoEventFn(){
jqueryevent = jQuery.Event( "onno"+eventname );
$(this).trigger(jqueryevent);
e.timeStampVision=e.timeStamp+t;
e.timer=t; e.type="onno"+eventname;
fn(e);
}
onnotimer = window.setTimeout( OnNoEventFn, t);
});
return $(this);
}
});
})(jQuery);
$(document).ready(function() {
// installs "onnomousemove" and fires after 5sec if mousemove does not happen.
$(window).onno('mousemove', 5000, function(e){
console.log('function fires after:'+e.timer+'ms at:'+e.timeStampVision+'ms with:"'+e.type+'" event, exact fired:', e.timeStamp);
});
// installs "onnoclick" and fires after 4sec if click does not happen.
$(window).onno('click', 4000, function(e){
console.log('function fires after:'+e.timer+'ms at:'+e.timeStampVision+'ms with:"'+e.type+'" event, exact fired:', e.timeStamp);
});
// just for demonstration, routine with "onno.." eventnamescheme
$(window).on('onnomousemove',function(e){
console.log( 'tadaaaa: "'+e.type+'" works! with jQuery Event',e);
});
// same for "onnoclick"
$(window).on('onnoclick',function(e){
console.log( 'tadaaaa: "'+e.type+'" works! with jQuery Event',e);
});
});
// but how to install Custom Events even in older Safari ?
// newer Chrome, Firefox & Opera have CustomEvent.
window.addEventListener('onnomousemove',function(e){
console.log('native js is watching you',e);
},false);
I'm using the excellent jQuery knob plugin. However, I need to dynamically enable/disable the element depending on user input. There is support for having a disabled state on page load which have the effect that no mouse (or touch) events are bound to the canvas element. Does anyone know how to resolve this issue, that is, how to (after page load) bind and unbind these mouse event listeners?
Ideally I would like to do something like this (on a disabled knob)
$('.button').click(function() {
$('.knob').enable();
});
Edit:
I ended up rewriting the source which binds/unbinds the mouse and touch events. The solution is not perfect so I leave the question open if someone perhaps have a better (cleaner) solution.
html
<input class="knobSlider" data-readOnly="true">
<button id="testBtn">clickHere</button>
script
in doc ready,
$(".knobSlider").knob();
$("#testBtn").click(function(){
$(".knobSlider").siblings("canvas").remove();
if($(".knobSlider").attr("data-readOnly")=='true'){
$(".knobSlider").unwrap().removeAttr("data-readOnly readonly").data("kontroled","").data("readonly",false).knob();
}
else{
$(".knobSlider").unwrap().attr("data-readOnly",true).data("kontroled","").data("readonly",true).knob();
}
});
For reference you can use my jsfiddle link > http://jsfiddle.net/EG4QM/ (check this in firefox, because of some external resource load problem in chrome)
If someone doesn't like how the accepted answer destroys and recreates the internal canvas element, then checkout my approach:
https://jsfiddle.net/604kj5g5/1/
Essentially, check the draw() implementation (I also recommend listening on value changes in the draw method instead of the change and release, which work for and click and mousewheel events respectively, which imo is inconvenient).
var $input = $("input");
var knobEnabled = true;
var knobPreviousValue = $input.val();
$input.knob({
draw: function () {
if (knobPreviousValue === $input.val()) {
return;
}
if (!knobEnabled) {
$input.val(knobPreviousValue).trigger("change");
return;
}
knobPreviousValue = $input.val();
console.log($input.val());
},
});
Try this to disable the control.
I'm still trying to find a way to enable it back
$("#btnDisable").click(function(){
$("#knob").off().prev().off();
});