I'm testing a ratings module I'm working on, had an idea for a fairly simple construction that'd allow for smooth ajax based voting, but found something odd..
The contruction is two divs, one nested in the other to show the stars, mousing over sets the width, which would be translated into a percent as a vote later on.
In testing this, I found that everything worked, but when I clicked, it sometimes made the width of the inner DIV reset, which is what it would do if I moused out, I'm not sure I understand why just yet. I'm including a working example of this.
http://www.nogumallowed.com/test.php
Here is the fixed code:
$(".ratingsBlock").mousemove(function(e){
$(".ratingsScale").width(e.offsetX);
});
$(".ratingsBlock").click(function(e){
$(this).attr("score",e.offsetX);
});
$(".ratingsBlock").mouseleave(function(e){
$(".ratingsScale").width($(this).attr('score'));
//$(".ratingsScale").animate({width:$(this).attr('score')+'px'}, 500);
});
I changed the mouseOut function to mouseLeave, and made the rating's score update when .ratingsBlock is clicked.
mouseOut is weird sometimes...
Related
I am using jQuery.eraser which works well to erase an image. But it works on click rather than hover. I thought I would be able to trigger a click on hover so it clicked where the mouse is. But what I have tried is not working. I am presuming I need to feed it some coordinates to work?
This is what I have tried:
$( "#image1" ).on('mouseenter mouseleave', function(){
$(this).trigger( "click" );
})
Here is a fiddle of a working example.
In the "bind events" section of eraser code, replace the bindings to the following:
$canvas.bind('mouseenter.eraser', methods.mouseDown);
$canvas.bind('mouseenter.eraser', methods.touchStart);
$canvas.bind('touchmove.eraser', methods.touchMove);
$canvas.bind('mouseleave.eraser', methods.touchEnd);
This seems to work on a laptop, however you should be aware that this is a quick and ugly fix, I am not sure how it will behave on mobile devices, and you should think twice before using it.
Demo: https://jsfiddle.net/q49w1cuj/
So i have this click function that toggles a dropdown-menu, but on Smartphones this is slow and not smooth.
Is there any other way to make this dropdown work with a smooth transition on any mobile device using jQuery?
(I've heard about "vclick" but couldn't find out how to make this work.
$j('.dropdown-menu').click(function() {
$j('.dropdown-menu').not(this).children('ul').slideUp("slow");
$j(this).children('ul').slideDown("slow");
});
$j('.dropdown-menu').blur(function() {
$j('.dropdown-inside').hide('slow', function() {
});
});
Try the click on Id rather then class. Class is always slow. So suppose if your dropdown has id like 'myDropdown' then do it like
$j('#myDropdown').click(function(){
//your code here
});
The first part can be simplified to this:
$j('.dropdown-menu').click(function() {
$j('.dropdown-menu').not(this).children('ul').slideToggle(2000);
});
Also, try wrapping the hidden content in a div and giving it a width. When you click on the div, it actually pulls it out of position to measure it before quickly replacing it because JQuery doesn't know the dimensions of your hidden div until it's displayed. So . This could make the whole animation laggy!
Another suggestion:
ID is faster than class. Part of the reason is that ID is supposed to be unique, so the API stops searching after the ID is found in the DOM.
If you must use a class or attribute selector, you can improve performance by specifying the optional context parameter.
Credits
Cause
According to Google :
...mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap.
Solution
1. Use fastclick.js to get rid of this 300ms lag
https://github.com/ftlabs/fastclick
2. Use application cache to speed up the load
https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache
I'm creating a site using Bootstrap 3, and also using a script that makes the dropdown-menu appear on hover using the .hover() function. I'm trying to prevent this on small devices by using enquire.js. I'm trying to unbind the .hover() event on the element using this code:
$('.dropdown').unbind('mouseenter mouseleave');
This unbinds the .hover of that script but apparently it also removes the .click() event(or whatever bootstrap uses), and now when I hover or click on the element, nothing happens.
So I just want to how I can remove the .hover() on that element, that is originating from that script, but not change anything else.
Would really appreciate any help.
Thanks!
Edit: Here is how I'm calling the handlers for the hover functions:
$('.dropdown').hover(handlerIn, handlerOut);
function handlerIn(){
// mouseenter code
}
function hideMenu() {
// mouseleave code
}
I'm trying to unbind them with this code.
$('.dropdown').unbind('mouseenter', showMenu);
$('.dropdown').unbind('mouseleave', hideMenu);
But its not working.
Please help!
**Edit2: ** Based on the answer of Tieson T.:
function dropdownOnHover(){
if (window.matchMedia("(min-width: 800px)").matches) {
/* the view port is at least 800 pixels wide */
$('.dropdown').hover(handlerIn, handlerOut);
function handlerIn(){
// mouseenter code
}
function hideMenu() {
// mouseleave code
}
}
}
$(window).load(function() {
dropdownOnHover();
});
$(window).resize(function() {
dropdownOnHover();
});
The code that Tieson T. provided worked the best; however, when I resize the window, until I reach the breakpoint from any direction, the effect doesn't change. That is, if the window is loaded above 800px, the hover effect will be there, but if I make the window smaller it still remains. I tried to invoke the functions with window.load and window.resize but it is still the same.
Edit 3: I'm actually trying to create Bootstrap dropdown on hover instead of click. Here is the updated jsFiddle: http://jsfiddle.net/CR2Lw/2/
Please note: In the jsFiddle example, I could use css :hover property and set the dropdow-menu to display:block. But because the way I need to style the dropdown, there needs to be some space between the link and the dropdown (it is a must), and so I have to find a javascript solution. or a very tricky css solution, in which the there is abot 50px space between the link and the dropdown, when when the user has hovered over the link and the dropdown has appeared, the dropdown shouldn't disappear when the user tries to reach it. Hope it makes sense and thanks.
Edit 4 - First possible solution: http://jsfiddle.net/g9JJk/6/
Might be easier to selectively apply the hover, rather than try to remove it later. You can use window.matchMedia and only apply your script if the browser has a screen size that implies a desktop browser (or a largish tablet):
if (window.matchMedia("(min-width: 800px)").matches) {
/* the view port is at least 800 pixels wide */
$('.dropdown').on({
mouseenter: function () {
//stuff to do on mouse enter
},
mouseleave: function () {
//stuff to do on mouse leave
}
});
}
else{
$('.dropdown').off('mouseenter, mouseleave');
}
Since it's not 100% supported, you'd want to add a polyfill for those browsers without native support: https://github.com/paulirish/matchMedia.js/
If you're using Moderizr, that polyfill is included in that library already, so you're good-to-go.
I still don't understand how you intend to "dismiss" the dropdown-menu once it is displayed upon mousing over the dropdown element partly because there's not enough code in your question, but that's sort of irrelevant to this answer.
I think a much easier way to approach the mousenter event handling portion is not by using off()/on() to unbind/bind events at a specific breakpoints, but rather to do just do a simple check when the event is triggered. In other words, something like this:
$('.dropdown').on('mouseenter', function() {
if($('.navbar-toggle').css('display') == 'none') {
$(this).children('.dropdown-menu').show();
};
});
$('.dropdown-menu').on('click', function() {
$(this).hide();
});
Here's a working fiddle: http://jsfiddle.net/jme11/g9JJk/
Basically, in the mouseenter event I'm checking if the menu toggle is displayed, but you can check window.width() at that point instead if you prefer. In my mind, the toggle element's display value is easier to follow and it also ensures that if you change your media query breakpoints for the "collapsed" menu, the code will remain in sync without having to update the hardcoded values (e.g. 768px).
The on click to dismiss the menu doesn't need a check, as it has no detrimental effects that I can see when triggered on the "collapsed" menu dropdown.
I still don't like this from a UX perspective. I would much rather have to click to open a menu than click to close a menu that's being opened on a hover event, but maybe you have some magic plan for some other way of triggering the hide method. Maybe you are planning to register a mousemove event that checks if the mouse is anywhere within the bounds of the .dropdown + 50px + .dropdown-menu or something like that... I would really like to know how you intend to do this (curiosity is sort of killing me). Maybe you can update your code to show the final result.
EDIT: Thanks for posting your solution!
Got a simple problem, which it doesn't look like HoverIntent would solve.
I have two elements (lets say a button and a div), one element is the trigger to start the div expanding, which is triggered by a mouseenter event (this would be a suitable candidate for HoverIntent).
However when the mouse leaves the expanded div for a given amount of time I need it to contract again, however if they re-enter the div it should NOT contract. Most hoverintent style plugins would give me this functionality but only for 1 element, and as one element controls the expanding (button - mouseenter) and one controls the contracting (div - mouseleave).
I know I could write some code to just do a setTimeout to delay for a period and make sure that the mouse is still outside of the area, but I would rather use a pre-made plugin if one exists.
So could anyone advise if this exists?
-- Edited --
Edited the above question to make clear that the main intent part is to stop it contracting the div if the mouse re-enters the div within a given amount of time, lets say 2 seconds. So the div should expand on mouseenter button, then contract if mouseleaves the div for >= 2 seconds.
Not something like this?
$('.hover-items').each(function(idx, el){
$(el).mouseenter(function() {
$(this).slideDown(300);
$('#target_div').unbind().mouseleave(function() {$(this).slideUp(300)});
});
});
The unbind is there so that you don't wind up with a bunch of events tied to the element. Just reset and go.
Added to satisfy clarification of question.
$('.hover-items').each(function(idx, el){
$(el).mouseenter(function() {
clearTimeout($(el).data('timer'));
$('#target_div').slideDown(300)
.unbind()
.mouseleave(function() {
var closure = function(){$('#target_div').slideUp(300)};
$(el).data('timer', setTimeout(closure,2000));
});
});
});
I have a BG image animation that relies on the hover callback to revert to it's original state. If I move the mouse quickly over the links, the hovered state sticks. My guess is that I'm moving the mouse off before the first animation completes, so the callback doesn't register.
Is there a more bulletproof way to write this function?
$('.nav li a').hover(function() {
$(this).addClass('hovered', 300);
}, function() {
$(this).removeClass('hovered', 300);
});
(it uses a BGimg plugin to support the speed parameter on add/removeClass)
Testable here: McPherson Industries
This is a common problem and cannot be fixed, I'm afraid – it's up to the browser to keep up with events, and if it can't, well, you're out of luck.
It might be jQuery's fault also, though. Hard to say without dwelling into the source code. Anyways, there's a easy workaround:
$('.nav li a').hover(function() {
// When element is hovered, remove hovered state from all elements..
$('.hovered').removeClass('hovered');
// ..and add it to this one.
$(this).addClass('hovered', 300);
}, function() {
// This is only needed when exiting an element and not enterin another one
$(this).removeClass('hovered', 300);
});
This might not be 100% certain, but it's better than your current.
What is the 300 value in the addClass method ? it does not take two parameters.. just one
Api reference: http://api.jquery.com/addClass/
(ok,noticed the plugin)
It works just fine for me .. all links revert back to their original image, no-matter how fast i move the mouse..
Update
Ok i see the problem now..
Chrome is OK (the only one it seems..)
Firefox shows the problem..
IE shows the problem
Update 2
It seems to me that the problem is with the plugin you use.. It ignores queued requests to the same object until the current animation has finished.. So if you hover out before the first one has completed it will not return to normal..
I can't help more on this, sorry ..