I've found an interesting resource: Hammer.js. I tried to swipe with Hammer and jQuery.
1) I've downloaded the code here
2) I've put that code in a document. I put a link to that code in the head of the document I want to use swipe: <script src="hammer.js"></script>
3) I do not know how to use it. I try to do something similar to this in jQuery. I mean I want to swipe instead of click:
$(function(){
$(".blue").click(function() {
$(".blue").animate({left: "0"}, 500)
});
})
http://jsfiddle.net/Narcis/rmtXC/
Something like this? http://jsfiddle.net/6jxbv/119/
I'm using Hammer(element).on("event", callback); to get the result. In this case, I added the swipeleft and swiperight events.
The script uses the syntax described above to add events like:
drag, dragstart, dragend, dragup, dragdown, dragleft, dragright
swipe, swipeup, swipedown, swipeleft, swiperight
If you want to use it with jQuery, they provide this syntax (which is kind of awkward if you ask me):
$(elementOrSelector).hammer().on("event", function(event) {
//callback
});
But you have to include the jquery.hammer.js plugin
Try reading the docs for more info
EDIT:
Here, you can see an example using swipe and drag. Take into account that swipe is a fast movement (with the mouse or touch) and drag is pressing and moving (so the implementation it's not correct, but I'll leave the animate to you. :) )
http://jsfiddle.net/uZjCB/183/ and full screen http://jsfiddle.net/uZjCB/183/embedded/result/
Hope it helps
With Hammer.js 2.0 you need to use a Recognizer :
var blue = document.getElementById('blue');
var hammer = new Hammer.Manager(blue);
var swipe = new Hammer.Swipe();
hammer.add(swipe);
hammer.on('swipeleft', function(){
$(blue).animate({left: "-=100"}, 500)
});
hammer.on('swiperight', function(){
$(blue).animate({left: "+=100"}, 500)
});
read more on Hammer documentation
updating the JS fiddle with correct Hammer cdn so now it's working:
$(function(){
var red = document.getElementById("red");
var blue = document.getElementById("blue");
//Swipe
Hammer(red).on("swipeleft", function() {
$(this).find(".color").animate({left: "-=100"}, 500);
$("#event").text("swipe left");
});
Hammer(red).on("swiperight", function() {
$(this).find(".color").animate({left: "+=100"}, 500);
$("#event").text("swipe right");
});
// Drag
Hammer(blue).on("dragleft", function() {
$(this).find(".color").animate({left: "-=100"}, 500);
$("#event").text("drag left");
});
Hammer(blue).on("dragright", function() {
$(this).find(".color").animate({left: "+=100"}, 500);
$("#event").text("drag right");
});
});
Try this way with hammer.js v2.0.8
https://jsfiddle.net/elijah123467/q6m84wgt/6/
var body = $("#body");
var navbar = $("#navbar");
var hammertimeBodyRight = new Hammer.Manager(body[0], {
recognizers: [
[Hammer.Swipe, { direction: Hammer.DIRECTION_RIGHT}]
]
});
hammertimeBodyRight.on("swipe", function (ev) {
var canvasSlid = navbar.hasClass("canvas-slid");
if (!canvasSlid) {
$(".navbar-toggle").click();
}
});
var hammertimeBodyLeft = new Hammer.Manager(body[0], {
recognizers: [
[Hammer.Swipe, { direction: Hammer.DIRECTION_LEFT}]
]
});
hammertimeBodyLeft.on("swipe", function (ev) {
var canvasSlid = navbar.hasClass("canvas-slid");
if (canvasSlid) {
$(".navbar-toggle").click();
}
});
var hammertimeNavbarRight = new Hammer.Manager(navbar[0], {
recognizers: [
[Hammer.Swipe, { direction: Hammer.DIRECTION_RIGHT}]
]
});
hammertimeNavbarRight.on("swipe", function (ev) {
var canvasSlid = navbar.hasClass("canvas-slid");
if (!canvasSlid) {
$(".navbar-toggle").click();
}
});
var hammertimeNavbarLeft = new Hammer.Manager(navbar[0], {
recognizers: [
[Hammer.Swipe, { direction: Hammer.DIRECTION_LEFT}]
]
});
hammertimeNavbarLeft.on("swipe", function (ev) {
var canvasSlid = navbar.hasClass("canvas-slid");
if (canvasSlid) {
$(".navbar-toggle").click();
}
});
Related
Hi I have a slider image gallery built with slides.js. The slider works pretty well but I need to implement swipe functionality. To get it I've thought to make a swipe callback with Hammer.js and make a function to force the slider to slide the image to the next one or the previous one. But I don't know if Slides.js has this option. What I want to do would be something like this:
document.addEventListener("DOMContentLoaded", function() {
var listItems = document.getElementsByTagName("body");
var touchControl = new Hammer(listItems[0]);
touchControl.on("panright", function(event) {
// Here is what I'm not sure how to do it
$("slider").slide
}
});
Well this is what I've done to make it work
document.addEventListener("DOMContentLoaded", function() {
var item = document.getElementsByClassName("flexslider");
var touchControl = new Hammer(item[0]);
touchControl.on("panright", function(event) {
if (event.distance > 250) {
$(".flexslider").flexslider("prev");
}
});
});
document.addEventListener("DOMContentLoaded", function() {
var item = document.getElementsByClassName("flexslider");
var touchControl = new Hammer(item[0]);
touchControl.on("panleft", function(event) {
console.log(event.distance)
if (event.distance > 250) {
$(".flexslider").flexslider("next");
}
});
});
I want to make the sticky-nav to act similar(scroll is off when the menu is expanded) to this website's nav(http://amandagerhardsen.com/#cloudbusting/4) when expanded.
How do I do it?
var Boxlayout = (function () {
var $el = $('#sticky-nav'),
$sections = $el.children('section'),
// work panels
$workPanelsContainer = $('#bl-panel-work-items'),
// close work panel trigger
$closeWorkItem = $workPanelsContainer.find('nav > span.hidemenu'),
transEndEventNames = {
'WebkitTransition': 'webkitTransitionEnd',
'MozTransition': 'transitionend',
'OTransition': 'oTransitionEnd',
'msTransition': 'MSTransitionEnd',
'transition': 'transitionend'
},
// transition end event name
transEndEventName = transEndEventNames[Modernizr.prefixed('transition')],
// support css transitions
supportTransitions = Modernizr.csstransitions;
function init() {
initEvents();
}
function initEvents() {
$sections.each(function () {
var $section = $(this);
// expand the clicked section and scale down the others
$section.on('click', function () {
if (!$section.data('open')) {
$section.data('open', true).addClass('bl-expand bl-expand-top');
$el.addClass('bl-expand-item');
}
}).find('span.hidemenu').on('click', function () {
// close the expanded section and scale up the others
$section.data('open', false).removeClass('bl-expand').on(transEndEventName, function (event) {
if (!$(event.target).is('section')) return false;
$(this).off(transEndEventName).removeClass('bl-expand-top');
});
if (!supportTransitions) {
$section.removeClass('bl-expand-top');
}
$el.removeClass('bl-expand-item');
return false;
});
});
// clicking on a work item: the current section scales down and the respective work panel slides up
$workItems.on('click', function (event) {
// scale down main section
$sectionWork.addClass('bl-scale-down');
// show panel for this work item
$workPanelsContainer.addClass('bl-panel-items-show');
var $panel = $workPanelsContainer.find("[data-panel='" + $(this).data('panel') + "']");
currentWorkPanel = $panel.index();
$panel.addClass('bl-show-work');
return false;
});
// navigating the work items: current work panel scales down and the next work panel slides up
$nextWorkItem.on('click', function (event) {
if (isAnimating) {
return false;
}
isAnimating = true;
var $currentPanel = $workPanels.eq(currentWorkPanel);
currentWorkPanel = currentWorkPanel < totalWorkPanels - 1 ? currentWorkPanel + 1 : 0;
var $nextPanel = $workPanels.eq(currentWorkPanel);
$currentPanel.removeClass('bl-show-work').addClass('bl-hide-current-work').on(transEndEventName, function (event) {
if (!$(event.target).is('div')) return false;
$(this).off(transEndEventName).removeClass('bl-hide-current-work');
isAnimating = false;
});
if (!supportTransitions) {
$currentPanel.removeClass('bl-hide-current-work');
isAnimating = false;
}
$nextPanel.addClass('bl-show-work');
return false;
});
// clicking the work panels close button: the current work panel slides down and the section scales up again
$closeWorkItem.on('click', function (event) {
// scale up main section
$sectionWork.removeClass('bl-scale-down');
$workPanelsContainer.removeClass('bl-panel-items-show');
$workPanels.eq(currentWorkPanel).removeClass('bl-show-work');
return false;
});
}
return {
init: init
};
})();
Here is a fiddle: http://jsfiddle.net/77P2e/
Be careful to unlock scrolling again when done, or this could be very annoying for the user!
Setup code
var $window = $(window), previousScrollTop = 0, scrollLock = false;
$window.scroll(function(event) {
if(scrollLock) {
$window.scrollTop(previousScrollTop);
}
previousScrollTop = $window.scrollTop();
});
To lock scroll position:
scrollLock = true;
And to unlock again...
scrollLock = false;
As an example use, you could lock the window scroll position when the mouse enters the navigation area, and unlock it again when the mouse leaves:
$("nav")
.mouseenter(function(){ scrollLock = true; })
.mouseleave(function(){ scrollLock = false; });
In my opinion the accepted answer is not what should be achieved, as the window.scroll() function will be still running (endlessly), even if the 'event' has occured.
The window.scroll() function is an event handler. So use on() to bind the event and off() to unbind it (after the 'event' has occured).
$(window).on('scroll', function() { // bind event handler
var offset = $(window).scrollTop();
console.log("page Y-Offset: ", offset); // just to see it working
if(offset >= 100) $(window).off('scroll'); // unbind the event handler when the condition is met
});
The Javascript solution is a little janky for me, on mobile. It's like it scrolls a little bit and then snaps back into place.
However, I figured out a way to do it much more cleanly, without any jank, just by changing CSS's overflow property on the part you don't want to scroll. Here's the code in d3 but the concept should be pretty clear:
var body = d3.select('body');
var preventScroll = function () {
body.style('overflow', 'hidden');
},
allowScroll = function () {
body.style('overflow', 'scroll');
};
d3.select('#sticky-nav')
.on('touchmove', preventScroll)
.on('touchstart', preventScroll)
.on('touchend', allowScroll)
.on('touchcancel', allowScroll);
As I was using jquery animation,
if ($(window).scrollTop() >= $('.btn').offset().top + $('.btn').outerHeight() - window.innerHeight)
{
$(".tab").stop();
}
I did this and it worked.
.btn is the button. That .tab div would stop if it scrolls to that position.
If you're using jquery animation you can try using the stop() function on the animated object.
I want to be able to fire an event when a user clicks on a button, then holds that click down for 1000 to 1500 ms.
Is there jQuery core functionality or a plugin that already enables this?
Should I roll my own? Where should I start?
var timeoutId = 0;
$('#myElement').on('mousedown', function() {
timeoutId = setTimeout(myFunction, 1000);
}).on('mouseup mouseleave', function() {
clearTimeout(timeoutId);
});
Edit: correction per AndyE...thanks!
Edit 2: using bind now for two events with same handler per gnarf
Aircoded (but tested on this fiddle)
(function($) {
function startTrigger(e) {
var $elem = $(this);
$elem.data('mouseheld_timeout', setTimeout(function() {
$elem.trigger('mouseheld');
}, e.data));
}
function stopTrigger() {
var $elem = $(this);
clearTimeout($elem.data('mouseheld_timeout'));
}
var mouseheld = $.event.special.mouseheld = {
setup: function(data) {
// the first binding of a mouseheld event on an element will trigger this
// lets bind our event handlers
var $this = $(this);
$this.bind('mousedown', +data || mouseheld.time, startTrigger);
$this.bind('mouseleave mouseup', stopTrigger);
},
teardown: function() {
var $this = $(this);
$this.unbind('mousedown', startTrigger);
$this.unbind('mouseleave mouseup', stopTrigger);
},
time: 750 // default to 750ms
};
})(jQuery);
// usage
$("div").bind('mouseheld', function(e) {
console.log('Held', e);
})
I made a simple JQuery plugin for this if anyone is interested.
http://plugins.jquery.com/pressAndHold/
Presumably you could kick off a setTimeout call in mousedown, and then cancel it in mouseup (if mouseup happens before your timeout completes).
However, looks like there is a plugin: longclick.
var _timeoutId = 0;
var _startHoldEvent = function(e) {
_timeoutId = setInterval(function() {
myFunction.call(e.target);
}, 1000);
};
var _stopHoldEvent = function() {
clearInterval(_timeoutId );
};
$('#myElement').on('mousedown', _startHoldEvent).on('mouseup mouseleave', _stopHoldEvent);
Here's my current implementation:
$.liveClickHold = function(selector, fn) {
$(selector).live("mousedown", function(evt) {
var $this = $(this).data("mousedown", true);
setTimeout(function() {
if ($this.data("mousedown") === true) {
fn(evt);
}
}, 500);
});
$(selector).live("mouseup", function(evt) {
$(this).data("mousedown", false);
});
}
I wrote some code to make it easy
//Add custom event listener
$(':root').on('mousedown', '*', function() {
var el = $(this),
events = $._data(this, 'events');
if (events && events.clickHold) {
el.data(
'clickHoldTimer',
setTimeout(
function() {
el.trigger('clickHold')
},
el.data('clickHoldTimeout')
)
);
}
}).on('mouseup mouseleave mousemove', '*', function() {
clearTimeout($(this).data('clickHoldTimer'));
});
//Attach it to the element
$('#HoldListener').data('clickHoldTimeout', 2000); //Time to hold
$('#HoldListener').on('clickHold', function() {
console.log('Worked!');
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<img src="http://lorempixel.com/400/200/" id="HoldListener">
See on JSFiddle
Now you need just to set the time of holding and add clickHold event on your element
Try this:
var thumbnailHold;
$(".image_thumb").mousedown(function() {
thumbnailHold = setTimeout(function(){
checkboxOn(); // Your action Here
} , 1000);
return false;
});
$(".image_thumb").mouseup(function() {
clearTimeout(thumbnailHold);
});
I'd like to do some fancy jQuery stuff when the user scrolls the page. But I have no idea how to tackle this problem, since there is only the scroll() method.
Any ideas?
You can make the scroll() have a time-out that gets overwritten each times the user scrolls. That way, when he stops after a certain amount of milliseconds your script is run, but if he scrolls in the meantime the counter will start over again and the script will wait until he is done scrolling again.
Update:
Because this question got some action again I figured I might as well update it with a jQuery extension that adds a scrollEnd event
// extension:
$.fn.scrollEnd = function(callback, timeout) {
$(this).on('scroll', function(){
var $this = $(this);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout'));
}
$this.data('scrollTimeout', setTimeout(callback,timeout));
});
};
// how to call it (with a 1000ms timeout):
$(window).scrollEnd(function(){
alert('stopped scrolling');
}, 1000);
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<div style="height: 200vh">
Long div
</div>
Here is a simple example using setTimeout to fire a function when the user stops scrolling:
(function() {
var timer;
$(window).bind('scroll',function () {
clearTimeout(timer);
timer = setTimeout( refresh , 150 );
});
var refresh = function () {
// do stuff
console.log('Stopped Scrolling');
};
})();
The timer is cleared while the scroll event is firing. Once scrolling stops, the refresh function is fired.
Or as a plugin:
$.fn.afterwards = function (event, callback, timeout) {
var self = $(this), delay = timeout || 16;
self.each(function () {
var $t = $(this);
$t.on(event, function(){
if ($t.data(event+'-timeout')) {
clearTimeout($t.data(event+'-timeout'));
}
$t.data(event + '-timeout', setTimeout(function () { callback.apply($t); },delay));
})
});
return this;
};
To fire callback after 100ms of the last scroll event on a div (with namespace):
$('div.mydiv').afterwards('scroll.mynamespace', function(e) {
// do stuff when stops scrolling
$(this).addClass('stopped');
}, 100
);
I use this for scroll and resize.
Here is another more generic solution based on the same ideas mentioned:
var delayedExec = function(after, fn) {
var timer;
return function() {
timer && clearTimeout(timer);
timer = setTimeout(fn, after);
};
};
var scrollStopper = delayedExec(500, function() {
console.log('stopped it');
});
document.getElementById('box').addEventListener('scroll', scrollStopper);
I had the need to implement onScrollEnd event discussed hear as well.
The idea of using timer works for me.
I implement this using JavaScript Module Pattern:
var WindowCustomEventsModule = (function(){
var _scrollEndTimeout = 30;
var _delayedExec = function(callback){
var timer;
return function(){
timer && clearTimeout(timer);
timer = setTimeout(callback, _scrollEndTimeout);
}
};
var onScrollEnd = function(callback) {
window.addEventListener('scroll', _delayedExec(callback), false);
};
return {
onScrollEnd: onScrollEnd
}
})();
// usage example
WindowCustomEventsModule.onScrollEnd(function(){
//
// do stuff
//
});
Hope this will help / inspire someone
Why so complicated? As the documentation points out, this http://jsfiddle.net/x3s7F/9/ works!
$('.frame').scroll(function() {
$('.back').hide().fadeIn(100);
}
http://api.jquery.com/scroll/.
Note: The scroll event on Windows Chrome is differently to all others. You need to scroll fast to get the same as result as in e.g. FF. Look at https://liebdich.biz/back.min.js the "X" function.
Some findings from my how many ms a scroll event test:
Safari, Mac FF, Mac Chrome: ~16ms an event.
Windows FF: ~19ms an event.
Windows Chrome: up to ~130ms an event, when scrolling slow.
Internet Explorer: up to ~110ms an event.
http://jsfiddle.net/TRNCFRMCN/1Lygop32/4/.
There is no such event as 'scrollEnd'. I recommend that you check the value returned by scroll() every once in a while (say, 200ms) using setInterval, and record the delta between the current and the previous value. If the delta becomes zero, you can use it as your event.
There are scrollstart and scrollstop functions that are part of jquery mobile.
Example using scrollstop:
$(document).on("scrollstop",function(){
alert("Stopped scrolling!");
});
Hope this helps someone.
The scrollEnd event is coming. It's currently experimental and is only supported by Firefox. See the Mozilla documentation here - https://developer.mozilla.org/en-US/docs/Web/API/Document/scrollend_event
Once it's supported by more browsers, you can use it like this...
document.onscrollend = (event) => {
console.log('Document scrollend event fired!');
};
I pulled some code out of a quick piece I cobbled together that does this as an example (note that scroll.chain is an object containing two arrays start and end that are containers for the callback functions). Also note that I am using jQuery and underscore here.
$('body').on('scroll', scrollCall);
scrollBind('end', callbackFunction);
scrollBind('start', callbackFunction);
var scrollCall = function(e) {
if (scroll.last === false || (Date.now() - scroll.last) <= 500) {
scroll.last = Date.now();
if (scroll.timeout !== false) {
window.clearTimeout(scroll.timeout);
} else {
_(scroll.chain.start).each(function(f){
f.call(window, {type: 'start'}, e.event);
});
}
scroll.timeout = window.setTimeout(self.scrollCall, 550, {callback: true, event: e});
return;
}
if (e.callback !== undefined) {
_(scroll.chain.end).each(function(f){
f.call(window, {type: 'end'}, e.event);
});
scroll.last = false;
scroll.timeout = false;
}
};
var scrollBind = function(type, func) {
type = type.toLowerCase();
if (_(scroll.chain).has(type)) {
if (_(scroll.chain[type]).indexOf(func) === -1) {
scroll.chain[type].push(func);
return true;
}
return false;
}
return false;
}
Is it possible to implement "long press" in JavaScript (or jQuery)? How?
(source: androinica.com)
HTML
Long press
JavaScript
$("a").mouseup(function(){
// Clear timeout
return false;
}).mousedown(function(){
// Set timeout
return false;
});
There is no 'jQuery' magic, just JavaScript timers.
var pressTimer;
$("a").mouseup(function(){
clearTimeout(pressTimer);
// Clear timeout
return false;
}).mousedown(function(){
// Set timeout
pressTimer = window.setTimeout(function() { ... Your Code ...},1000);
return false;
});
Based on Maycow Moura's answer, I wrote this. It also ensures that the user didn't do a right click, which would trigger a long press and works on mobile devices. DEMO
var node = document.getElementsByTagName("p")[0];
var longpress = false;
var presstimer = null;
var longtarget = null;
var cancel = function(e) {
if (presstimer !== null) {
clearTimeout(presstimer);
presstimer = null;
}
this.classList.remove("longpress");
};
var click = function(e) {
if (presstimer !== null) {
clearTimeout(presstimer);
presstimer = null;
}
this.classList.remove("longpress");
if (longpress) {
return false;
}
alert("press");
};
var start = function(e) {
console.log(e);
if (e.type === "click" && e.button !== 0) {
return;
}
longpress = false;
this.classList.add("longpress");
if (presstimer === null) {
presstimer = setTimeout(function() {
alert("long click");
longpress = true;
}, 1000);
}
return false;
};
node.addEventListener("mousedown", start);
node.addEventListener("touchstart", start);
node.addEventListener("click", click);
node.addEventListener("mouseout", cancel);
node.addEventListener("touchend", cancel);
node.addEventListener("touchleave", cancel);
node.addEventListener("touchcancel", cancel);
You should also include some indicator using CSS animations:
p {
background: red;
padding: 100px;
}
.longpress {
-webkit-animation: 1s longpress;
animation: 1s longpress;
}
#-webkit-keyframes longpress {
0%, 20% { background: red; }
100% { background: yellow; }
}
#keyframes longpress {
0%, 20% { background: red; }
100% { background: yellow; }
}
You can use taphold event of jQuery mobile API.
jQuery("a").on("taphold", function( event ) { ... } )
I created long-press-event (0.5k pure JS) to solve this, it adds a long-press event to the DOM.
Listen for a long-press on any element:
// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
console.log(e.target);
});
Listen for a long-press on a specific element:
// get the element
var el = document.getElementById('idOfElement');
// add a long-press event listener
el.addEventListener('long-press', function(e) {
// stop the event from bubbling up
e.preventDefault()
console.log(e.target);
});
Works in IE9+, Chrome, Firefox, Safari & hybrid mobile apps (Cordova & Ionic on iOS/Android)
Demo
While it does look simple enough to implement on your own with a timeout and a couple of mouse event handlers, it gets a bit more complicated when you consider cases like click-drag-release, supporting both press and long-press on the same element, and working with touch devices like the iPad. I ended up using the longclick jQuery plugin (Github), which takes care of that stuff for me. If you only need to support touchscreen devices like mobile phones, you might also try the jQuery Mobile taphold event.
For modern, mobile browsers:
document.addEventListener('contextmenu', callback);
https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu
jQuery plugin. Just put $(expression).longClick(function() { <your code here> });. Second parameter is hold duration; default timeout is 500 ms.
(function($) {
$.fn.longClick = function(callback, timeout) {
var timer;
timeout = timeout || 500;
$(this).mousedown(function() {
timer = setTimeout(function() { callback(); }, timeout);
return false;
});
$(document).mouseup(function() {
clearTimeout(timer);
return false;
});
};
})(jQuery);
$(document).ready(function () {
var longpress = false;
$("button").on('click', function () {
(longpress) ? alert("Long Press") : alert("Short Press");
});
var startTime, endTime;
$("button").on('mousedown', function () {
startTime = new Date().getTime();
});
$("button").on('mouseup', function () {
endTime = new Date().getTime();
longpress = (endTime - startTime < 500) ? false : true;
});
});
DEMO
For cross platform developers (Note All answers given so far will not work on iOS):
Mouseup/down seemed to work okay on android - but not all devices ie (samsung tab4). Did not work at all on iOS.
Further research its seems that this is due to the element having selection and the native magnification interupts the listener.
This event listener enables a thumbnail image to be opened in a bootstrap modal, if the user holds the image for 500ms.
It uses a responsive image class therefore showing a larger version of the image.
This piece of code has been fully tested upon (iPad/Tab4/TabA/Galaxy4):
var pressTimer;
$(".thumbnail").on('touchend', function (e) {
clearTimeout(pressTimer);
}).on('touchstart', function (e) {
var target = $(e.currentTarget);
var imagePath = target.find('img').attr('src');
var title = target.find('.myCaption:visible').first().text();
$('#dds-modal-title').text(title);
$('#dds-modal-img').attr('src', imagePath);
// Set timeout
pressTimer = window.setTimeout(function () {
$('#dds-modal').modal('show');
}, 500)
});
The Diodeus's answer is awesome, but it prevent you to add a onClick function, it'll never run hold function if you put an onclick. And the Razzak's answer is almost perfect, but it run hold function only on mouseup, and generally, the function runs even if user keep holding.
So, I joined both, and made this:
$(element).on('click', function () {
if(longpress) { // if detect hold, stop onclick function
return false;
};
});
$(element).on('mousedown', function () {
longpress = false; //longpress is false initially
pressTimer = window.setTimeout(function(){
// your code here
longpress = true; //if run hold function, longpress is true
},1000)
});
$(element).on('mouseup', function () {
clearTimeout(pressTimer); //clear time on mouseup
});
You could set the timeout for that element on mouse down and clear it on mouse up:
$("a").mousedown(function() {
// set timeout for this element
var timeout = window.setTimeout(function() { /* … */ }, 1234);
$(this).mouseup(function() {
// clear timeout for this element
window.clearTimeout(timeout);
// reset mouse up event handler
$(this).unbind("mouseup");
return false;
});
return false;
});
With this each element gets its own timeout.
This worked for me:
const a = document.querySelector('a');
a.oncontextmenu = function() {
console.log('south north');
};
https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/oncontextmenu
You can use jquery-mobile's taphold. Include the jquery-mobile.js and the following code will work fine
$(document).on("pagecreate","#pagename",function(){
$("p").on("taphold",function(){
$(this).hide(); //your code
});
});
Most elegant and clean is a jQuery plugin:
https://github.com/untill/jquery.longclick/,
also available as packacke:
https://www.npmjs.com/package/jquery.longclick.
In short, you use it like so:
$( 'button').mayTriggerLongClicks().on( 'longClick', function() { your code here } );
The advantage of this plugin is that, in contrast to some of the other answers here, click events are still possible. Note also that a long click occurs, just like a long tap on a device, before mouseup. So, that's a feature.
I needed something for longpress keyboard events, so I wrote this.
var longpressKeys = [13];
var longpressTimeout = 1500;
var longpressActive = false;
var longpressFunc = null;
document.addEventListener('keydown', function(e) {
if (longpressFunc == null && longpressKeys.indexOf(e.keyCode) > -1) {
longpressFunc = setTimeout(function() {
console.log('longpress triggered');
longpressActive = true;
}, longpressTimeout);
// any key not defined as a longpress
} else if (longpressKeys.indexOf(e.keyCode) == -1) {
console.log('shortpress triggered');
}
});
document.addEventListener('keyup', function(e) {
clearTimeout(longpressFunc);
longpressFunc = null;
// longpress key triggered as a shortpress
if (!longpressActive && longpressKeys.indexOf(e.keyCode) > -1) {
console.log('shortpress triggered');
}
longpressActive = false;
});
In vanila JS if need to detect long-click after click released:
document.addEventListener("mousedown", longClickHandler, true);
document.addEventListener("mouseup", longClickHandler, true);
let startClick = 0;
function longClickHandler(e){
if(e.type == "mousedown"){
startClick = e.timeStamp;
}
else if(e.type == "mouseup" && startClick > 0){
if(e.timeStamp - startClick > 500){ // 0.5 secound
console.log("Long click !!!");
}
}
}
May need to use timer if need to check long-click while clicking. But for most case after release click is enought.
For me it's work with that code (with jQuery):
var int = null,
fired = false;
var longclickFilm = function($t) {
$body.css('background', 'red');
},
clickFilm = function($t) {
$t = $t.clone(false, false);
var $to = $('footer > div:first');
$to.find('.empty').remove();
$t.appendTo($to);
},
touchStartFilm = function(event) {
event.preventDefault();
fired = false;
int = setTimeout(function($t) {
longclickFilm($t);
fired = true;
}, 2000, $(this)); // 2 sec for long click ?
return false;
},
touchEndFilm = function(event) {
event.preventDefault();
clearTimeout(int);
if (fired) return false;
else clickFilm($(this));
return false;
};
$('ul#thelist .thumbBox')
.live('mousedown touchstart', touchStartFilm)
.live('mouseup touchend touchcancel', touchEndFilm);
You can check the time to identify Click or Long Press [jQuery]
function AddButtonEventListener() {
try {
var mousedowntime;
var presstime;
$("button[id$='" + buttonID + "']").mousedown(function() {
var d = new Date();
mousedowntime = d.getTime();
});
$("button[id$='" + buttonID + "']").mouseup(function() {
var d = new Date();
presstime = d.getTime() - mousedowntime;
if (presstime > 999/*You can decide the time*/) {
//Do_Action_Long_Press_Event();
}
else {
//Do_Action_Click_Event();
}
});
}
catch (err) {
alert(err.message);
}
}
You can use jquery Touch events. (see here)
let holdBtn = $('#holdBtn')
let holdDuration = 1000
let holdTimer
holdBtn.on('touchend', function () {
// finish hold
});
holdBtn.on('touchstart', function () {
// start hold
holdTimer = setTimeout(function() {
//action after certain time of hold
}, holdDuration );
});
like this?
target.addEeventListener("touchstart", function(){
// your code ...
}, false);