Mask/overlay over page when menu is opened - javascript

I've some trouble with my script, I'm trying to figure out how I can make a mask/filter over the website when the menu is opened. In the HTML is a class called cmask and there is also a class called cmask is-active
It only has to do this when the screen is smaller than 900px. I've been trying to use cmask.addClass("is-active") and removeclass but its not working like that and it keeps crashing(makes the other part of the script not working anymore). Does someone knows what im doing wrong?
//scrolling----------------
//scrolling----------------
//scrolling----------------
var nav = $("#nav_id");
var nav_overflow = $("#nav_overflow");
var page_end_logo_nav = $("#page_end_logo_nav").visible();
var logo_container = $("#logo_container");
var nav_ani_speed = 200 //in ms
var nav_state = 0 // 0 is nav 1 is hamburger visable
var hamburger = $("#hamburgermenu") //hamburger elemnt
var distanceY;
var shrinkOn;
var winkel_mand = $("#winkel_mand")
//set scroll for desktop nav
function nav_desktop_check() {
distanceY = window.pageYOffset || document.documentElement.scrollTop;
shrinkOn = 100;
//run the header script
if (distanceY > shrinkOn) {
if (nav_state === 0) {
nav_hamburger();
}
} else {
if (nav_state === 1 ){
if ($(window).width() >= 900){
nav_normal_desktop();
}
}
}
}
//tablet nav check
function tablet_nav_check() {
if (nav_state === 0){
if ($(window).width() <= 900){
nav_hamburger();
}
}
}
tablet_nav_check()
//hambutton onclikc
hamburger.click(function() {
if (nav_state === 1){
if ($(window).width() >= 900){
nav_normal_desktop();
} else {
nav_normal_mobile();
}
logo_animation();
remove_winkel_icon_check()
} else{
nav_hamburger()
}
});
//nav to hamburger
function nav_hamburger() {
hamburger.removeClass("active")
nav_overflow.animate({
width: 0
}, nav_ani_speed, function() {
hamburger.addClass("active")
});
nav_state = 1;
logo_animation();
}
//hamburger to nav
function nav_normal_desktop() {
hamburger.addClass("active");
hamburger.removeClass("active");
nav_overflow.css("width", "auto");
nav_witdh = nav_overflow.innerWidth();
nav_overflow.css("width", 0);
nav_overflow.animate({
width: nav_witdh
}, nav_ani_speed, function() {
hamburger.removeClass("active")
});
nav_state = 0;
}
function nav_normal_mobile() {
nav_overflow.animate({
width: "100%"
}, nav_ani_speed, function() {
hamburger.removeClass("active")
});
nav_state = 0;
}

First I would add semicolons to all statements where it could fit, just to be sure you are not missing a mandatory one.
I've made a small overlay mask example
Javascript
$('#element').on("click",function() {
if($('#overlay').length == 0) {
$(this).wrap('<div id="overlay"><div>');
} else {
$(this).unwrap();
}
});
CSS
#element {
width:200px;
height:200px;
background-color:#f00;
}
#inner {
width:100px;
height:100px;
background-color:#0ff;
}
#overlay
{
background-color:#000;
opacity:0.3;
width:200px;
height:200px;
}
http://jsfiddle.net/5aw0wsy4/

Related

Javascript scroll listener not working in chrome or firefox

