Sorry if this is a repeated question but i couldn't find any aswers.
Basically, I'm developing a web app that has a button in it.
I want that button to highlight in two different scenarios:
-If the user is on a non-touch (desktop) device, the button will highlight if the mouse is on top of it and get back to normal when it's not.
-If the user is on a touch device WITHOUT a mouse, the button will highlight if it's touched and get back to normal when the touching stops.
The desktop part is working fine, but the touch part have a problem: to get the button back to normal, I have to click somewhere else after clicking it, just stop touching the screen doesn't work.
What I'm doing wrong? Thanks!
JS Code:
if (!this.isTouch) {
document.getElementById("search_button").addEventListener("mouseover", function () {
highlightButton();
});
document.getElementById("search_button").addEventListener("mouseout", function() {
restoreButton();
});
}
else if (window.matchMedia("(any-pointer: none)").matches) {
document.getElementById("search_button").addEventListener("touchstart", function () {
highlightButton();
});
document.getElementById("search_button").addEventListener("touchend", function () {
restoreButton();
});
}
There are several touch events listed as well that may be of use for you, this extends touch devices such as tablets and phones:
el.addEventListener("touchstart", handleStart, false);
el.addEventListener("touchend", handleEnd, false);
el.addEventListener("touchcancel", handleCancel, false);
el.addEventListener("touchmove", handleMove, false);
read more at MDN docs
Try to combine also touchcancel event :
addEventListener( "touchcancel", function ( event ) {
console.log( "BREAK" );
restoreButton();
}, false );
Related
I'm making a simple player motion in Javascript canvas. (Up down left right)
I created 4 buttons on screen for mobile players. I used the following code for the buttons as I wanted to move the player until the button is released.
upBtn.addEventListeter('mousedown',()=>{
let interval=setInterval(()=>{
player.y--;
}, 50);
upBtn.addEventListener('mouseup',()=>{
clearInterval(interval);
});
});
The above code works perfectly when the buttons are clicked in a computer. But in mobile it is not working.
I also tried to use touchdown and touchup but it didn't work.
What changes should I make in the code to make it work in mobile also?
Thanks in advance
You're looking for touchstart and touchend
function upFunc(event) {
//prevents some devices to emulate the click event
event.preventDefault();
let interval=setInterval(()=>{
player.y--;
}, 50);
upBtn.addEventListener('mouseup',downFunc);
upBtn.addEventListener('touchend',downFunc);
}
function downFunc(e) {
e.preventDefault();
clearInterval(interval);
}
upBtn.addEventListeter('mousedown', upFunc);
upBtn.addEventListeter('touchstart', upFunc);
Note that to support both mouse and touch in vanilla js you'll have to add both event listeners.
Also, some devices emulate the mouse events, so you can use preventDefault() to make sure your functions fires only once.
I had a similar issue and eventually solved it. I don't remember all the details of how I got to the end result but here is the code I eventually used to get it to work.
It is for controlling a camera robot. Pressing and holding the forward arrow makes the robot move forward while the button is held down and stops as soon as the button is released.
It works both on PC browser and on smartphone browsers. I've only tried it on a couple of browsers on Samsung though.
It uses the onmousup and onmousedown for the PC while for the smartphone it is a bit more complicated using the touch events.
Also important is the oncontextmenu="absorbEvent_()" which prevents the context menu from appearing when you hold down a button.
<button id="moveForward"
onmousedown="moveForward_onmousedown()"
onmouseup="anyMovementButton_onmouseup()"
onmouseout="anyMovementButton_onmouseout()"
ontouchstart="moveForward_onmousedown()"
ontouchend="anyMovementButton_onmouseup()"
ontouchmove="anyMovementButton_onmouseout()"
ontouchcancel="anyMovementButton_onmouseout()"
oncontextmenu="absorbEvent_()">
<svg width="34" height="34">
<polygon points="2,32 17,2 32,32" style="fill:lime;stroke:purple;stroke-width:3;fill-rule:evenodd;"></polygon>
</svg>
</button>
function moveLeft_onmousedown() {startMovement('left' ); }
function moveReverse_onmousedown() {startMovement('reverse'); }
function moveForward_onmousedown() {startMovement('forward'); }
function moveRight_onmousedown() {startMovement('right' ); }
function tiltUp_onmousedown() { singleMove('up' ); }
function tiltDown_onmousedown() { singleMove('down' ); }
function anyMovementButton_onmouseup() {stopMovement();}
function anyMovementButton_onmouseout() {stopMovement();}
// this function is for preventing context menu on mobile browser
function absorbEvent_(event)
{
var e = event || window.event;
e.preventDefault && e.preventDefault();
e.stopPropagation && e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
return false;
}
I develop a web GUI for a special tablet. This tablet is running with Linux and the used browser is Chromium. The application is a web application with PHP, HTML5, JQuery and JavaScript. Now I run into a problem. The screen is a touchscreen and the user is able to navigate through the application by touch the screen. However now we decided to add a feature for saving electricity. This feature will shutdown the background light after three minutes. To turn on the backlight again, the user should touch the screen again. This leads to this problem, because on any touch the buttons are also pressed even if the background light is shutdown. I want to prevent this by discarding all clicks on the touchscreen if a cookie is set. If this cookie is not set the touchscreen and the application should work as desired. How can I solve this problem?
I installed an event listener to register all clicks and to reset the time.
window.addEventListener('mousedown', function(e){
$.get('php/timeupdate.php', function(){});
}, false);
Code used to stop the execution:
$(document).on('click', function(event) {
$.get('php/getwakeup.php', function(e){
if(e==='true'){
//event.preventDefault(); // I tried all three possibilities
//event.stopImmediatePropagation();
event.stopPropagation();
}
});
});
You can try this:
$(document).on('click', function(event) {
// get your cookie
if( cookie is set ) {
event.stopPropagation();
}
});
event.stopPropagation(); stops every event handling from where you called it =)
EDIT:
You have to set your $.get call synchronous or do it completely diffrent. Take a look at the jQuery.Ajax documenation. There is a parameter called "async".
But be careful unless the call is ready nothing else will be executed on you page! So if your script doesn't answer nothing else will work on your site.
The better solution would be setting ja recurring call that will get the information you need. Set it to every two seconds (setInterval is your friend here). If your response is true than set a global variable that you can check in your onDocumentClick event.
window.isBacklightOff = false;
setInterval(function() {
$.get('php/timeupdate.php', function(e) { window.isBacklightOff = !!e; })
}, 2000);
$(document).on('click', function(event) {
// get your cookie
if( window.isBacklightOff === true ) {
event.stopPropagation();
}
});
When the back light goes off you can set some flag handleEvents=false;
So when the flag is on don't handle any events.
Now when the back light is on you can set handleEvents = true.
$(document).on('click', function(event) {
// get your flag say handleEvents
if( !handleEvents ) {
event.stopImmediatePropagation();
return;
} else {
//do your biz logic send ajax..etc
}
});
Reason why your code above is not working:
$(document).on('click', function(event) {
$.get('php/getwakeup.php', function(e){
if(e==='true'){
//event.preventDefault(); // I tried all three possibilities
//event.stopImmediatePropagation();
event.stopPropagation();
}
});
});
The function inside $.get is async and called on success in that you are setting the event to stop propagating...well by that time when the success function is called the event is already complete and has called all the listeners.
So in short you must not do the event stop propagation inside the success function.
Since on mobile device browser such as safari , when user drag the screen, the whole website will move along with the finger. So the common solution is :
addEventListener('touchmove', function(e) { e.preventDefault(); }, true);
This will prevent any touchmove event . However, since the browser on mobile device has no scroll bar , when user want to scroll the dialog box of jquery ui , the touchmove event need to be permit. This statement will block that event.
addEventListener('touchmove', function(e) {
if (e.target.id != 'dialog' )
e.preventDefault();
return false;
}, true);
Then I add this statement to allow the dialog box to scroll. However, this solution has flaw because the background will be draggable and move along with user finger again. How to fix this problem? Thanks.
Been dealing with this all day and found this solution. When you want it to scroll the dialog on safari mobile on ipad/iphone/ipod, you need to use this:
if (/iPhone|iPod|iPad/.test(navigator.userAgent)) {
$('iframe').wrap(function () {
var $this = $(this);
return $('<div />').css({
width: $this.attr('width'),
height: $this.attr('height'),
overflow: 'auto',
'-webkit-overflow-scrolling': 'touch'
});
});
}
Adding a backbutton event listener to my Phonegap 2.0 mobile app prevents the user from exiting using the back key.
Before adding the event listener this was working: if the user visited N pages and clicked back N+1 times, the app would close (or go in the background for android 4.0 or higher).
Please see my code bellow.
document.addEventListener("backbutton", function(){
if (window.history.length == 0) { // this does not work
function quitApp(){
navigator.app.exitApp();
}
navigator.notification.confirm(
"Are you sure you want to quit?",
quitApp,
'App Title',
'Cancel,Ok');
return;
}
if (typeof(window.activePage.onBack) === 'function') {
window.activePage.onBack();
} else {
window.history.back();
}
}, false);
Any idea how i can achieve this: allow the user to exit using the back button while keeping my event listener?
Thanks!
Try to bind the back button on your title page, maybe something like this:
$('#home-page-title').bind( 'pageinit',function(event){
document.addEventListener("backbutton", function(){
navigator.app.exitApp();
}, false);
});
I'm building a HTML/JavaScript interface in which I would need some reactivity and so, the possibility for users to click really fast on the same button on the page.
I disabled the doubleclick/zoom on the iPad thanks to the <meta name="viewport" content="user-scalable=no" />, but then, if I double click or click too fast on the buttons, it does nothing.
I'm using jQuery and tried the dblclick event, didn't work.
You can try using the doubletap plugin which enable the use of "doubletap" events on iPhone and iPad devices.
I gave up on this, rolled my own inside my 'touchstart - move - touchend' sequence. Its horrible, but, inside my touchend, I have :
if (swipeMoving==0) {
swipeStarted = 0;
tapco +=1;
if (tapco==2) doDblClick();
window.setTimeout(function(){ tapco=0; }, 700);
return;
}
If you want click, too, put it in a delay, and cancel if the second click comes.
Use this script to use double click in Ipad.
http://code.google.com/p/jquery-ui-for-ipad-and-iphone/
Alternative :-
As click on the desktop browser is equivalent to the touch on the Ipad. So, the double click will be equivalent to the click on the Ipad.
To implement this :
if((navigator.userAgent.match(/iPad/i))){
$(".element").click(function () {/*run the code*/ });
}
else {
$(".element").dblclick(function () {/*run the code*/ });
}
Hope it helps.