JavaScript: Set scroll position variable according to media queries - javascript

I am working on a fade-in/out-effect-on-scroll on a web project.
On my js I have to set a certain value for the scroll position i. e. the offset to make the effect kick in.
The problem:
The offset value cannot be applied to all kinds of devices due to
different heights.
Questions (hierarchic):
How to make the static values dynamic and variable to the device
height/media queries?
How can you generally slim down the code?
How can I trigger an additional slide-slightly-from-right/left to the
effect?
Here is the code:
// ---### FOUNDATION FRAMEWORK ###---
$(document).foundation()
// ---### FADE FX ###---
// ## SECTION-01: fade out on scroll ##
$(window).scroll(function(){
// fade out content a
$(".j-fadeOut").css("opacity", 1 - $(window).scrollTop() / 470);// 470 should be variable
// ## SECTION-02: fade in/out on scroll bottom ##
var offset = $('.j-fadeOut-2').offset().top;
console.log('offset: '+offset);
console.log('window: '+$(window).scrollTop())
if($(window).scrollTop() > offset)
{
// fade out top part of content b
$(".j-fadeOut-2").css("opacity", 1-($(window).scrollTop() - offset)/520);// 520 should be variable
// fade in bottom part of content c
$(".j-fadeIn").css("opacity", 0 + ($(window).scrollTop() - offset)/ 1100);// 1100 should be variable
}
});

See here for JavaScript Media Queries
You can use window.matchMedia to perform media queries in JavaScript. Example:
var mediaQuery = window.matchMedia( "(min-width: 800px)" );
The result will be stored as a boolean in mediaQuery.matches, i.e.
if (mediaQuery.matches) {
// window width is at least 800px
} else {
// window width is less than 800px
}
You can use multiple of these to suit your different device widths. Using the standard Bootstrap buckets:
var sizes = ['1200px', '992px', '768px', '480px']; // standard Bootstrap breakpoints
var fadeOutAs = [470, 500, 530, 560]; // this corresponds to your content a fadeout variable. Modify as required per screen size
var fadeOutBs = [520, 530, 540, 550]; // content B fadeout
var fadeOutCs = [1100, 1200, 1300, 1400]; // content C fadeout
var fadeOutA = 0;
var fadeOutB = 0;
var fadeOutC = 0;
for (i = 0; i < sizes.length; i++) {
var mediaQuery = window.matchMedia( "(min-width: " + sizes[i] + ")" );
if (mediaQuery.matches) {
fadeOutA = fadeOutAs[i];
fadeOutB = fadeOutBs[i];
fadeOutC = fadeOutCs[i];
}
}
Hope this helps

Related

conditional statement for running a function?

i have some js which runs when its on mobile. When the browser is above 768 this function shouldnt run. also is there a way to revert an append method in vanilla js?
if (window.innerWidth < 768 ) {
mobileNav();
} else {
}
Use this to conditional add and remove your mobile menu
var breakpoint = matchMedia("(min-width: 400px)")
var message1 = document.createElement('p')
var message2 = document.createElement('p')
message1.innerText = 'the viewport is at least 400 pixels wide'
message2.innerText = 'the viewport is less than 400 pixels wide'
function render() {
if (breakpoint.matches) {
// the viewport is at least 400 pixels wide
// add mobileNav()
message2.remove()
document.body.append(message1)
} else {
// the viewport is less than 400 pixels wide
// remove mobile nav
message1.remove()
document.body.append(message2)
}
}
render() // render initial
breakpoint.onchange = render // as well on changes

'Media-queries' for javascript - different code for different viewport height/widths

