Programatically remove "hover state" from element on mobile - javascript

I've got an element on a webpage, with a defined set of :hover styles. On mobile, this causes the "sticky hover" effect, where a touch on the element will cause the hover to apply, which is then removed when the user touches somewhere else on the page.
This is desirable for me - I'm not looking to prevent this, but I need a way to prgramatically remove that hover state once a user has interacted with it (to return the element to it's original state).
Is that possible? I've tried a $('some-other-element').click() but nothing will remove that state aside from manually clicking elsewhere on the page.

Instead of using :hover, make it a class such as .hover.
Then add and remove it using jQuery such as
$(".your-button").on("mouseenter", function()
{
$(this).addClass("hover");
});
$(".your-button").on("mouseleave", function()
{
$(this).removeClass("hover");
});
// Explicitly remove it
$(".your-button").removeClass("hover");
Edit: also if you want to use the click method. You may need to make it click on something that is focusable.
Lastly you could also try using the :active requirement.

Related

jQuery toggle on click out

I have a series of spans (togglers) and a series of divs (toggled). I created a make_toggle function that receives the toggler and its corresponding toggled as arguments.
Everything seems to work kind of ok up to the point where I try to implement a "toggle on click out". What I've tried is to attach to the html click event a function that checks whether the target of the click is contained within the toggled element. On toggle "back", I would then detach the handler so I am only checking when I need.
var check_if_clickingout = function(e) {
if (!toggled[0].contains(e.target)) {
toggle();
}
};
See fiddle: https://jsfiddle.net/andinse/65o211nc/11/
It doesn't even seem to work anymore but when it used to, it was triggering many more times than necessary (which was the reason for me to come here ask for help).
What am I doing wrong? What is the most effective way to go about this kind of situation where I am giving functionality to a series of independent DOM elements?
Just putting this out here that this seems to do the same thing.
$("span").click(function() {
$(this).siblings("div").toggleClass("blue");
});
Maybe I am missing something more that I am not seeing in your example.
See more: http://api.jquery.com/toggleclass/

Prevent iframe from keeping focus using jquery

Background:
I'm helping an old friend who has a mixed media slideshow, and one of the slides is an iframe embed of a lytro camera image (it's interactive and you can click or tap on mobile to change the focus).
Issue:
The issue that I'm having is that when you interact with the iframe, it steals keyboard focus on desktops and that prevents the arrow keys from allowing you to change slides.
What I've tried:
My main attack angle on this had been trying to use jquery to set a timer that periodically sets focus on the parent document, to remove focus from the iframe and allow the keystrokes to be captured properly. I've noticed that if I click anywhere outside of the iframe then I can use the arrow keys properly.
Here's my jquery code, along with comments about why I tried each method. Unfortunatly nothing has worked (I've also tried including the lytro image with an embed tag instead of the iframe tag with no change in results).
<script>
//make sure body maintains focus, so that swipe and arrows still work
function focusit(){
$('#focushere').focus(); // this is a div on the main page that I tried to set focus to
$('body').focus(); // tried moving focus to the body
$('embed').blur(); // tried bluring the embed
$('iframe').blur(); // tried bluring the iframe
$('body').click(); // tried faking a click on the body
$('#focushere').click(); //tried faking a click on a element
$(document).click(); // tried click on document
$(document).focus(); //tried setting focus to document
}
setTimeout(focusit, 100);
</script>
Your issue seems to be two-fold.
You are using setTimeout which will only run your callback once. I think you mean to use setInterval, which will repeatedly run the callback.
You can't set focus to document using the focus method natively or in jQuery. In order to restore focus to the body, you should call the blur method on the currently active element using document.activeElement.
Example:
function focusit(){
if(document.activeElement)
{
document.activeElement.blur();
}
}
setInterval(focusit, 100);
CodePen Demo

Twitter Bootstrap: Remove/Toggle the active state of checkbox-like button group

