Im using Skrollr for my website. It has to change from a horizontal scroll, for larger screens, to a vertical scroll, for phones. But the s.refresh didn't refresh the data-* values. I tried two codes, both of which changes the id, but skrollr didn't update accordingly.
Code 1:
<style>
#MainX {
-skrollr-animation-name: ScrollsX;
}
#-skrollr-keyframes ScrollsX {
0 {transform: translateX(0%);}
4000 {transform: translateX(-400%);}
}
#MainY {
-skrollr-animation-name: ScrollsY;
}
#-skrollr-keyframes ScrollsY {
0 {transform: translateY(0%);}
4000 {transform: translateY(-400%);}
}
#media (max-width: 991px) {
.container {
display: flex;
flex-direction: column;
height: auto;
}
.navbar {
position: relative;
}
}
</style>
<div id="MainX" class="container">
... Whole Code ...
</div>
<script>
var Func = function(){
if (window.innerWidth < 991) {
var Size = document.getElementById("MainX");
Size.id = "MainY";
skrollr.init();
skrollr.destroy();
skrollr.init();
}
if(window.innerWidth >= 991) {
var Size = document.getElementById("MainY");
Size.id = "MainX";
skrollr.init();
skrollr.destroy();
skrollr.init();
}
};
window.addEventListener("resize", Func);
window.addEventListener("onload", Func);
</script>
Code 2 (Style block code is unchanged):
<script>
window.onload = function(){
if (window.innerWidth < 991) {
var Size = document.getElementById("Gg");
Size.id = "MainY";
}
if(window.innerWidth >= 991) {
var Size = document.getElementById("Gg");
Size.id = "MainX";
}
};
var Func = function(){
if (window.innerWidth < 991) {
var Size = document.getElementById("MainX");
Size.id = "MainY";
}
if(window.innerWidth >= 991) {
var Size = document.getElementById("MainY");
Size.id = "MainX";
}
};
window.addEventListener("resize", Func);
</script>
<div id="Gg" class="container">
... Whole Code ...
</div>
<script type="text/javascript" src="js/ScrollX.js"></script>
<script type="text/javascript" src="js/ScrollAll.js"></script>
<script type="text/javascript">
var s = skrollr.init();
</script>
ScrollX.js is skrollr.min.js whilst ScrollAll.js is skrollr.stylesheets.min.js
For code 1, if the screen width initially is > 991, the id is MainX, and the data-0, and data-4000 are transform:translateX(*%);, while if I resize it to < 991, the id changes to MainY, but the corresponding data-0 and data-4000 are not updated to transform:translateY(*%);. if the width is initially < 991, the id is still MainX, and changes id only when resized, with no changes to the data-* variables. Moreover, this also adds a "no-skrollr" class in the head automatically, might be the reason why the skrollr doesn't works.
For code 2, the initial detection, and resize detection of screen width works fine, but does not even create the class skrollable skrollable-between nor the data-*.
What am I doing wrongly? Any help will be greatly help me. (p.s. this is for my e-portfolio website, wanted to make it a lil fun.)
Related
I want to fix a div element on the top by scrolling.
I have achieved this with the following code:
Javascript:
$(function () {
var msie6 = $.browser == 'msie' && $.browser.version < 7;
if (!msie6) {
var top = $('#betslip').offset().top - parseFloat($('#betslip').css('margin-top').replace(/auto/, 0));
$(window).scroll(function (event) {
// what the y position of the scroll is
var y = $(this).scrollTop();
// whether that's below the form
if (y >= top) {
// if so, ad the fixed class
$('#betslip').addClass('fixed');
} else {
// otherwise remove it
$('#betslip').removeClass('fixed');
}
});
}
CSS:
#betslip.fixed {
position: fixed;
top: 0;
}
HTML:
<div class="col-md-12" id="betslip">
...
</div>
The problem is that, while scrolling the div element is getting larger. How I can fix/prevent this?
Here is a screenshot after and before the scrolling:
By adding position: fixed; to #betslip it will ignore width of container. Try adding width: inherit; to #betslip.fixed
I'm trying to fade in/out and fix the blue div on the left when scrolled relative to the image blocks on the right.
http://www.warface.co.uk/#/testing/
pass: squared
.meta { /*This is the block I'm trying to stick/*
background: blue;
position: fixed;
width: 372px;
float: left;
z-index: 3;
right: 100%;
}
Here is the basics in JavaScript:
function controlMeta() {
var meta = document.querySelector("div.meta");
console.log(meta);
if (window.scrollY > 500) {
meta.style.display = "none";
} else {
meta.style.display = "block";
}
}
window.addEventListener("scroll", function () {
controlMeta();
})
You can get your elements scroll position with something like this:
document.getElementById("57513a9220c6475fb77061c5").getBoundingClientRect().top+window.scrollY
EDIT 1
Here is a method for associating elements with the meta box, based upon the previous:
//Load elements that affect the meta box
var meta = [];
var images = document.querySelector('.sqs-gallery').getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
meta.push({
node : images[i],
height : images[i].height,
//top is used with scroll position to determine which element we are looking at
top : images[i].getBoundingClientRect().top + window.scrollY
});
}
function controlMeta() {
meta.filter(function (el) {
//You might need to pad your filter a little
return window.scrollY < el.top && window.scrollY > el.top - el.height;
}).forEach(function (el) {
//These are the matching elements. I'm just fetching the src as an example
document.querySelector("div.meta div.body").innerHTML = el.node.src;
});
}
window.addEventListener("scroll", function () {
controlMeta();
});
I'm trying to create a div which will get a class only on scrolling and when the value of scroll is 210. I have next code :
$(document).ready(function() {
var pageWidth = $(window).width();
if(pageWidth > 700){
var contentLeft = $('#content-left');
var height = 210;
$(window).scroll(function () {
if ($(window).scrollTop() < height) {
contentLeft.attr('class', 'content-left');
} else {
contentLeft.attr('class', 'content-left leftContentFixed');
}
});
}
});
I try to apply this only on desktops.
Thus, I do not need the class leftContentFixed if it's on a smartphone or tablet.
If I try something like :
$(document).ready(function() {
var pageWidth = $(window).width();
if(pageWidth > 700){
alert("Bigger than 700");
}else{
alert("Smaller than 700");
}
});
Than it works perfect, but with my code it isn't working. The class leftContentFixed is added although the screen is smaller than 700.
Any advice?
You need to check screen size on resize event and check for its value when user scrolls the page. You could create mobile variable and make it true/false depends on screen size, then in scroll callback check for its value and choose correct class.
$(document).ready(function() {
var pageWidth = $(window).width(),
height = 210,
contentLeft = $('.content-left'),
mobile = false;
$(window).on('load resize', function() {
pageWidth = $(this).width();
// Save mobile status
if (pageWidth > 700) {
mobile = false;
} else {
mobile = true
}
})
$(window).on('scroll', function() {
if ($(window).scrollTop() > height) {
// Set default class
var _class = 'content-left leftContentFixed';
// If mobile then modify class
if (mobile) {
_class = 'content-left';
}
contentLeft.attr('class', _class);
} else {
var _class = 'content-left';
contentLeft.attr('class', _class);
}
});
});
html {
height: 2000px
}
.content-left {
background: gold;
width: 50px;
height: 100px;
}
.content-left.leftContentFixed {
position: fixed;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content-left"></div>
So basically I'd like to remove the class from 'header' after the user scrolls down a little and add another class to change it's look.
Trying to figure out the simplest way of doing this but I can't make it work.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll <= 500) {
$(".clearheader").removeClass("clearHeader").addClass("darkHeader");
}
}
CSS
.clearHeader{
height: 200px;
background-color: rgba(107,107,107,0.66);
position: fixed;
top:200;
width: 100%;
}
.darkHeader { height: 100px; }
.wrapper {
height:2000px;
}
HTML
<header class="clearHeader"> </header>
<div class="wrapper"> </div>
I'm sure I'm doing something very elementary wrong.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
//>=, not <=
if (scroll >= 500) {
//clearHeader, not clearheader - caps H
$(".clearHeader").addClass("darkHeader");
}
}); //missing );
Fiddle
Also, by removing the clearHeader class, you're removing the position:fixed; from the element as well as the ability of re-selecting it through the $(".clearHeader") selector. I'd suggest not removing that class and adding a new CSS class on top of it for styling purposes.
And if you want to "reset" the class addition when the users scrolls back up:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
});
Fiddle
edit: Here's version caching the header selector - better performance as it won't query the DOM every time you scroll and you can safely remove/add any class to the header element without losing the reference:
$(function() {
//caches a jQuery object containing the header element
var header = $(".clearHeader");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
header.removeClass('clearHeader').addClass("darkHeader");
} else {
header.removeClass("darkHeader").addClass('clearHeader');
}
});
});
Fiddle
Pure javascript
Here's javascript-only example of handling classes during scrolling.
const navbar = document.getElementById('navbar')
// OnScroll event handler
const onScroll = () => {
// Get scroll value
const scroll = document.documentElement.scrollTop
// If scroll value is more than 0 - add class
if (scroll > 0) {
navbar.classList.add("scrolled");
} else {
navbar.classList.remove("scrolled")
}
}
// Use the function
window.addEventListener('scroll', onScroll)
#navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 60px;
background-color: #89d0f7;
box-shadow: 0px 5px 0px rgba(0, 0, 0, 0);
transition: box-shadow 500ms;
}
#navbar.scrolled {
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.25);
}
#content {
height: 3000px;
margin-top: 60px;
}
<!-- Optional - lodash library, used for throttlin onScroll handler-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
<header id="navbar"></header>
<div id="content"></div>
Some improvements
You'd probably want to throttle handling scroll events, more so as handler logic gets more complex, in that case throttle from lodash lib comes in handy.
And if you're doing spa, keep in mind that you need to clear event listeners with removeEventListener once they're not needed (eg during onDestroy lifecycle hook of your component, like destroyed() for Vue, or maybe return function of useEffect hook for React).
Example throttling with lodash:
// Throttling onScroll handler at 100ms with lodash
const throttledOnScroll = _.throttle(onScroll, 100, {})
// Use
window.addEventListener('scroll', throttledOnScroll)
Add some transition effect to it if you like:
http://jsbin.com/boreme/17/edit?html,css,js
.clearHeader {
height:50px;
background:lightblue;
position:fixed;
top:0;
left:0;
width:100%;
-webkit-transition: background 2s; /* For Safari 3.1 to 6.0 */
transition: background 2s;
}
.clearHeader.darkHeader {
background:#000;
}
Its my code
jQuery(document).ready(function(e) {
var WindowHeight = jQuery(window).height();
var load_element = 0;
//position of element
var scroll_position = jQuery('.product-bottom').offset().top;
var screen_height = jQuery(window).height();
var activation_offset = 0;
var max_scroll_height = jQuery('body').height() + screen_height;
var scroll_activation_point = scroll_position - (screen_height * activation_offset);
jQuery(window).on('scroll', function(e) {
var y_scroll_pos = window.pageYOffset;
var element_in_view = y_scroll_pos > scroll_activation_point;
var has_reached_bottom_of_page = max_scroll_height <= y_scroll_pos && !element_in_view;
if (element_in_view || has_reached_bottom_of_page) {
jQuery('.product-bottom').addClass("change");
} else {
jQuery('.product-bottom').removeClass("change");
}
});
});
Its working Fine
Is this value intended? if (scroll <= 500) { ... This means it's happening from 0 to 500, and not 500 and greater. In the original post you said "after the user scrolls down a little"
In a similar case, I wanted to avoid always calling addClass or removeClass due to performance issues. I've split the scroll handler function into two individual functions, used according to the current state. I also added a debounce functionality according to this article: https://developers.google.com/web/fundamentals/performance/rendering/debounce-your-input-handlers
var $header = jQuery( ".clearHeader" );
var appScroll = appScrollForward;
var appScrollPosition = 0;
var scheduledAnimationFrame = false;
function appScrollReverse() {
scheduledAnimationFrame = false;
if ( appScrollPosition > 500 )
return;
$header.removeClass( "darkHeader" );
appScroll = appScrollForward;
}
function appScrollForward() {
scheduledAnimationFrame = false;
if ( appScrollPosition < 500 )
return;
$header.addClass( "darkHeader" );
appScroll = appScrollReverse;
}
function appScrollHandler() {
appScrollPosition = window.pageYOffset;
if ( scheduledAnimationFrame )
return;
scheduledAnimationFrame = true;
requestAnimationFrame( appScroll );
}
jQuery( window ).scroll( appScrollHandler );
Maybe someone finds this helpful.
For Android mobile $(window).scroll(function() and $(document).scroll(function() may or may not work. So instead use the following.
jQuery(document.body).scroll(function() {
var scroll = jQuery(document.body).scrollTop();
if (scroll >= 300) {
//alert();
header.addClass("sticky");
} else {
header.removeClass('sticky');
}
});
This code worked for me. Hope it will help you.
This is based of of #shahzad-yousuf's answer, but I only needed to compress a menu when the user scrolled down. I used the reference point of the top container rolling "off screen" to initiate the "squish"
<script type="text/javascript">
$(document).ready(function (e) {
//position of element
var scroll_position = $('div.mainContainer').offset().top;
var scroll_activation_point = scroll_position;
$(window).on('scroll', function (e) {
var y_scroll_pos = window.pageYOffset;
var element_in_view = scroll_activation_point < y_scroll_pos;
if (element_in_view) {
$('body').addClass("toolbar-compressed ");
$('div.toolbar').addClass("toolbar-compressed ");
} else {
$('body').removeClass("toolbar-compressed ");
$('div.toolbar').removeClass("toolbar-compressed ");
}
});
}); </script>
I am trying to create an flexibg image but it is not working.
I have followed this guide: http://kimili.com/journal/flexible-scalable-background-image
You can see the problem here:
http://mobilhimlen.dk/
My flexi.js:
var flexiBackground = function(){
/**
CONFIGURATION:
Define the size of our background image
*/
var bgImageSize = {
width : 1050,
height : 800
};
/**
Declare and define variables
*/
var $window,
$body,
imageID = "expando",
tallClass = 'tall',
wideClass = 'wide',
$bgImage, $wrapper, img, url, imgAR;
/**
Are we dealing with ie6?
*/
var ie6 = ($.browser.msie && parseInt($.browser.version, 10) <= 6);
/**
Set up the action that happens on resize
*/
var resizeAction = function() {
var win = {
height : $window.height(),
width : $window.width()
};
// The current aspect ratio of the window
var winAR = win.width / win.height;
// Determine if we need to show the image and whether it needs to stretch tall or wide
if (win.width < bgImageSize.width && win.height < bgImageSize.height) {
$body
.removeClass(wideClass)
.removeClass(tallClass);
} else if ((win.w < bgImageSize.width && win.height >= bgImageSize.height) || (winAR < imgAR)) {
$body
.removeClass(wideClass)
.addClass(tallClass);
// Center the image
$bgImage.css('left', Math.min(((win.width - bgImageSize.width) / 2), 0));
} else if (win.width >= bgImageSize.width) {
$body
.addClass(wideClass)
.removeClass(tallClass);
$bgImage.css('left', 0);
}
// Need to fix the height of the wrapper for IE6
if (ie6) {
$wrapper.css('height', win.height);
}
};
return {
/*
Sets up the basic functionality
*/
initialize : function() {
// No need for any of this if the screen isn't bigger than the background image
if (screen.availWidth <= bgImageSize.width || screen.availHeight <= bgImageSize.height) {
return;
}
// Grab elements we'll reference throughout
$window = $(window);
$body = $('body');
// Parse out the URL of the background image and drop out if we don't have one
url = $body.css('background-image').replace(/^url\(("|')?|("|')?\);?$/g, '') || false;
if (!url || url === "none" || url === "") {
return;
}
// Get the aspect ratio of the image
imgAR = bgImageSize.width / bgImageSize.height;
// Create a new image element
$bgImage = $('<img />')
.attr('src', url)
.attr('id', imageID);
// Create a wrapper and append the image to it.
// The wrapper ensures we don't get scrollbars.
$wrapper = $('<div></div>')
.css({
'overflow' : 'hidden',
'width' : '100%',
'height' : '100%',
'z-index' : '-1'
})
.append($bgImage)
.appendTo($body);
// IE6 Doesn't do position: fixed, so let's fake it out.
// We'll apply a class which gets used in the CSS to emulate position: fixed
// Otherwise, we'll simply used position: fixed.
if (ie6) {
$wrapper.addClass('ie6fixed');
} else {
$wrapper.css({
'position' : 'fixed',
'top' : 0,
'left' : 0
});
}
// Set up a resize listener to add/remove classes from the body
$window.bind('resize', resizeAction);
// Set it up by triggering a resize
$window.trigger('resize');
}
};
}();
$(document).ready(flexiBackground.initialize);
And my html:
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(document).ready(function() {
// simple example, using all default options
$('div.expandable').expander({slicePoint: 0});
});
</script>
<style type="text/css" media="screen">
body {
padding: 0;
margin: 0;
background-image:url(../images/bg_page_defaults.jpg);
background-position: top center;
background-repeat: no-repeat;
background-attachment: fixed;
margin-top:50px;
}
img#expando {
position: absolute;
display: none;
z-index: 1;
-ms-interpolation-mode: bicubic;
}
.wide img#expando,
.tall img#expando {
display: block;
}
.wide img#expando {
width: 100%;
height: auto;
}
.tall img#expando {
width: auto;
height: 100%;
}
.ie6fixed {
position: absolute;
top: expression((ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + 'px') !important;
}
</style>
</script><script type="text/javascript">
var border = RUZEE.ShadedBorder.create({ corner:8, shadow:16, border:2 });
border.render('round_me');
</script>
</head>
<body>
<script src="flexibg.js" type="text/javascript" charset="utf-8"></script>
</body>
Dont know what where wrong. Think I did update Jquery.