Trigger ('mouseleave') - not working as desired on mobile - javascript

I have a burger menu button in the header which opens and closes the menu. And I have hover and focus animations for it.
So when the menu is clicked or tapped or touched (on mobile devices) - the second time it loses the hover and focus styles. Everything in the code below is working perfectly, but the trigger mouseleave isn't working. I tested my code and found out that on mobile devices when a person clicks on a button, hover animation applies there too. So trigger mouseleave should cancel the hover effects I have on my burger menu button, but it isn't working.
I have tried everything: I have put this in setTimeout function and tried other different events, too (like testing it out in different browsers). Yet nothing seems to remove that hover animation on mobile devices when a user touches or clicks this burger menu button. Please help, as I have been stuck on this for two days.
//losing focus for menu toggler on smaller devices
var loseFocusMenu = 0;
$(".c-header-nav__toggle").on("click touch", function(){
if (loseFocusMenu === 0){
loseFocusMenu++;
}else if(loseFocusMenu === 1){
$(".c-header-nav__toggle").trigger('mouseleave');
$(".c-header-nav__toggle").trigger('blur');
loseFocusMenu--;
}
});
I am developing a Wordpress theme, so I am using that platform (and obviously that's jquery in the code). Please help
Also that hover and focus animations are coming from internal styling in the style tag and coming from another class that's assigned to the same burger menu button

i solved the issue with adding and removing classes. if your hands are tied and u can't do it any other way like in my case than this is the work around

Related

How to initiate touchscreen on page load

I have a menu that uses hover to display submenus on a desktop. It seems with touchscreen devices the menu focus doesn't get initiated until after another element is touched (focused) first. When I touch the menu item to display the submenu, the menu item shows selected but the submenu doesn't display. If I take the focus off by touching another page element, such as an image or form field, and then touch the menu item a second time, the submenu works as expected. It will also work if I focus on a form element first and then the submenu. I have :hover, :focus, and :active all in my CSS but it seems to ignore the first focus/active. Is there a JQuery method to force the touchscreen device to initiate focus as soon as the page loads? Is there another solution to this problem?
From my experience, depending on css status is not enough to do what you are looking for here. It will either only work on desktops or only on mobile. Instead I would use the javascript ontouchstart event (https://developer.mozilla.org/en-US/docs/Web/API/Touch_events) for this.
Assuming your css looks something like this:
.your-hoverable-class:hover .submenu{
display: block;
}
You can move that :hover state onto a class of its own (.is-hovered), like:
.your-hoverable-class.is-hovered .submenu{
display: block;
}
Then you can perform the state toggling like this with Javascript (ES6)
const hoverableElem = document.querySelector('.your-hoverable-class');
hoverableElem.addEventListener('touchstart',(event)=>{
event.target.classList.toggle('is-hovered')
});
Now the user can "tap" on that element if they are using a mobile device. the :hover css works quite well with mouse, so you may want to keep the :hover toggling as it is too. Otherwise, you can just use the onmouseover and onmouseout events like above if you want to stick to a pure javascript solution.

Switching from an open Bootstrap 3 dropdown menu to a different dropdown menu requires an extra tap on mobile

When a bootstrap dropdown is open, opening another dropdown requires two taps. This is because of an overlaying div that swallows all other input in order to close the first dropdown.
This is a known bug. According to the bootstrap documentation:
On mobile devices, opening a dropdown adds a .dropdown-backdrop as a
tap area for closing dropdown menus when tapping outside the menu, a
requirement for proper iOS support. This means that switching from an
open dropdown menu to a different dropdown menu requires an extra tap
on mobile.
However, the behaviour is not consistent. The backdrop overlay is not applied to dropdowns within a .navbar-nav, and as far as I can tell, everything appears to work just fine for me on my iPhone (Safari).
Check out this jsfiddle to see the different behaviours.
Does anyone know more about the iOS-specific issue that this is supposed to be for, and does anyone have a browser-compatible workaround for this?
I've posted some potential solutions in this jsfiddle.
1) Hiding the backdrop
.dropdown-backdrop {
display: none;
}
2) Applying .navbar-nav to the dropdowns (and removing the negative margins).
Working on Windows (Chrome) and iPhone (Safari). Not tested any more than that. Does anyone know any issues with these approaches? It seems too easy...
Apparently this is due to "click" events not bubbling up to the body properly in iOS Safari, which would make Bootstrap unable to listen for dismiss clicks with one global handler. It appears that a different workaround has been added for Bootstrap 4 so that a backdrop is no longer required:
https://github.com/twbs/bootstrap/pull/22426

JQuery Mobile: Disable page transitions only on back/forward buttons