I have created a simple slider that on scroll scrolls down 100vh. It works perfectly in Safari but it doesn't seem to fire at all in both Chrome or Firefox.
Really appreciate it if anyone could point out to me where i may have gone wrong. I'm sure it's something simple but I just can't figure it out.
I have uploaded the files to my test web server so you can see the issue.
test.liamcrane.co.uk
var slider = document.querySelector('.section__wrapper__inner');
var sections = document.querySelectorAll('.section');
var currentTransform = 0;
var activeSection = 0;
function slideDown() {
if (!(activeSection === sections.length - 1)) {
sectionReset();
currentTransform -= 100;
slider.style.transform = "translate3d(0," + currentTransform + "vh, 0)";
activeSection++;
sections[activeSection].classList.add('active');
}
setTimeout(function() {
ready = true;
}, 2000);
}
function slideUp() {
if (!(activeSection === 0)) {
sectionReset();
currentTransform += 100;
slider.style.transform = "translate3d(0," + currentTransform + "vh, 0)";
activeSection--;
sections[activeSection].classList.add('active');
}
setTimeout(function() {
ready = true;
}, 2000);
}
function sectionReset() {
sections[activeSection].classList.remove('active');
}
var ready = true;
document.addEventListener('scroll', function() {
if (ready && window.pageYOffset > 0) {
ready = false;
slideDown();
} else if (ready && window.pageYOffset <= 0) {
ready = false;
slideUp();
}
});
.section__wrapper {
height: 100vh;
overflow: hidden;
}
.section__wrapper__inner {
height: 100%;
transform: translate3d(0, 0, 0);
transition: transform 1s;
}
.section {
position: relative;
height: 100vh;
color: black;
text-align: center;
}
.section span {
line-height: 100vh;
display:block;
}
<div class="section__wrapper">
<div class="section__wrapper__inner">
<section class="section"><span>1</span></section>
<section class="section"><span>2</span></section>
<section class="section"><span>3</span></section>
<section class="section"><span>4</span></section>
<section class="section"><span>5</span></section>
</div>
</div>
I think is that what you want
I have made a little workarround to force scroll ... maybe a little bit ugly but work see fakeScroll() function bellow.
That force the scrollbar to does not reach the beggining and the end. Because in your example above if the scroll bar reach the end ... scroll event can't be triggered (same if reach the begining).
I have also changed the conditions and the timming from setTimeout (ready = true) to 500. You can change it as you want
Sory for my English.
var slider = document.querySelector('.section__wrapper__inner');
var sections = document.querySelectorAll('.section');
var currentTransform = 0;
var activeSection = 0;
var lastOffset = window.pageYOffset;
var actualOffset = lastOffset;
function fakeScroll(){
if(lastOffset > 1){
window.scrollTo(0,lastOffset - 1);
}else{
window.scrollTo(0,1);
}
}
function slideDown() {
if (!(activeSection === sections.length - 1)) {
sectionReset();
currentTransform -= 100;
slider.style.transform = "translate3d(0," + currentTransform + "vh, 0)";
activeSection++;
sections[activeSection].classList.add('active');
}
fakeScroll();
setTimeout(function() {
ready = true;
}, 500);
}
function slideUp() {
if (!(activeSection === 0)) {
sectionReset();
currentTransform += 100;
slider.style.transform = "translate3d(0," + currentTransform + "vh, 0)";
activeSection--;
sections[activeSection].classList.add('active');
}
fakeScroll();
setTimeout(function() {
ready = true;
}, 500);
}
function sectionReset() {
sections[activeSection].classList.remove('active');
}
var ready = true;
window.addEventListener('scroll', function() {
actualOffset = window.pageYOffset;
if (actualOffset > lastOffset) {
if(ready){
ready = false;
slideDown();
}else{
fakeScroll();
}
} else if (window.pageYOffset <= lastOffset) {
if(ready){
ready = false;
slideUp();
}else{
fakeScroll();
}
}
lastOffset = window.pageYOffset;
});
.section__wrapper {
height: 100vh;
position:relative;
overflow: hidden;
}
.section__wrapper__inner {
height: 100%;
position:relative;
transform: translate3d(0, 0, 0);
transition: transform 1s;
}
.section {
position: relative;
height: 100vh;
color: black;
text-align: center;
}
.section span {
line-height: 100vh;
display:block;
}
<div class="section__wrapper">
<div class="section__wrapper__inner">
<section class="section"><span>1</span></section>
<section class="section"><span>2</span></section>
<section class="section"><span>3</span></section>
<section class="section"><span>4</span></section>
<section class="section"><span>5</span></section>
</div>
</div>
window.addEventListener('scroll', function() {
if (ready && window.pageYOffset > 0) {
ready = false;
slideDown();
} else if (ready && window.pageYOffset <= 0) {
ready = false;
slideUp();
}
});

How to add active class while scrolling in div?

