Detecting mouse position in viewport (not in document) - javascript

I want to create a page that scrolls horizontally when user moves his mouse near left/right edge of the screen. My current code is:
$(window).mousemove(function(e) {
var mousePosition = e.pageX,
bodyWidth = config.windowWidth - 300;
if(mousePosition >= bodyWidth) {
$('body, html').animate({
scrollLeft: '+=50'
}, 100, function() {
console.log($('body, html').scrollLeft())
});
}
if(mousePosition < bodyWidth) {
$('body, html').stop()
}
});
It works great, but only until you get a little farther. Then it gets mousePosition from documents point of view, not viewport's. How can I fix this?

event.clientX/Y -> viewport
event.pageX/Y -> document

Related

Scroll position not being detected good enough

I have a part of code that looks if a user is scrolling up or down, and inside that check if the user is at the top of the page.
To see my position I log that position in my console but for some reason when I scroll up using my scroll wheel fast, it shows a number like 75, 98, 66 etc. Only when I scroll again (while it's already at the top) it goes to 0. Why?
$(window).bind('mousewheel', function(event) {
if (event.originalEvent.wheelDelta >= 0) {
var height = $(window).scrollTop();
console.log(height);
if(height > 20) {
$('.nav-link').css('color', '#2f323a');
}else{
$('.nav-link').css('color', '#ffffff');
}
}
});
I want to change the text color of my menu to white when a user is at the top but now if I scroll up fast using my mouse scroll it does not work right away.
Wouldn't you want to detect any kind of scroll? Not just mouse wheel.
$(document).ready(function() {
$(window).scroll(function() {
if ($(window).scrollTop() >= 20) {
$('.nav-link').css('color', '#2f323a');
} else {
$('.nav-link').css('color', '#ffffff');
}
});
});

Calculate distance to left/right viewport edge on load AND resize

I am trying to calculate the distance of an element to the left (and in another case to the right) edge of the viewport, so I could add it as a negative margin for the element to align with the viewport's edge. So far it works on load, but does some strange calculations when resizing the browser. Do I think something wrong here?
Here's what I use so far:
Right-viewport alignment:
$sidepic_element = jQuery('.right_element');
if($sidepic_element.length) {
jQuery(window).on("load resize", function() {
$offset = $sidepic_element.offset();
$sidepic_margin = -(jQuery(window).width() - ($sidepic_element.offset().left + $sidepic_element.width()));
$sidepic_element.css({
'margin-right': $sidepic_margin
});
});
}
Left-viewport alignment:
$blog_element = jQuery('.left_element');
jQuery(window).on("load resize", function() {
$offset = $blog_element.offset();
$blog_margin = -($blog_element.offset().left - jQuery(window).scrollLeft());
$blog_element.css({
'margin-left': $blog_margin
});
});

Smooth horizontal scrolling of large background images

at the website klangmanufaktur.de we have a horizontal scrolling design (on desktop screens). However, on some subpages there are large background images and scrolling is not smooth at all (when clicking the horizontal arrows):
www.klangmanufaktur.de/impressionen/
This is especially true for Safari.
The images are loaded using tags, but are changed to background images within a large using DOM manipulation with jQuery. There are to issues:
1. No smooth scrolling
2. Background images load only when scrolled into the viewport, so for a short moment, the black background is visible
Here is the code for horizontal scrolling on arrow click:
// horizontal scrolling on arrow click
$('.horizontal-arrow.right').click(function(){
if($(window).innerWidth()>767) {
var scrolled = false;
$('.pagebox-inner').each(function(){
if($(this).offset().left>window.pageXOffset + $(window).width() - $('header.site-header').outerWidth() && scrolled==false) {
$('body,html').animate({ scrollLeft: $(this).offset().left - $('header.site-header').outerWidth() }, 2000, 'swing',function(){
});
scrolled=true;
}
});
}
});
$('.horizontal-arrow.left').click(function(){
if($(window).innerWidth()>767) {
var scrolled = false;
$($('.pagebox-inner').get().reverse()).each(function(){
if($(this).offset().left<window.pageXOffset + $('header.site-header').outerWidth() && scrolled==false) {
$('body,html').animate({ scrollLeft: $(this).offset().left - $('header.site-header').outerWidth() }, 2000, 'swing',function(){
});
scrolled=true;
}
});
}
});
And here is the code for scrolling when a submenu link is clicked, like here:
www.klangmanufaktur.de/restaurierung
// horizontal scrolling of anchor links
$('nav.main-navigation li a').each(function(){
if($(this).attr('href')!=$(this).attr('href').replace('#','')) {
$(this).click(function(){
currentMainHash = window.location.hash;
var linkUrlSplit = $(this).attr('href').split("#");
var currElem = $('#post-'+linkUrlSplit[linkUrlSplit.length-1]);
if(currElem) {
if($(window).innerWidth()>767) $('body,html').animate({ scrollLeft: currElem.offset().left - $('header.site-header').outerWidth() }, 2000,'swing',function(){ scrolled = false; });
else $('body,html').animate({ scrollTop: currElem.offset().top }, 2000,'swing',function(){
scrolled = false;
$(this).blur();
});
}
$('.currentLink').removeClass('currentLink');
$(this).addClass('currentLink');
});
}
});
Any suggestions how to resolve the "unsmooth scrolling" issue here? Is it maybe helpful do display the images as elements instead of background images?
Thanks for your help!
Kind regards
joschi81

Fix navigation position when scrolling

I want to fix the position of navigation at the top when the navigation position and scroll position are equal.
Please let me know how can I get the position of navigation and page scroll position? I want something like this: http://new.livestream.com/live-video-tools
I've tried:
$(function() {
// grab the initial top offset of the navigation
var sticky_navigation_offset_top = $('#main-heading').offset().top;
// our function that decides weather the navigation bar should have "fixed" cs s position or not.
var sticky_navigation = function(){
var scroll_top = $(window).scrollTop(); // our current vertical position from the top
// if we've scrolled more than the navigation, change its position to fixed to stick to top,
// otherwise change it back to relative
if(scroll_top > sticky_navigation_offset_top) {
$('#fixed_nav').css({ 'position': 'fixed', 'top':6, 'left':0, 'width':'100%', 'z-index':999, 'height':80, 'background':'#fff' });
} else {
$('#fixed_nav').css({ 'position': '','overflow': 'visible', 'display':'block','height':80});
}
};
// run our function on load
sticky_navigation();
// and run it again every time you scroll
$(window).scroll(function() {
sticky_navigation();
});
});
This is old, but deserves an answer for Googlers' benefit.
See Fiddle here.
$(function () {
var offset = $('#nav').offset().top;
var nav = function () {
var scroll = $(window).scrollTop();
if (scroll < offset) {
$('#nav').css({ 'position': 'relative' });
}
else {
$('#nav').css({ 'position': 'fixed', 'top': 0 });
}
};
nav();
$(window).scroll(function () {
nav(); //this ensures we check again every time the user scrolls
});
});
OP - you probably figured it out by now, but I'm not sure why you were checking the offset of #main-heading and then setting the position of a different #fixed-nav, that's probably where you're issue was.

How to force positioned elements to stay withing viewable browser area?

I have a script which inserts "popup" elements into the DOM. It sets their top and left css properties relative to mouse coordinates on a click event. It works great except that the height of these "popup" elements are variable and some of them extend beyond the viewable area of the browser window. I would like to avoid this.
Here's what I have so far
<script type="text/javascript">
$(function () {
$("area").click(function (e) {
e.preventDefault();
var offset = $(this).offset();
var relativeX = e.pageX - offset.left;
var relativeY = e.pageY - offset.top;
// 'responseText' is the "popup" HTML fragment
$.get($(this).attr("href"), function (responseText) {
$(responseText).css({
top: relativeY,
left: relativeX
}).appendTo("#territories");
// Need to be able to determine
// viewable area width and height
// so that I can check if the "popup"
// extends beyond.
$(".popup .close").click(function () {
$(this).closest(".popup").remove();
});
});
});
});
</script>
You would compare the window width/height to the window's scrollTop, scrollLeft, etc.
Here are some methods for you to take a look at:
$(window).width()
$(window).height()
$(window).scrollTop()
$(window).scrollLeft()
$(window).scrollWidth()
$(window).scrollHeight()
Take a look at the jQuery documentation on these methods. Depending on exactly the behavior you want, you'll need to compare the width and position of your popup with the currently visible area of the window, determined with the scroll dimensions.
http://api.jquery.com/scrollTop/ .. etc
I figured out a solution. I added the following code in the place of my 4 line comment in the original question.
var diffY = (popup.offset().top + popup.outerHeight(true)) - $(window).height();
if (diffY > 0) {
popup.css({ top: relativeY - diffY });
}
var diffX = (popup.offset().left + popup.outerWidth(true)) - $(window).width();
if (diffX > 0) {
popup.css({ left: relativeX - diffX });
}
#liquidleaf pointed me in the right direction, so +1 and thanks for that.

Categories

Resources