I'm writing the same code three times for the different pages of my WordPress site. I feel that it could be written more elegantly but unfortunately I'm not at the skill level yet to achieve this. Is there any way to combine all of this into something more concise? It would also probably help me learn more about what can and can't be done with JavaScript.
if (jQuery(document.body).hasClass("home")) {
jQuery(window).scroll(function () {
var threshold = 654;
if (jQuery(window).scrollTop() >= 654)
jQuery('#sidebar').addClass('fixed');
else
jQuery('#sidebar').removeClass('fixed');
});
} else if (jQuery(document.body).hasClass("single") || jQuery(document.body).hasClass("page")) {
jQuery(window).scroll(function () {
var threshold = 20;
if (jQuery(window).scrollTop() >= 20)
jQuery('#sidebar').addClass('fixed');
else
jQuery('#sidebar').removeClass('fixed');
});
} else {
jQuery(window).scroll(function () {
var threshold = 236;
if (jQuery(window).scrollTop() >= 236)
jQuery('#sidebar').addClass('fixed');
else
jQuery('#sidebar').removeClass('fixed');
});
}
var threshold = 236;
if (jQuery(document.body).hasClass("home")) {
threshold = 654;
} else if (jQuery(document.body).hasClass("single") || jQuery(document.body).hasClass("page")) {
threshold = 20;
}
var scrolled = false;
jQuery(window).scroll(function () {
if (!scrolled && jQuery(window).scrollTop() >= threshold){
jQuery('#sidebar').addClass('fixed');
scrolled = true;
} else if (scrolled && jQuery(window).scrollTop() < threshold) {
jQuery('#sidebar').removeClass('fixed');
scrolled = false;
}
});
UPDATE: I was created a simple demo to show how to implement sidebar scrolls within his parent.
Demo on CodePen
Damn.. I got beat. Well, I'm still posting this anyway.
var scrollTopFn = function(amount){
$(window).scroll(function(){
// this is a ternary statement, basically a shorthand for writing if else statements
$(window).scrollTop() >= amount
? $('#sidebar').addClass('fixed')
: $('#sidebar').removeClass('fixed');
});
}
if ($(document.body).hasClass('home')) {
scrollTopFn(654);
} else if ($(document.body).hasClass('single')){
scrollTopFn(20);
} else {
scrollTopFn(236);
}
Could be:
var threshold = 236;
switch (jQuery(document.body).attr("class")) {
case "home":
threshold = 654
break;
case "single":
case "page":
threshold = 20
break;
}
$(window).scroll(function () {
if (jQuery(window).scrollTop() >= threshold )
jQuery('#sidebar').addClass('fixed');
else
jQuery('#sidebar').removeClass('fixed');
});
Your code could be simplified to:
var $body = jQuery(document.body),
threshold = $body.hasClass("home") ? 654
: $body.hasClass("single") || $body.hasClass("page") ? 20
: 236;
jQuery(window).on('scroll', function() {
jQuery('#sidebar').toggleClass('fixed', state);
});
But this one should have better performance:
var $body = jQuery(document.body),
state = false,
threshold = $body.hasClass("home") ? 654
: $body.hasClass("single") || $body.hasClass("page") ? 20
: 236;
jQuery(window).on('scroll', function() {
if(state != (state = jQuery(window).scrollTop() >= threshold))
jQuery('#sidebar').toggleClass('fixed', state);
});
Related
I want to run a JS script when a particular div comes into the viewport/is visible.
The div will always be visible, but when the user scrolls it in to view.
I have created a JSFiddle with the example:
Example http://jsfiddle.net/sv8boe9u/21/
JS
consoleText(['HELLO,', 'HERE IS A BIT ABOUT ME,', 'ENJOY!'], 'text', ['#333', '#333', '#333']);
function consoleText(words, id, colors) {
"use strict";
if (colors === undefined) {
colors = ['#fff'];
}
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id);
target.setAttribute('style', 'color:' + colors[0]);
window.setInterval(function() {
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount);
window.setTimeout(function() {
var usedColor = colors.shift();
colors.push(usedColor);
var usedWord = words.shift();
words.push(usedWord);
x = 1;
target.setAttribute('style', 'color:' + colors[0]);
letterCount += x;
waiting = false;
}, 1000);
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000);
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount);
letterCount += x;
}
}, 120);
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden';
visible = false;
} else {
con.className = 'console-underscore';
visible = true;
}
}, 400);
}
To clarify, I want it to start at 'Hello' when it is actually in viewport. Any ideas?
Thanks.
Using the jQuery scroll() and scrollTop() functions you can specify a height in px that triggers another function when reached such as:
$(window).scroll(function () {
if ($(this).scrollTop() >= 50) { // If page is scrolled more than 50px
doSomething(); // call this function
}
});
jQuery Scroll and Scroll Top
you can use the scroll function ..like create a function that runs until wen you reach that element u are targeting.. then call the alert('hello');
window.addEventListener('scroll', (e) => {
console.log(window.scrollY)
if (window.scrollY == 705) {
alert('got ya')
// do your stuff here boss
}
})
you should make sure to find that scroll position wen yo element comes into view and then put it wr 705 is.. hope this helps ya
I have a javascript function that I need modified for certain screen sizes, though I've tried "if (screen.width <= 960) {... " and "if (window.width <= 960) {..." , only the part after "else" get's executed, like it's not even looking at the screen width I'm placing in the parenthesis.
Here is my function ( I know it's poorly written, but I'm new to javascript):
$(document).ready(function(){
var numberofscroll = 0;
var lastScrollTop = 0;
$("#home").scroll(function(){
var st = $(this).scrollTop();
(st > lastScrollTop) ? numberofscroll++ : numberofscroll--;
console.log(numberofscroll);
console.log(lastScrollTop);
console.log(st);
if (numberofscroll<2){
change_background2(numberofscroll);
}
else if (numberofscroll<3){
change_background3(numberofscroll);
}
else if (numberofscroll<4){
change_background4(numberofscroll);
}
lastScrollTop = st;
});
function change_background2(numberofscroll){
var i;
for (i = 2) {
$("#home").css("background-position","0 -652px");
}
}
function change_background3(numberofscroll){
var i;
for (i = 3) {
$("#home").css("background-position","0 -1326px");
}
}
function change_background4(numberofscroll){
var i;
for (i = 4) {
$("#home").css("background-position","0 -1978px");
}
}
)};
Corrections:
Changed all the for to ifs.
Corrected the parentheses.
Assigned a temp variable to ternary operation.
Changed all the i to numberofscroll
I believe the corrected JavaScript is:
$(document).ready(function () {
var numberofscroll = 0;
var lastScrollTop = 0;
$("#home").scroll(function () {
var st = $(this).scrollTop();
n = (st > lastScrollTop) ? numberofscroll++ : numberofscroll--;
console.log(numberofscroll);
console.log(lastScrollTop);
console.log(st);
if (numberofscroll < 2) {
change_background2(numberofscroll);
} else if (numberofscroll < 3) {
change_background3(numberofscroll);
} else if (numberofscroll < 4) {
change_background4(numberofscroll);
}
lastScrollTop = st;
});
function change_background2(numberofscroll) {
if (numberofscroll == 2) {
$("#home").css("background-position","0 -652px");
}
}
function change_background3(numberofscroll) {
if (numberofscroll == 3) {
$("#home").css("background-position","0 -1326px");
}
}
function change_background4(numberofscroll) {
if (numberofscroll == 4) {
$("#home").css("background-position","0 -1978px");
}
}
});
I think you want to use the innerWidth property of window. (https://developer.mozilla.org/en/docs/Web/API/window/innerWidth).
Basically, I want to have certain points on my website, that act like "magnets". If you are near one of these, the window should scroll to the top, similar to this jQuery plug-in : http://benoit.pointet.info/stuff/jquery-scrollsnap-plugin/
The problem is, that the window does not scroll, even though the page is in range of a "magnet".
here is the jQuery:
$(document).ready( function() {
var magnets = [];
var range = 200;
var active = true;
$('.container').each(function(i,obj) {
magnets.push($(this).offset().top);
});
console.log(magnets);
var attract = function(where,time){
$('html, body').animate({
scrollTop: where
}, time);
active = false;
};
//checks the range of a magnet
var magnetic = function(what){
var top = $(window).scrollTop();
var min = top - range;
var max = top + range;
if( (min <= what) && (max >= what) ){
return true;
} else{
return false;
}
}
//returns, wether you are in range of a magnet from your magnets array or not
var inRange = function(){
var magnet = -1;
for(var i=0; i<magnets.length; i++){
if( magnetic(magnets[i]) == true){
magnet = i;
}
}
return magnet;
}
$(window).scroll(function() {
$('.counter').html("");
$('.counter').append("<p>"+inRange()+"</p>");
if(active == true && inRange != -1){
attract(magnets[inRange()]);
}
else if(active == false && inRange() == -1){
active = true;
}
else if(active == true && inRange() == -1){
console.log("fuck");
}
});
});
alternative codepen link: http://codepen.io/NiclasvanEyk/pen/jEMrZr
There is a mistake in your code:
if(active == true && inRange != -1){
attract(magnets[inRange()]);
}
Should be
if(active == true && inRange() != -1){
attract(magnets[inRange()]);
}
Anywhy can i detect when user push up when scroll top less than 0 ? (Like facebook app reload)
This is my code idea so far :
window.onscroll = function (e) {
scrollTop = hasOffset ? window.pageYOffset : docBody.scrollTop;
detect_pushUp(scrollTop);
};
var push_up_check = true;
function detect_pushUp(scrollPosition) {
if(scrollPosition === 0 && !push_up_check) {
push_up_check = true;
} else if(scrollPosition === 0 && push_up_check) {
location.reload(true);
} else {
push_up_check = false;
}
}
This is working ok, But any better idea? to detect something like this?
I have a script that I want to execute only when a user reaches a position X (under my Nav bar) and to stop only when the user reaches this position X again (under my Nav bar).
How to achieve this effect?
EDIT:
How can I implement this code:
var reachedFromTop = false;
var reachedFromBottom = false;
$(window).scroll(function() {
//After scrolling 100px from the top...
if ($(window).scrollTop() > 100 ) {
if (!reachedFromTop) something();
reachedFromTop = true;
} else if (reachedFromTop && otherCondition) {
if (!reachedFromBottom) somethingElse();
reachedFromBottom = true;
}
});
in my existing script:
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('.main-navigation').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
if(Math.abs(lastScrollTop - st) <= delta)
return;
if (st > lastScrollTop && st > navbarHeight){
$('.main-navigation').removeClass('nav-down').addClass('nav-up');
} else {
if(st + $(window).height() < $(document).height()) {
$('.main-navigation').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
you should be able to do something like this.
var reachedFromTop = false;
var reachedFromBottom = false;
$(window).scroll(function() {
//After scrolling 100px from the top...
if ($(window).scrollTop() > 100 ) {
if (!reachedFromTop) something();
reachedFromTop = true;
} else if (reachedFromTop && otherCondition) {
if (!reachedFromBottom) somethingElse();
reachedFromBottom = true;
}
});
and you need to include jquery as your dependency