Could you please tell me how to add an active class while scrolling in a div? I have one container, in which there are four divs. In the footer I also have four li (first, second, third). I want to select the li when the user scrolls the div.
Example
When the code runs, the first li should be selected because the first div is in the view port. If the user scrolls and moves to the second div, the second li should be selected. And so on.
I tried like that
https://jsbin.com/giwizufotu/edit?html,css,js,output
(function(){
'use strict';
$(function(){
$( "#container" ).scroll(function() {
console.log('scrlling');
if (elementInViewport2($('#first'))) {
// The element is visible, do something
console.log('first visible')
} else {
console.log('second visible')
}
});
})
function elementInViewport2(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}
})()
I don't want to use plugin
I have tried to use almost all the code you have written with little modifications:
Here is the working example link: https://jsfiddle.net/almamun1996/21wc37sx/3/
CSS:
.item {
width:25%;
display:inline-block;
margin:0;
padding:0;
color:blue;
font-size:20px;
text-align: center;
}
.footer{
border:1px solid;
position:fixed;
width:100%;
bottom:0px;
}
#container {
border:1px solid red;
overflow:auto;
width:100%;
height:300px;
}
.fC{
background-color:yellow;
padding:0;
}
#first{
background-color:blue;
}
#second {
background-color:green;
}
#third {
background-color:pink;
}
#fourth {
background-color:red;
}
.active {
background-color : red;
}
JS:
(function(){
'use strict';
$(function(){
$('.fC li:eq(0)').css('background-color','red').css('color','#ffffff');
$( "#container" ).scroll(function() {
//console.log('scrlling');
if (elementInViewport($('#first'))) {
// The element is visible, do something
//console.log('first visible')
} else {
//console.log('second visible')
}
});
});
function elementInViewport(e) {
var winBottom = $(window).scrollTop() + $(window).height();
var visibleETop = e.offset().top - winBottom;
var first = parseInt($('#first').css('height'));
var second = parseInt($('#second').css('height'));
var third = parseInt($('#third').css('height'));
var fourth = parseInt($('#fourth').css('height'));
if(Math.abs(e.offset().top) > first - parseInt($('#container').css('height')) && Math.abs(e.offset().top) <= first+second - parseInt($('#container').css('height')))
{
$('.fC li:eq(0)').css('background-color','').css('color','');
$('.fC li:eq(2)').css('background-color','').css('color','');
$('.fC li:eq(3)').css('background-color','').css('color','');
$('.fC li:eq(1)').css('background-color','red').css('color','#ffffff');
}
else if(Math.abs(e.offset().top) > first+second - parseInt($('#container').css('height')) && Math.abs(e.offset().top) <= first+second+third - parseInt($('#container').css('height')))
{
$('.fC li:eq(0)').css('background-color','').css('color','');
$('.fC li:eq(1)').css('background-color','').css('color','');
$('.fC li:eq(3)').css('background-color','').css('color','');
$('.fC li:eq(2)').css('background-color','red').css('color','#ffffff');
}
else if(Math.abs(e.offset().top) > first+second+third - parseInt($('#container').css('height')) && Math.abs(e.offset().top) <= first+second+third+fourth - parseInt($('#container').css('height')))
{
$('.fC li:eq(0)').css('background-color','').css('color','');
$('.fC li:eq(1)').css('background-color','').css('color','');
$('.fC li:eq(2)').css('background-color','').css('color','');
$('.fC li:eq(3)').css('background-color','red').css('color','#ffffff');
}
else{
$('.fC li:eq(1)').css('background-color','').css('color','');
$('.fC li:eq(2)').css('background-color','').css('color','');
$('.fC li:eq(3)').css('background-color','').css('color','');
$('.fC li:eq(0)').css('background-color','red').css('color','#ffffff');
}
if(visibleETop < 0){
return false;
}else{
return true;
}
}
})();
HTML:
Just replace the id='three' to id='third' in third div from your html.
You should consider changing class based on one edge-
function elementInViewport(e) {
var winBottom = $(window).scrollTop() + $(window).height();
var visibleETop = e.offset().top - winBottom;
if(visibleETop < 0){
return false;
}else{
return true;
}
}

Fixed div on scroll

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>

Horizontal scroll only if necessary