The problem
I'm using javascript to calculate widths of elements to achieve the layout I'm after. The problem is, I don't want to load the code on smaller screen sizes (when the screen width is less than 480px for example). I'd like this to work on load and on browser/viewport resize.
I'd consider small screen devices 'the default' and working up from there. So, none of the following script is called by default, then if the browser width is greater than 480px (for example), the following script would be called:
The code
$(document).ready(function() {
//Get the figures width
var figure_width = $(".project-index figure").css("width").replace("px", "");
//Get num figures
var num_figures = $(".project-index figure").length;
//Work out how manay figures per row
var num_row_figures = Math.ceil(num_figures / 2);
//Get the total width
var row_width = figure_width * num_row_figures;
//Set container width to half the total
$(".project-index").width(row_width);
x = null;
y = null;
$(".project-index div").mousedown(function(e) {
x = e.clientX;
y = e.clientY;
});
$(".project-index div").mouseup(function(e) {
if (x == e.clientX && y == e.clientY) {
//alert($(this).next().attr("href"));
window.location.assign($(this).next().attr("href"));
}
x = y = null;
});
});
// Drag-on content
jQuery(document).ready(function() {
jQuery('#main').dragOn();
});
The extra bit
The slight difference on larger screens is to do with the browser/viewport height. This is in regards to the line:
var num_row_figures = Math.ceil(num_figures / 2);
You can see once the calculation has a value, it divides it by 2. I only want this to happen when the browser/viewport height is above a certain amount - say 600px.
I'd be happy with this being the 1st state and then the value is divided by 2 if the height is greater than 600px if it's easier.
Can anyone help me/shed some light on how to manage my script this way. I know there's media queries for managing CSS but I can't seem to find any resources for how to manage javascript this way - hope someone can help.
Cheers,
Steve
You can use window.matchMedia, which is the javascript equivalent of media queries. The matchMedia call creates a mediaQueryList object. We can query the mediaQueryList object matches property to get the state, and attach an event handler using mediaQueryList.addListener to track changes.
I've added an example on fiddle of using matchMedia on load and on resize. Change the bottom left pane height and width (using the borders), and see the states of the two queries.
This is the code I've used:
<div>Min width 400: <span id="minWidth400"></span></div>
<div>Min height 600: <span id="minHeight600"></span></div>
var matchMinWidth400 = window.matchMedia("(min-width: 400px)"); // create a MediaQueryList
var matchMinHeight600 = window.matchMedia("(min-height: 600px)"); // create a MediaQueryList
var minWidth400Status = document.getElementById('minWidth400');
var minHeight600Status = document.getElementById('minHeight600');
function updateMinWidth400(state) {
minWidth400Status.innerText = state;
}
function updateMinHeight600(state) {
minHeight600Status.innerText = state;
}
updateMinWidth400(matchMinWidth400.matches); // check match on load
updateMinHeight600(matchMinHeight600.matches); // check match on load
matchMinWidth400.addListener(function(MediaQueryListEvent) { // check match on resize
updateMinWidth400(MediaQueryListEvent.matches);
});
matchMinHeight600.addListener(function(MediaQueryListEvent) { // check match on resize
updateMinHeight600(MediaQueryListEvent.matches);
});
#media screen and (max-width: 300px) {
body {
background-color: lightblue;
}
}
So i searched a bit and came up with this example from w3 schools .http://www.w3schools.com/cssref/tryit.asp?filename=trycss3_media_example1
i think this is something you are trying to achieve.
For pure js , you can get the screen width by screen.width

Change margin-top as user scrolls

I am trying to get a div to scroll up at the same amount of pixels as the user scrolls down the page. For example, in Google Chrome when using the mouse wheel, it scrolls down in about 20px intervals. But when you scroll down using the handle, the scrolling amount varies.
Here is my code so far:
var scrollCtr = 50;
$(window).scroll(function(){
scrollCtr = scrollCtr - 20;
$('div.nexus-files').css('margin-top', scrollCtr + 'px');
});
There are a few problems with this:
The user scrolling varies
It needs to subtract from margin-top if scrolling down and add to margin-top if scrolling up
Here is an example:
http://www.enflick.com/
Thanks for the help
You're doing it the wrong way, what you are trying to do should be done using position: fixed on div.nexus-files
div.nexus-files{position: fixed; top: 0;}
but anyway - if you still want to know what you can do with the scroll event - you better get to scrollTop of the document and set the margin-top to the same value
window.onscroll = function(event){
var doc = document.documentElement, body = document.body;
var top = (doc && doc.scrollTop || body && body.scrollTop || 0);
document.getElementById('nexus-files_id').style.marginTop = top+'px';
}
I'm using pure Javascript instead of jQuery because of the overhead that might be crucial when the browser need to calculate stuff in a very short amount of time (during the scrolling). [this can be done even more efficient by storing reference to the element and the doc... but you know..)
I used id based selector to get the specific element instead of class based
AND I SAY AGAIN - this is not how you should do what you were trying to do
Why not using the actual scroll offset as reference or position ?
// or whatever offset you need
var scrollOffset = document.body.scrollTop + 20;
// jQuery
var scrollOffset = $("body").scrollTop() + 20;
Finally Got it
Here is the code I used to accomplish the task.
Most of the code is from http://enflick.com and I modified it to work with my individual situation.
jQuery(window).load(function(){
initParallax();
});
// parallax init
function initParallax(){
var win = jQuery(window);
var wrapper = jQuery('#wrapper');
var bg1 = wrapper.find('.nexus-files');
var koeff = 0.55;
if (bg1.length) {
function refreshPosition(){
var scrolled = win.scrollTop();
var maxOffsetY1 = 450;
var offsetY1 = scrolled * koeff;
var offsetY2 = scrolled * koeff - (maxOffsetY1 * koeff - offsetY1);
if (offsetY1 <= maxOffsetY1 * koeff - offsetY1) {
bg1.css("margin-top", +-offsetY1+"px");
//alert(+-offsetY1+"px");
}
}
refreshPosition();
win.bind('resize scroll', refreshPosition);
}
}