I am new to JQuery Mobile (1.4.5) and have just finished my first project with it.
The only problem is with page transitions on iOS7+ (in my case the slide transition). While they work fine within the site and back/forward buttons, if someone swipes the left or right edge of the iOS device to navigate browser history, there's a double transition, since the native iOS slide and JQM's slide happen in succession. This appears to be an issue with any page transition (except "none" of course). It even happens on JQuery Mobile's demo pages. I've seen others report this issue with no reliable solution.
Since there is currently no way in iOS Safari to detect history swipe events, I figured the next best thing is to turn off transitions (set to 'none') but only if back/forward events are triggered (which I assume also applies to the swipe left/right for iOS7+). I know I'll lose the transition on the back/forward buttons, but they would still work within the site so that's a compromise I'm willing to make. However I'm not sure where to go in JQM's code to achieve this.
TL;DR: Is there a way to set JQuery Mobile page transitions to 'none' only when the browser's back (and/or forward) button is pressed?
According to this article, yes you can. When browser's buttons are used, options.direction returns either back or forward. And then change options.transition to none.
$(document).on("pagecontainerbeforechange", function (e, data) {
if (data.options.direction == "back" || data.options.direction == "forward") {
data.options.transition = "none";
}
});

Prevent scrolling but allow swipe event in JQuery

I'm working on a mobile version of a webpage, and one of the features we have is a slide out sidebar. On my Android device, when the sdiebar is visible it is still possible to scroll the background using the part of the body that's still visible. To solve this, I disable scrolling on the page using:
$(document).bind('touchmove', function (e) { e.preventDefault(); });
When the sidebar is opened, and then unbind it when the sidebar is closed.
Recently I wanted to try and add in the ability to swipe and close the sidebar. Using jQuery Mobile functionality, I subscribed tot he swipeleft event like so:
$(document).on("swipeleft", swipeLeftHandler);
function swipeLeftHandler(event) {
if (isSidebarOpen()) {
toggleSidebar();
}
}
I'm intentionally subscribing to the entire page since it doesn't matter where they swipe. This doesn't work when I'm preventing touchmove, but does when I remove that code. Obviously the downside to that is that a user can still scroll the main page behind the sidebar.
To implement the sidebar, I'm using the JQuery slide event and have it inside a div that's floating to the left and has a fixed position.
Is there any way I could disable scrolling but still allow for the swipeleft event to work?

Is there a way to "reset" mobile Webkit's pseudo-hover behaviour after the initial hover-triggering click?

I'm working on a website where I'm using Javascript (via JQuery) to add pop-up boxes containing extra information for items in a list. I'm using JQuery's mouseeneter and mouseleave events to make the popups appear and disappear which of course all works fine in desktop browsers.
In Mobile Safari the popup appears when I click an item (which is what I expect and what I want to happen) and I have added an ontouchstart which triggers the mouseleave JQuery event thus hiding any visible pop-up when the user does anything else. This works fine too except that when a user taps an item the pop-up of which they've just looked at and cancelled (either by scrolling or by doing anything else that triggers the ontouchstart event), rather than it showing the pop-up again it activates the link attached to that item.
If a user were to tap another item instead of tapping the same item again then that new item's pop-up would show and then if they were to tap the first item again then that item's pop-up would show. Again, this is both expected and what I want to happen.
It would seem that once an item with a hover event has been tapped and Mobile Safari as been forced to make that event happen, that item is then flagged as having had its hover event triggered and so the next tap doesn't have to pretend to be a hover, it can be a normal click. Tapping another item with a hover event seems to "reset" the flag set for the previous item.
I'd like to be able to 'reset' this flag for myself so that, rather than how things work currently where clicking an item shows the pop-up and the next click on that item, even if the pop-up has been closed, will activate the link, instead when I close the pop-up with my ontouchstart, and so to my mind the item is no longer being "hovered over", a second click on that same item should show the pop-up again and then only by clicking on the item whilst the pop-up is visible should the link activate.
The secret would seem to be in getting Mobile Safari to exit its "pseudo-hover" mode when I use ontouchstart to trigger mouseleave but I have been unable to find anything useful anywhere on exactly what's going on when Mobile Safari pretends to hover over anything and whether any of this is accessible via Javascript events.
I know I could write a version of my pop-up code to work specifically for Mobile Safari but it seems much more efficient to me to get the browser to do most of the hard work of mimicking hover events. If only I could get this final little niggle sorted out.
I'm guessing the hover state is tied into which element has focus rather than as a flag. One tap gives focus, second tap activates the link.
Try closing the pop-up by giving another element focus, and see if that works out any better.
$('body').focus();
tl;dr but try this:
# :hover fix
# e.g.: body:not(.stoppedhovering) .styled:hover
hoverFix = ->
window.clearTimeout hoverFix.delay if hoverFix.delay?
$('body').removeClass 'stoppedhovering'
delayed = -> $('body').addClass 'stoppedhovering'
hoverFix.delay = _.delay delayed, 600
$('*').live 'touchstart', hoverFix

Categories