With twitters Bootstrap I've created a button group with radiobox behaviour to let the user choose between the different states. This works out of the box as supposed.
I arranged a jsFiddle with the example here: http://jsfiddle.net/jpxWj/
What I tried (and want) is that the pressed state can be removed when I click the active button second time.
I tried with jQuerys removeClass() to remove the active class from the btn classes but it won't work. (I also tried removing with .on() but this just keeps the active always hidden/removed)
Here you go, quite an unknown event phenomenon, in my opinion. You can read more about it here.
Edit:
To ellaborate, the reason why a simple .removeClass doesn't work, is because there are multiple listeners, listening to the same event. So when the click event is fired, a normal .removeClass would remove the class, but then the Twitter Bootstrap handler would add it again! To prevent any other handlers from being executed after yours, you can do e.stopPropagation. However, this does not stop the handlers attached to the same element as yours, it only stops the ones further up the tree. To completely make sure no other handlers are executed after yours, you can use event.stopImmediatePropagation().
Bootstrap 3 Update:
$('body').on('click', '.btn-group .btn.active',function(e){
e.preventDefault();
e.stopImmediatePropagation();
$(this).find('input').removeAttr('checked');
$(this).removeClass('active');
});

Changing css styles with jQuery (within a container)

Here is the jsFiddle: http://jsfiddle.net/JFwDw/2/
What I'm wanting to do is use links to change the font-size and line-height of paragraphs only within a division id'd "content". I've made another division to make sure it isn't changing anywhere else... can't get it to work after a while of playing around with it.
Thanks in advance.
You want to change which selector you're using. Instead of doing to all p tags, you just want the ones under #content
$("#content p, #content ul").css()
DEMO
Your links also link to <a href=""... which causes the page to reload. I changed it to href="#" so this doesn't happen. You could also prevent the default event from happening inside the functions.
function origText() {
event.preventDefault()
...
On a side note, I can't figure out why the functions are not working in the JS part of the fiddle...
http://jsfiddle.net/JFwDw/34/
This is working for me.
Edit: I think that this is what you're trying to achieve!
Well, for one, your links are being activated and reloading the page.
Typically when you write jQuery, you would attached the events using selectors, not using inline code. This let's you keep your JavaScript and HTML in separate files as well as allows jQuery to remove events when needed.
big text
$('#bigText').click( function(event) {
// code here
} );
Then to prevent the default action (following the link), you can use the jQuery method, prevent default action.
$('#bigText').click( function(event) {
event.preventDefaultAction();
// code here
} );
You may also what to wrap you event binding code withing a document ready event in order to make sure that the DOM is loaded before trying to attach events to it.
$(document).ready( function() {
$('#bigText').click( function(event) {
event.preventDefaultAction();
// code here
} );
} );
Also, you would typically want to add a class to change an element's styles rather than using jQuery to change the style. It's more performant. Also, if you want to only affect element within a container, you can use the jQuery "find" method to do so.
$('#someContainer').find('p').addClass('someClass');

How to stop toggle event from being fired multiple times on mouseenter/mouseleave?

I'm using jQuery to toggle the visibility of a <div> using the jQuery toggle method. The toggle is fired on the mouseenter and mouseleave event, thus creating the effect of the div to fold out on mouseenter and fold in on mouseleave. Problem is, if the user drags the mouse over the <div> a few times and then leaves the <div>, the div will toggle in and out several times. This can happen if the user accidentally moves around the mouse pointer in the <div> are. Do anyone have any idea on how I can avoid this behavior?
Thanx!
Two things:
If you're going to use both mouseenter and mouseleave I'd suggest using the hover() function; and
When using triggered animations it's a good habit to get into to use the stop() method.
So:
$("div.someclass").hover(function() {
$("...").stop().fadeIn("slow");
}, function() {
$("...").stop().fadeOut("slow");
});
Note: replace "..." with the appropriate selector for what you're toggling and use the appropriate effect (I'm using fade here). Also, this in an event handler refers to the source of the event.
You can use the more common mouseover/mouseout events to get a hover event that doesn't fire on internal mouse movements.
But don't use toggle on a mouse event, it can easily go wrong if eg. the mouse is over the element at page load time, or the mouse leaves the browser (which can allow the mouse to leave the bounds of the element without firing a mouseout). Have separate function for over which shows the content, and out which hides it.
Better: just use the hover() method which is meant for exactly this purpose.
Aside from the correct answer by Cletus, i'd like to point out that using mouseenter and mouseleave events is not wrong. The trick only resides into the stop() method, in fact we could still do:
$("div.someclass").on("mouseenter", function() {
$("...").stop().fadeIn("slow");
});
$("div.someclass").on("mouseleave", function() {
$("...").stop().fadeOut("slow");
});
Here is a jsFiddle example :)

Categories