Making a set of images move cross the screen then when leaving the window, it comes up from the other side

I'm trying to implement the marquee tag in jQuery by animation a set of images using animate() function, making them move to the right or left direction.
But, I couldn't figure out when a single image goes to the end of the screen returns individually to the other side.
Because I heard that the window size is not constant for every browser, So is there anyway to implement that?
this is what I came up so far(it's simple and basic):
$(document).ready(function(){
moveThumbs(500);
function moveThumbs(speed){
$('.thumbnails').animate({
right:"+=150"
}, speed);
setTimeout(moveThumbs, speed);
}
});
note: I searched in SO for related questions, but had no luck to find exact information for my specific issue.
Here's a basic script that moves an image across the screen and then resumes on the other side and adapts to the window width.
You can see it working here: http://jsfiddle.net/jfriend00/rnWa2/
function startMoving(img) {
var img$ = $(img);
var imgWidth = img$.width();
var screenWidth = $(window).width();
var amount = screenWidth - (parseInt(img$.css("left"), 10) || 0);
// if already past right edge, reset to
// just left of left edge
if (amount <=0 ) {
img$.css("left", -imgWidth);
amount = screenWidth + imgWidth;
}
var moveRate = 300; // pixels per second to move
var time = amount * 1000 / moveRate;
img$.stop(true)
.animate({left: "+=" + amount}, time, "linear", function() {
// when animation finishes, start over
startMoving(this);
})
}
$(document).ready(function() {
// readjust if window changes size
$(window).resize(function() {
$(".mover").each(function() {
startMoving(this);
});
});
});
​ ​

Auto-detect a screen resolution and change browser zoom with Javascript?

How do I auto-detect a screen resolution and change browser zoom with Javascript?
I was thinking of something more like this:
I've got the following code:
#warp with width: 3300% and a mask with width: 100%; and then, each .item has width: 3.030303% — with overflow hidden, otherwise it couldn't work as I want.
My point is: I've done this for at least 1280px wide screens.
What I want is if someone can write code that I could use toswitch the CSS file once viewed on a <1280px screen — them, I could do something like:
.item img { width: 80%; } and then, the result would be the same as "browser zoom out".
If you mean change the native browser zoom triggered by CTRL +/- then this isn't possible. You can adjust CSS properties/apply stylesheets but you cannot affect native browser controls. There are in fact CSS only options here depending on your target audience (and their browser choice) through the use of media queries, a couple of examples here and here. If these are not suitable then you can do various things with JavaScript to detect screen width/height and adjust accordingly.
Auto-detect a screen resolution
See this SO question
change browser zoom with javascript
This is not possible. See this SO question.
This will help to detect browser zoom tested on all browser
<script>
window.utility = function(utility){
utility.screen = {
rtime : new Date(1, 1, 2000, 12,00,00),
timeout : false,
delta : 200
};
utility.getBrowser = function(){
var $b = $.browser;
$.extend(utility.screen,$.browser);
utility.screen.isZoomed = false;
var screen = utility.screen;
screen.zoomf = screen.zoom = 1;
screen.width = window.screen.width;
screen.height = window.screen.height;
if($b.mozilla){ //FOR MOZILLA
screen.isZoomed = window.matchMedia('(max--moz-device-pixel-ratio:0.99), (min--moz-device-pixel-ratio:1.01)').matches;
} else {
if($b.chrome){ //FOR CHROME
screen.zoom = (window.outerWidth - 8) / window.innerWidth;
screen.isZoomed = (screen.zoom < .98 || screen.zoom > 1.02)
} else if($b.msie){//FOR IE7,IE8,IE9
var _screen = document.frames.screen;
screen.zoom = ((((_screen.deviceXDPI / _screen.systemXDPI) * 100 + 0.9).toFixed())/100);
screen.isZoomed = (screen.zoom < .98 || screen.zoom > 1.02);
if(screen.isZoomed) screen.zoomf = screen.zoom;
screen.width = window.screen.width*screen.zoomf;
screen.height = window.screen.height*screen.zoomf;
}
}
return utility.screen;
};
window.onresize = function(e){
utility.screen.rtime = new Date();
if (utility.screen.timeout === false) {
utility.screen.timeout = true;
setTimeout(window.resizeend, utility.screen.delta);
}
};
window.resizeend = function() {
if (new Date() - utility.screen.rtime < utility.screen.delta) {
setTimeout(window.resizeend, utility.screen.delta);
} else {
utility.screen.timeout = false;
utility.screen = utility.getBrowser();
if(window.onresizeend) window.onresizeend (utility.screen);
if(utility.onResize) utility.onResize(utility.screen);
}
};
window.onresizeend = function(screen){
if(screen.isZoomed)
$('body').text('zoom is not 100%');
else{
$('body').text('zoom is 100% & browser resolution is'+[screen.width+'X'+screen.height]);
}
};
$(document).ready(function(){
window.onresize();
});
return utility;
}({});
</script>
Demo
RE: Auto-detect a screen resolution and change browser zoom with Javascript?
The question is perfectly possible and is in effect at our website here:
www.noteswithwings.com
JS detects the screen width and zooms out or in a little to fit the content on to the screen.
Further, if the user resizes the window the zoom is triggered.
This actually helps fit content on to tablet sized screens and screens as small as the iphone without adding extra stylesheets or having to detect an OS/ Browser..
var oldZoom = $(window).width();
var windowWidth = $(window).width();
check_window_size(windowWidth,1,bsr,bsr_ver);
$(window).resize(function() {
var windowWidthnow = $(window).width();
check_window_size(windowWidthnow,2,bsr,bsr_ver);
});
function check_window_size(size,init_var,bsr,bsr_ver)
{
/* Develop for resizing page to avoid grey border!
Page layout 1265px wide.
On page resize shift layout to keep central, zoom BG-img to fill screen
Zoom content down for smaller screens by 5% to keep content flow!
*/
//change this var for screen width to work with, in this case our site is built at 1265
var wdth = 1265;
//Change this variable for minimum screen;
var smallest_width=1120;
var varZoom= $(window).width()/wdth;
var s_size = $(window).width();
var scale_smaller;
var center = (s_size-wdth)/2;
var its_ie=false;
if(size<=smallest_width)
{
$("#old_browser").css("width","50%").css({"height":"40px","left": center+"px"});
if(!check_for_object(false,"moved_pages"))
{
if(center<-110)//margin width!
{
if(!its_ie)
$("#scroller").css("zoom",0.95);
$("#footer").css("zoom",0.9).css("left",120+"px");
$(".colmask").css("left",-110+"px");
if(check_for_object(false,"move_menu_loggedin"))
$("#move_menu_loggedin").css("right","110px");
if(check_for_object(false,"login_div"))
$("#login_div").css("left","-80px");
return;
}
$("#move_menu_loggedin").css("left","-"+center+"px");
$("#scroll").css("zoom","normal");
$(".colmask").css("left",center+"px");
}
else
{
/*Only pages that you do not want to move the colmask for!*/
$("#scroller").css("zoom",0.90);//.css("left","-50px");;
$("#footer").css("zoom","normal");
}
}
else
{
if(size>wdth)
$("#background").css("zoom",varZoom);
$("#scroller").css("zoom","normal");
$("#footer").css({"zoom":"normal","left":0});
if(!check_for_object(false,"moved_pages"))
{
$(".colmask").css("left",center+"px");
$(".colmask").css("zoom","normal");
var movelog = -center;
if(check_for_object(false,"move_menu_loggedin"))
$("#move_menu_loggedin").css("right",movelog +"px");
if(check_for_object(false,"login_div"))
$("#login_div").css("left","80px");
}
else
{
$(".colmask").css("zoom","normal");
}
}
}
-- check_window_size(windowWidth,1,bsr,bsr_ver); bsr & bsr_ver are detected using a php class.
-- #old_browser is a div containing information if you have an old web browser.
-- #background is a fixed image 100x100% of the screen.
As you can see we also move a few items which were not in the containing div scope.
Colmask is the containing div for most of the pages content (For us that sits underneath the header which is why we move some items manually)
Hope the code snippet can help someone else achieve this.

Categories