Hover effect stays after touch in jQueryMobile - javascript

I'm developiong application in phonegap with jQueryMobile for mobile devices only. In which I've search icon. I want to give hover effect on that icon when user touchs it.
I've achived this by css:
<a href="search.html" class="custom_header" >
.custom_header:hover {
background:url('../images/effect_glow.png') no-repeat center;
Now the problem is this hover effect stays after touch. I want behaviour like mousein and mouseout. In this case effect stays even that part is not touching.
How to remove hover effect after finger get off on it?

You maybe know this but :hover doesn’t exist on touch screen devices. So when you design a responsive website, you should carefully plan when and where to use :hover interactions.
While it is implemented on mobile devices it is extremely buggy, mostly on iOS devices. On the other end you cant use :focus because it can be used only on a elements that support focus so a tags and buttons are ruled out. Also :active is no go on mobile devices.
In this case we can use jQuery to remedy this problem.
Working example: http://jsfiddle.net/Gajotres/84Nug/
In this example I have used vmousedown, vmouseup and vmousecancel events so I can test it on desktop / mobile devices alike. Just replace them with touchstart, touchend and touchcancel.
touchcancel / vmousecancel is needed because sometimes button can stay in pressed state.
Code:
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('touchstart','.custom_header' ,function(){
$(".custom_header").css("background","url('http://www.cesarsway.com/sites/default/files/cesarsway-images/features/2012/March/Puppies-and-Exercise.jpg') no-repeat center");
}).on('touchend', function(){
$(".custom_header").css("background","red");
}).on("touchcancel", function() {
$(".custom_header").css("background","red");
});
});

Related

how to launch a webpage on mobile web application without scroll

