jQuery /hover()/.mousemove() optimization issue - javascript

I'm working on a basic modal example in which the modal would follow the mouse cursor as long as the user was hovering over a certain section.
The issue I'm having is, when going from left to right, the modal lags significantly, as well as triggers the fadeOut() set if the user were to mouse out of the specific section.
Right to left, works seamlessly.
In the fiddle, you can observe the lagginess when moving the mouse over the <nav> from top to bottom, as well as notice the solid performance from bottom to top.
If there are any duplicate questions or related articles that you all know of, please point me in the right direction. My searches thus far have been informational but have not adressed this specific issue.
Here is my fiddle.
Thank you all, as always pro advice is warmly welcomed.
Ken

The issue is that jquery fires onmouseout event when you add the modal element it gets "focus" and hover events are not firing on your nav element.
I altered your example so that it is wokring much better now, check it out here

Oh awesome, classic example! The problem is that the jQuery thinks you've moused-out once you touch the section#coming-soon, so it obviously runs the fadeOut...
One way to overcome this is to put the section#coming-soon inside the nav, that way the script will still think you're inside the section#coming-soon, even if you hover over it:
<nav>
<ul>
<li><a>Home</a></li>
<br />
<li><a>About</a></li>
<br />
<li><a>My Work</a></li>
<br />
<li><a>Blog</a></li>
<br />
<li><a>Contact</a></li>
</ul>
<section id="coming-soon">
<h2>Coming Soon!</h2>
</section>
</nav>
Example here: http://jsfiddle.net/gcJuz/1/

Just a few recommendations to help out.
// cache the jquery object
var target = $('section#coming-soon');
target.hide();
// select the specific nav, not all navs
$('nav:first').mouseenter(function(){
// only need to show it once on enter
target.show();
}).mousemove(function(e) {
// can't really avoid this unless you want to keep moving it around all the time
// but show it only once you mouse over
target.css({
'position' : 'absolute',
'top' : e.pageY,
'left' : e.pageX
});
}).mouseleave(function() {
target.fadeOut(1300);
});

Related

Click function making page scroll in odd way (not to top of page)