I'm having a horizontal scrolling page where arrows are indicated to scroll. I'm using the following code which works fine.
HTML:
<div id="container">
<div id="parent">
<div class="contentBlock">1</div>
<div class="contentBlock">2</div>
<div class="contentBlock">3</div>
<div class="contentBlock">4</div>
<div class="contentBlock">5</div>
</div>
<span id="panLeft" class="panner" data-scroll-modifier='-1'>Left</span>
<span id="panRight" class="panner" data-scroll-modifier='1'>Right</span>
CSS:
#container{
width:600px;
overflow-x:hidden;
}
#parent {
width:6000px;
}
.contentBlock {
font-size:10em;
text-align:center;
line-height:400px;
height:400px;
width:500px;
margin:10px;
border:1px solid black;
float:left;
}
.panner {
border:1px solid black;
display:block;
position:fixed;
width:50px;
height:50px;
top:45%;
}
.active {
color:red;
}
#panLeft {
left:0px;
}
#panRight {
right:0px;
}
Javascript:
(function () {
var scrollHandle = 0,
scrollStep = 5,
parent = $("#container");
//Start the scrolling process
$(".panner").on("mouseenter", function () {
var data = $(this).data('scrollModifier'),
direction = parseInt(data, 10);
$(this).addClass('active');
startScrolling(direction, scrollStep);
});
//Kill the scrolling
$(".panner").on("mouseleave", function () {
stopScrolling();
$(this).removeClass('active');
});
//Actual handling of the scrolling
function startScrolling(modifier, step) {
if (scrollHandle === 0) {
scrollHandle = setInterval(function () {
var newOffset = parent.scrollLeft() + (scrollStep * modifier);
parent.scrollLeft(newOffset);
}, 10);
}
}
function stopScrolling() {
clearInterval(scrollHandle);
scrollHandle = 0;
}
}());
You can also view the code in a WordPress-Installation right here: http://ustria-steila.ch/test
The arrows and the scroll works really well - but I have different sites with different amounts of text and images. So some pages need a horizontal scroll and some not. How can I add some kind of if-condition to display the arrows only if there is a horizontal overflow?
Your JavaScript code should go like this:
(function () {
var scrollHandle = 0,
scrollStep = 5,
parent = $("#container");
if(checkOverflow()){
$(".panner").show();
}
else
$(".panner").hide();
//Start the scrolling process
$(".panner").on("mouseenter", function () {
var data = $(this).data('scrollModifier'),
direction = parseInt(data, 10);
$(this).addClass('active');
startScrolling(direction, scrollStep);
});
//Kill the scrolling
$(".panner").on("mouseleave", function () {
stopScrolling();
$(this).removeClass('active');
});
//Actual handling of the scrolling
function startScrolling(modifier, step) {
if (scrollHandle === 0) {
scrollHandle = setInterval(function () {
var newOffset = parent.scrollLeft() + (scrollStep * modifier);
parent.scrollLeft(newOffset);
}, 10);
}
}
function stopScrolling() {
clearInterval(scrollHandle);
scrollHandle = 0;
}
function checkOverflow()
{
var el=document.getElementById('container');
var curOverflow = el.style.overflowX;
if ( !curOverflow || curOverflow === "visible" )
el.style.overflowX = "hidden";
var isOverflowing = el.clientWidth < el.scrollWidth;
el.style.overflowX = curOverflow;
return isOverflowing;
}
}());

Javascript/JQuery bouncing text off left and right sides of a div

I want text to bounce of the left and right sides of a div tag (#header). It works fine when it bounces of the right, then goes back and hits the left. The problem is that after it hits the left and starts to go right again it never hits the right side. It just keeps going and the window scrollbar appears. It appears as soon as it hits the left side. It seems that the div tag.
var finishedGoingRight = false;
setInterval(function() {
slideText();
}, 10);
function slideText(){
if(!finishedGoingRight){
$('#header h1').css("right","-=1");
}else{
$('#header h1').css("left","-=1");
}
if($('#header h1').css("right") == "20px"){
finishedGoingRight = true;
}
if($('#header h1').css("left") == "485px"){
finishedGoingRight = false;
}
}
Hope I explained it clearly :)
Debugging your code revealed that $('#header h1').css("right") always equals "auto", unless you've set it explicitly somewhere.
This works:
http://jsfiddle.net/7z3a3/1/
var finishedGoingRight = false;
setInterval(function() { slideText(); }, 10);
function slideText() {
if (!finishedGoingRight) {
$('#header h1').css("left", "+=1");
} else {
$('#header h1').css("left", "-=1");
}
if ($('#header h1').position().left >= $('#header').width()-$('#header h1').width()) {
finishedGoingRight = true;
} else if ($('#header h1').position().left <= 0) {
finishedGoingRight = false;
}
}
Here's my solution using animate:
JS:
var inner = $('#inner'), widthInner = inner.width(), outer = $('#outer'), widthOuter = outer.width();
function animateRight() {
inner.animate({ left: widthOuter - widthInner }, 1000, function() {
animateLeft();
});
}
function animateLeft() {
inner.animate({ left: 0 }, 1000, function() {
animateRight();
});
}
animateRight();
HTML
<div id="outer"><h2 id="inner">Inner</h2></div>
CSS
div, h2 { border: 1px solid black; }
#outer { width: 300px; height: 200px; }
#inner { margin-top: 75px; width: 50px; position: relative; }
http://jsfiddle.net/rHEQA/2/

Categories

Resources