EDIT FOR CLARIFICATION:
What I want:
A full screen javascript canvas which can handle touch events without those events being further interpreted by the browser, but also reserve the ability to open a new window on user action.
Examples:
I should be able to swipe my finger around without the webpage trying to scroll
I should be able to swipe my finger around without the contents of the webpage being nudged in any way (normally, when one scrolls to the end of a scroll region, the browser allows some additional spring-loaded buffer scrolling to signal to the user that it is the end of the scroll region).
I should be able to pinch and pan without the webpage zooming
etc...
The point:
I need to interpret these events accurately and in realtime MYSELF to respond to these actions WITHIN THE CANVAS. (I am doing realtime drawing via requestAnimationFrame, allowing me to react to user events without using the DOM)
The state of things currently:
This all works perfectly (except for the ability to open a new window) because I position the canvas to be the full size of the viewport (handling any window resize events), and the canvas listens to ontouchstart, ontouchmove, ontouchend, etc... events, calling evt.preventDefault() after I have handled the user input myself. This works to ensure the canvas is ALWAYS full screen, doesn't budge, and user input is accurately given to me to handle in-game.
The Problem:
One bit of user input I need to handle is the launching of a webpage when they click the region of my canvas with a "launch my webpage" button. However, window.open(mywebpage) doesn't work, because mobile safari only allows such an action in the callstack of a click event. Because I rely on ontouchstart to get responsive controls, and evt.preventDefault() in an ontouchstart event CANCELS the click event from happening, I cannot launch the webpage (it gets blocked by the browser).
My attempted solutions, and why they are insufficient:
Just use a click event rather than ontouchstart: this means I can't prevent scrolling/etc... additionally, it is not as responsive, and doesn't allow me to handle touch-and-drag events well.
Overlay a div (or an a) tag atop the canvas over the launch webpage zone, and add a click event to that: if the user clicks-and-drags starting within this tag, then it allows the page to scroll and zoom. Trying to fix this results in the same problem as before.
ORIGINAL POST:
I have a mobile application that is a full-screen canvas, which locks itself positionally (can't scroll or zoom) so that I can correctly interpret user input uninterrupted (swipes, pans, etc...).
It locks itself in by intercepting touchstart events and calling evt.preventDefault (as well as the meta viewport no-zoom stuff which as far as I can tell doesn't actually do anything?).
This works great, and is absolutely necessary to make a game (or game-like application) function.
The problem is that I also have a "go to this webpage" button. I can intercept the touchstart, and use window.open(somewebpage), but mobile popup blockers will block it. The "rules" seem to be "the webpage will be allowed to be opened iff it is done in the call stack of a user interaction, AND that interaction is a 'click' event".
I have the first part down, but if I change the event to a click event, the web page now interprets swipes as scrolls (and pinches as zooms, etc...). If I have both a click and a touchstart event, then calling evt.preventDefault() on the touchstart (which stops the scroll/zoom) also stops the click event.
If I overlay a div atop the click zone of the "launch webpage" button, then the player can scroll/zoom when their input begins in that button, which results in an unpredictable and wonky experience.
How can I launch another webpage without allowing the current webpage to scroll?
Edit: at request, here is a code snippet at least partially illustrating what I'm trying to do https://jsfiddle.net/phildo/0q8e47fk/10/.
Note that in the "real" case, the canvas takes up the full width/height of the screen, and is explicitly set accordingly on screen resize.
Preventing bounces of any kind on mobile web page is a vast problem through out the mobile devices not depending about the manufacturer. I had similar issue on Windows Phone 8 app years ago and there (quite surprisingly) was a solution dedicated to Windows environment which of course cannot applied here.
For iOS you need an iOS solution, right?
The very solution is named iNoBounce. The idea is to add the little js library to your html page, code with some good conventions and the js lib will do the dirty job of preventing the default when necessary.
The trick it actually does is not to prevent just anything, but the ones only, that are "extra" and will cause the bounce events.
With the words of iNoBounce GitHub Readme:
iNoBounce detects if the browser supports -webkit-overflow-scrolling by checking for the property on a fresh CSSStyleDeclaration. If it does, iNoBounce will listen to touchmove and selectively preventDefault() on move events that don't occur on a child of an element with -webkit-overflow-scrolling: touch set. In addition, iNoBounce will preventDefault() when the user is attemping to scroll past the bounds of a scrollable element, preventing rubberbanding on the element itself (an unavoidable caveat).
The example code asks you to use the following parts (there is a separate example code for canvas, this is only the most common solution):
// All you need is an element with `height` or `max-height`, `overflow: auto` and `-webkit-overflow-scrolling: touch`.
<script src="inobounce.js"></script>
<style>
ul {
height: 115px;
border: 1px solid gray;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
</style>
Source:
[1] https://github.com/lazd/iNoBounce
Edit:
I found out you did not limit yourself to iOS. For other browsers, try
[2] https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior
which introduces overscroll-behavior setting, that you can set to none to disable bounces.
It will work only on Android, not ie or iOS.
For mobile Windows Phone I had the solution like this:
div.wp8ScrollFix {
-ms-touch-action: none;
}
which effectively does the same as iNoBounce, now with single CSS line for the div containing the canvas.
Edit2:
For a search of semi universal solution, I could find that
-touch-action: none;
applied to div element that includes the canvas, you can disable default touch events and for the canvas, define your own.
The solution works on any other than Safari browsers. As in [3] there may be some variants like
-ms-touch-action: none;
but I suppose they are now all same without prefixes. The [3] solution is very old and world has changed a lot from those days.
The sad thing is, the browser support is same at least 2019 [4] and maybe now also.
Sources:
[3] jQuery / HTML5 / gwt app for WP8 (Lumia 920) device: vertical css scroll fix
[4] https://css-tricks.com/almanac/properties/t/touch-action/
Problem
Show a div on top of full screen canvas element that intercepts normal click events on element canvas.
Solution
Aside from click events, you need to intrrcept the following touch events:
touchstart
touchend
touchmove
touchcancel
Additional Info
You only preventDefault on the canvas events so you should still be able to create a clickable/touchable element in the canvas that shows a div outside the canvas positioned with a z-index higher than the canvas element by setting on display: block on the div. The div should also have 100vh and 100vw set foe width and height respectively and be position: fixed. The div should also have a button to hide again display: none.
References
https://stackoverflow.com/a/51127296/806876

Mac Chrome hover events behave differently when window is maximised

A web page I am developing has mouse over events (both css and javascript) for a top navigation bar. It works fine when the browser window is floating, but when maximized (full screen) the hover classes have no effect anymore. It begins to act like a tablet display, I must point and click for my hover actions to take effect. I achieve the events when I click, but mouse hover changes my cursor to a text select cursor.
This does not happen on a windows computer
As a matter of fact, this behaviour is good if it is meant to support tablets but I'd appreciate if anybody could let me know if this is a bug or intended?
This is a 3+ year old unfixed bug in Chromium.
http://crbug.com/170058

Can't get this CSS transition to properly function on an iPhone

I'm currently working on a CSS transition and I'm struggling to find the proper Javascript to make it function properly on a mobile device.
http://seancrater.com/test/
In the section, "The Dirty Dozen Plus", the transition can be seen. I currently have
ontouchstart="this.classList.toggle('hover');
added to each of the DIVs but it currently requires you to hold down your finger on it from a mobile device to keep it on the transition state. I was wondering if anybody could give me some insight on how to make it a single click to make it stay in the transition state. I tried the pseudo :focus and it stopped it from functioning all together.
Thanks! -Sean
As others have stated, you'll need to avoid :hover.
The easiest way to address your issue is to update your CSS like so:
.top:hover,
.top.touched {
-webkit-transform:translateY(-150px);
-webkit-transition: all .5s;
}
And then add touched as a class to your elements on touchstart or touchend. My guess is you'll want to maintain which element currently is touched, so you can remove the transitioned state when a user scrolls or touches another element.
(EDIT: Updated fiddle to allow user to tap close the element)
http://jsfiddle.net/4n6Z4/1/
Shell, for easier testing on a smartphone:
http://fiddle.jshell.net/4n6Z4/1/show/
ontouchstart="this.classList.toggle('click'); There are no hover events in mobile. You need to turn your hover event into a click event for mobile phones. Use javascript to detect if it's a phone or not. Setup a constant var phone = false and if it's a phone and set it to true and if not it remains false. Then use it in your function that controls / or triggers that animation.
You cannot use :hover on mobile.
more info
As you know, :hover behavior doesn’t exist on touch screen devices. So
when you design a responsive website, you should carefully plan when
and where to use :hover interactions. Simple links that open some URL
will loose their :hover effect on some touch screen devices. On iOS
:hover is triggered before the click event, so you will see the hover
style for a brief moment before the page changes. Those are minor
things, they don’t affect the functionality of the site. The real
problem is a :hover that either hides or shows another element using
display or visibility CSS properties. This type of :hover will
transform into the double tap behavior on touch screens.
http://www.prowebdesign.ro/how-to-deal-with-hover-on-touch-screen-devices/

Javascript show menu on hover for iPad only

The menu on this site doesn't show when using an iPad. It's designed so that the menu is hovered on and the ul li list below should show, but it doesn't. When you click the menu, nothing appears.
I need to write some JS using onclick events instead to make the sub menu show. But this needs to be specific for iPad ONLY.
Is it possible to write JS specific to only certain devices?
I just need to get this menu working, it seems iPads will not show hover items even when you click... which renders the entire use of :hover defunct on iPads.
You will need to use browser sniffing to detect the mobile touch devices. Don't do it yourself, use one of the excellent scripts from http://detectmobilebrowsers.com/
You will needs to do this for iphones, androids, phones etc. anything with a touch screen.

Touch device HTML element :hover state

There is a HTML button, with 3 backgrounds - each for normal, hover and clicked states. Of course, it works fine with non touch device. If the button is clicked on touch device, the :hover state is also triggered and stays until another element is touched.
Is it possible to programmatically remove :hover state from element after it was clicked or prevent it from activating on touch devices?
Sorry, but suggestions to a detect mouseover and mouseout events and add artificial classes are not accepted.
One possible solution is to add "no-touch" class to html element in advance and remove it if only touch device is detected. In that case, CSS selector "html.no-touch button:hover" will not match for touch device.
Do you know more elegant solutions you may suggest?
I would try to overwrite the :hover state in an additional style-sheet for handheld devices like:
<link rel="stylesheet" type="text/css" href="handheld.css" media="handheld">
and in handheld.css put something like:
#some_selector:hover {
background: none; /* if you are setting a background in the main css file for example */
}
However, I´m not sure if handheld and touch screen are completely the same, there might be devices that have a touch screen and are not qualified as a handheld.
Edit: It seems you cannot detect touch screen devices 100% reliably, also see this question.
Seems that this issue can be resolved by overwriting the :hover state for a given element in media query - see this question:
CSS hover not being ignored on touch screen devices

Categories

Resources