First time asker, long time lurker.
I'm doing a fadein/out toggle that displays 1 of 2 charts depending on which button you click.
That bit works just fine, but I'm getting a weird page-jump glitch. Now, it's not the usual jump-to-the-top behaviour. I have that part covered in the code, and it doesn't do that.
Every time I click on one of the toggles, the page scrolls downward to the point where the chart area is at the bottom of the window.
But it gets weirder. If I make the browser window very short or very narrow (it's a responsive site), it stops doing this glitch. It's also not happening on iPhone or iPad at all, even though if I set the browser width to the same width as it would be on an iPad, the desktop browser still does the jumping.
There are no elements that are added/removed based on the viewport width in the area that's jumping around, and there are no anchor IDs that would be accidentally used as jump points.
Unfortunately I can't show the actual page to you, but I can show the script and a bit of the HTML.
The code for both toggles is the same, just with the IDs switched around.
The script:
$('#left-toggle > a').click(function(c)
{
c.preventDefault();
c.stopPropagation();
$('#right-toggle').removeClass('toggle-active');
$('#left-toggle').addClass('toggle-active');
$(pricing_subscriptionID).fadeOut('fast', function(){
$(pricing_singleID).fadeIn('fast', function(){
});
});
});
The HTML for the toggles:
<div id="chart-toggle">
<div id="left-toggle" class="toggle-active">Single Pricing</div>
<div id="right-toggle">Subscription Pricing</div>
</div>
"toggle-active" is just for styling.
Any ideas?
It seems to be almost wanting to centre the toggles on the page, but it's not quite putting them in the middle either.
JSFiddle: http://jsfiddle.net/TmrLw/
It's because of your link to #. Here are some ways you can fix this:
1. Replace "#" with something else
Instead of
Subscription Pricing
Try this:
Subscription Pricing
This will give you the cursor pointer you're looking for and avoid the page jump.
2. Create a class with the pointer effect
If you use this CSS rule:
.pointer {
cursor: pointer;
}
Then you can wrap your text with this class instead:
<div class="pointer">Subscription Pricing</div>
3. Remove the default effect of "#"
This Javascript will get rid of its default effect:
$('a[href="#"]').click(function(e)
{
// Cancel the default action
e.preventDefault();
});
Hope this helps
Probably its because the link's href is # which links to the top of the document.
try to remove the href attribute

how to show div when scroll reach?

divs are showing underneath one bye one of DIV
is there any option to show each .slide on the basis of mouse scrolling ?
go to underneath while scroll up
http://jsfiddle.net/WQ3hE/
You can check out the current scroll top, and then based on that, fire a jQuery code to activate the current tab. That's possible. A few things are unclear about your question. First being, this looks like a homework question. We would like to know what you have done so far. Secondly, you didn't provide what you need to do after the scroll.
$(document).ready(function(){
$(window).scroll(function(){
if (window.scrollY > 100)
$(".slide[data-slide='2']").height(2000);
});
});
Fiddle: http://jsfiddle.net/praveenscience/WQ3hE/1/

Scrolling a <div> to Specific Content

I'm creating a split page with a menu on the left, and the main content on the right. When I click on a menu item, I want to scroll the main content to that item.
I found JavaScript scrollTo(), which takes offset arguments.
Is there any way to determine the offset of a particular <p> or other element within a <div>? Or perhaps there is another way to scroll to an element without knowing its offset?
EDIT
Thanks for the replies. Looks like everyone gave similar answers. However, I ran into a problems with this. It seems that offset().top (or position().top) return different values depending on the current scroll position.
My jsFiddle is here: http://jsfiddle.net/gBTW9/4/embedded/result/
If I scroll to the top and selection Section 4, it works as expected. But once I've scrolled, it stops working correctly. Can anyone see what is happening.
There are jquery methods offset and position stat can help there.
Also there is good scrollTo plugin which accepts elements and much more.
You can get the vertical offset of an element using $('p').offset().top. You can combine this with scrollTop() using this:
$('div').scrollTop($('p').offset().top);
You need to use position() rather than offset(). If you know the id of that you can easily find the position of that paragraph tag
jQuery: Difference between position() and offset()
If i didn't misunderstood you just need an animated scrolling to a particular element, something similar on what I did on my portfolio.
Assuming that the menu on the left is fixed, then just scroll the page to the element you want to scroll to:
$("html, body").animate({
scrollTop: $('#element').offset().top
});
If you need to move a particular element over another element then:
$("#element1").animate({
top: $('#element2').offset().top
});
Why try it the hard way, when you can use a HTML native attribute??
call me old school, but i like to keep it simple.
within your menu:
use:
<ul>
<li>
Paragraph 1
</li>
</ul>
instead of
<ul>
<li>Paragraph 1</li>
</ul>
this will make your section jump to the # (id) that equals Paragraph1

How to disable all other events in jquery when animation is in progress

I am writing here againg, because I have some problems with script in my page. I had one problem with menu focus and I write it a week or two ago at this forum, but the awesome script which suggest me one user has one bug and I don't know how to solve it. I have tried a lot's of plausible solutions, but problem still persists.
Here is code at Fiddle, which simulates my problem: http://jsfiddle.net/PRZYN/15/
$(document).ready(function() {
$('#handle').mouseenter(slideIn);
$("#box").mouseleave(function() {
$(this).animate({
left: "-=180px"
}, "fast");
$('#handle').mouseenter(slideIn);
});
$("[name='skin']").mouseleave(function(e) {
e.stopPropagation();
});
});
function slideIn() {
if ($("#box")) $("#box").animate({
left: "+=180px"
}, "slow");
$(this).unbind("mouseenter");
}
As you can see, there is one div (blue-green one which presents left menu pop-up), which show when div get focus and hide when div lost focus.
Problem in this script is, that when are this two divs in animation state and If user very fast move mouse through animation of front end animation and backend the script gets confused and menu start showing and hiding and it's very annoying. Also there are some other ways when menu gets the same bug but I didn't located it very well. I think, that problem also shows when user hover this div and mouse stop at some place - which is different from time to time.
I have located problem somehow, but I don't know how to solve it. I need to disable all other events on this div (but not .animation()) when menu is in animation state and on elements when mouse is not over div and then enable it again when animation complete and user wants again open or hide menu.
I hope, that you understand my question and I will be very happy if someone could help me on that how to solve problem.
Regards,
Miha
You can use .stop() to cancel your animation queue and to prevent the animation from running after the user has stopped interacting with the element. Also, it's better to used fixed values for left, as using += and -= will cause the box to be incorrectly aligned after rapidly mousing in and out of the container. ie use values such as "-180px" and "0px" instead of "-=180px" and "+=180px".
JSFiddle: http://jsfiddle.net/PRZYN/16/

HTML "overlay" which allows clicks to fall through to elements behind it [duplicate]

This question already has answers here:
HTML/CSS: Make a div "invisible" to clicks?
(5 answers)
Closed 7 years ago.
I'm trying to overlay a element on top of a webpage (to draw arbitrary graphics), and I've come to the point where I can stack it inside of a element on top of everything, but this prevents the user from clicking on any links/buttons/etc.
Is there a way to have its content float on top of everything (it's semi-transparent, so you can still see what is behind) and have the user interact with the layer below it?
I've found a lot of information on the DOM event model, but none of it addresses the problem where the buttons and other "native" controls never seem to get the clicks in the first place.
A silly hack I did was to set the height of the element to zero but overflow:visible; combining this with pointer-events:none; seems to cover all the bases.
.overlay {
height:0px;
overflow:visible;
pointer-events:none;
background:none !important;
}
Add pointer-events: none; to the overlay.
Original answer: My suggestion would be that you could capture the click event with the overlay, hide the overlay, then refire the click event, then display the overlay again. I'm not sure if you'd get a flicker effect though.
[Update] Exactly this problem and exactly my solution just appeared in this post: "Forwarding Mouse Events Through Layers". I know its probably a little late for the OP, but for the sake of somebody having this problem in the future, I though I would include it.
For the record an alternative approach might be to make the clickable layer the overlay: you make it semi-transparent and then place the "overlay" image behind it (somewhat counterintuitively, the "overlay" image could then be opaque). Depending on what you're trying to do, you might well be able to get the exact same visual effect (of an image and a clickable layer semi-transparently superimposed on top of each other), while avoiding clickability problems (because the "overlay" is in fact in the background).
In case anyone else is running in to the same problem, the only solution I could find that satisfied me was to have the canvas cover everything and then to raise the Z-index of all clickable elements. You can't draw on them, but at least they are clickable...
My team ran into this issue and resolved it very nicely.
add a class "passthrough" or something to each element you want clickable and which is under the overlay.
for each ".passthrough" element append a div and position it exactly on top of its parent. add class "element-overlay" to this new div.
The ".element-overlay" css should have a high z-index (above the page's overlay), and the elements should be transparent.
This should resolve your problem as the events on the ".element-overlay" should bubble up to ".passthrough". If you still have problems (we did not see any so far) you can play around with the binding.
This is an enhancement to #jvenema's solution.
The nice thing about this is that
you don't pass through ALL events to ALL elements. Just the ones you want. (resolved #jvenema's argument)
All events will work properly. (hover for example).
If you have any problems please let me know so I can elaborate.
You can use an overlay with opacity set in order to the buttons/anchors in the back stay visible, but once you have that overlay over an element, you can't click it.
Generally, this isn't a great idea. Taking your scenario, if you had evil intentions, you could hide everything underneath your "overlay". Then, when a user clicks on a link they think should take them to bankofamerica.com, instead it triggers the hidden link which takes them to myevilsite.com.
That said, event bubbling works, and if it's within an application, it's not a big deal. The following code is an example. Clicking the blue area pops up an alert, even though the alert is set on the red area. Note that the orange area does NOT work, because the event will propagate through the PARENT elements, so your overlay needs to be inside whatever element you're observing the clicks on. In your scenario, you may be out of luck.
<html>
<head>
</head>
<body>
<div id="outer" style="position:absolute;height:50px;width:60px;z-index:1;background-color:red;top:5px;left:5px;" onclick="alert('outer')">
<div id="nested" style="position:absolute;height:50px;width:60px;z-index:2;background-color:blue;top:15px;left:15px;">
</div>
</div>
<div id="separate" style="position:absolute;height:50px;width:60px;z-index:3;background-color:orange;top:25px;left:25px;">
</div>
</body>
</html>
How about this for IE?:
onmousedown: Hide all elements which could overlay the event. Because display:none visibility:hidden not realy works, push the overlaying div out of the screen for a fixed number of pixels. After a delay push back the overlaying div with the same number of pixels.
onmouseup: Meanwhile this is the event you like to fire.
//script
var allclickthrough=[];
function hidedivover(){
if(allclickthrough.length==0){
allclickthrough=getElementsByClassName(document.body,"clickthrough");// if so .parentNode
}
for(var i=0;i<allclickthrough.length;i++){
allclickthrough[i].style.left=parseInt(allclickthrough[i].style.left)+2000+"px";
}
setTimeout(function(){showdivover()},1000);
}
function showdivover(){
for(var i=0;i<allclickthrough.length;i++){
allclickthrough[i].style.left=parseInt(allclickthrough[i].style.left)-2000+"px";
}
}
//html
<span onmouseup="Dreck_he_got_me()">Click me if you can.</span>
<div onmousedown="hidedivover()" style="position:absolute" class="clickthrough">You'll don't get through!</div>
I was having this issue when viewing my website on a phone. While I was trying to close the overlay, I was pretty much clicking on anything under the overlay. A solution that I found working for myself is to just add a tag around the entire overlay

Categories