Had a look around and couldn't find anything that solved this very simple problem.
I'm still learning jQuery so prior apologies for my stupidity on this one, I know it's a very simple fix but things like using || and trying to using if and else inside a var don't see to work for me.
Essentially this is what I have currently. All I want is to add/remove the class "whitebg" depending on the scroll position and height of the element, which works well.
The problem is trying to query two different elements that each need a different height buffer as you can see (-167 and -90) so cannot be grouped, but need to be 'either / or' so both are accounted for.
Many thanks
Rb
jQuery(window).scroll(function() {
Menuresize();
});
function Menuresize() {
var myheight = jQuery(".section-image-slider, .section-video-slider").height() - 90;
var myheightalt = jQuery(".area-tag").height() - 167;
var scroll = jQuery(window).scrollTop();
if (scroll > myheight) {
jQuery(".bt-menu").addClass("whitebg");
}
elseif (scroll > myheightalt){
jQuery(".bt-menu").addClass("whitebg");
}
else {jQuery(".bt-menu").removeClass("whitebg");}
};
jQuery(window).resize(function() {
Menuresize();
});
If I understand your problem correctly, toggleClass can take a boolean parameter to toggle on/off the class specified. You can then work out a compound boolean expression that results in true or false:
e.g.
jQuery(".bt-menu").toggleClass("whitebg", scroll > myheight || scroll > myheightAlt);
I found the question a little hard to follow so, if it is something else you wanted, please clarify :)
Have your Menuresize function take parameters for the selectors and height, and then just call it for each:
function Menuresize(selector, height) {
var myheight = jQuery(selector).height() - height;
var scroll = jQuery(window).scrollTop();
if (scroll > myheight) {
jQuery(".bt-menu").addClass("whitebg");
}
else {
jQuery(".bt-menu").removeClass("whitebg");
}
};
jQuery(window).resize(function() {
Menuresize(".section-image-slider, .section-video-slider", 90);
Menuresize(".area-tag", 167);
});
Related
I want to add a class to an element as soon as the users' scroll-position has "hit" a special - other - element.
I try to use that code therefore
var hands = $(".sw_3--breit");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
// The next line is the one I am asking for help
if (scroll >= window.innerHeight)
{
hands.addClass("fixed");
} else {
hands.removeClass("fixed");
}
});
Which works nice by adding the class after the scroll is bigger then the users display-height I guess. But I want to add - and afterwards also remove - a class when then user has "hit" another element.
What I am asking for is something - very roughly and stupid I know - like:
var other_elements_position = $(".other_element"().position;
if (scroll >= other_elements_position)
How can I achieve that? And I already do use jquery for other things, so using jquery there would make sense I guess.
Thanks!
For people that got the same problem as I do have, this worked for me:
var hands = $(".sw_3--breit");
var hands_original = $(".sw_8").position();
var hands_off = $("#target_agentur").position();
var hands_corrected = (hands_original.top + 680) // here I add a small delay to the trigger of the "animation"
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll >= hands_corrected && scroll <= hands_off.top) // I doublecheck against 2 heights
{
hands.addClass("fixed");
} else {
hands.removeClass("fixed");
}
});
I use anime-js for create an animation. But, It is far in the page. I would like to launch my animation function when the section in which the item to be animated appears on the screen.
I tried a plugin that I like to use (jquery viewportchecker) but it does not seem to do that.
Can you help me ?
Thank you
I found a solution. The problem with your method is that the function repeats itself to infinity.
I create a little function for check if element is visible. With that, no plugin needed.
function checkVisible( elm, evale ) {
var evale;
evale = evale || "object visible";
var viewportHeight = $(window).height(), // Viewport Height
scrolltop = $(window).scrollTop(), // Scroll Top
y = $(elm).offset().top,
elementHeight = $(elm).height();
if (evale == "object visible") return ((y < (viewportHeight + scrolltop)) && (y > (scrolltop - elementHeight)));
if (evale == "above") return ((y < (viewportHeight + scrolltop)));
}
I also created a variable var counter = 0;. And as soon as the function is called, I increment by 1.
$(window).on('scroll',function() {
if (counter == 0){
if (checkVisible($('.frontend'))) {
// Your function here
}
}
}
At the first time the function will be called, counter will be 1, and thus, the function will not repeat. Thank you for your help !
jQuery.appear
This plugin implements custom appear/disappear events which are fired when an element became visible/invisible in the browser viewport.
https://github.com/morr/jquery.appear
$('someselector').on('appear', function(event, $all_appeared_elements) {
// this element is now inside browser viewport
});
$('someselector').on('disappear', function(event, $all_disappeared_elements) {
// this element is now outside browser viewport
});
Also this plugin provides custom jQuery filter for manual checking element appearance.
$('someselector').is(':appeared')
Have you tried using JQuery's on load method?
Something like
$(document).on('load', '.exampleClass', function() { //do stuff } )
I need a script which toggle a class when another class or section is visible in the viewport (during scrolling).
Here I have an script which works for precised distance from top, but can somebody help me to modify it for my needs?
$(window).scroll(function(){
if ($(this).scrollTop() > 50) {
$('#viewport').addClass('turn_on');
} else {
$('#viewport').removeClass('turn_on');
}
});
A couple of things. First the scroll event (as well as the resize event) fire multiple times. Traditionally, developers have used something called debouncing to limit the number of times a function fires. I've never got it to work correctly, so instead I check if a condition is met before continuing. You are basically doing this already.
var bool = false
$(window).on('scroll', function(){
if(!bool){
bool = true;
//fire the function and then turn bool back to false.
};
});
The next thing you need is to identify the element to add the class to. Let's say it has an id of foo.
var yOffset = $('#foo').offset().top;
From here, you'll need to compare the current vertical scroll position with that of the yOffset. You may also need to add the height of the element for when it scrolls out of frame.
var elHeight = $('#foo').height();
The element should be completely in frame with the $(window).scrollTop() equals the yOffset and out of frame when the $(window).scrollTop() is greater than yOffset + elHeight.
This is all assuming the element isn't in the frame to begin with. If it is, it will be trickier but it's a start.
Working fiddle
Try to add function that detect if element passed in argument is visible :
function isVisisble(elem){
return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}
$(window).scroll(function(){
if (isVisisble( $('your_element') ))
$('#viewport').addClass('turn_on');
} else {
$('#viewport').removeClass('turn_on');
}
});
Hope this helps.
Thx everyone for help.
Here I found the solution: LINK
And here is the modified script:
$(document).ready(function () {
var windowHeight = $(window).height(),
gridTop = windowHeight * 0.1,
gridBottom = windowHeight * 1;
$(window).on('scroll', function () {
$('.inner').each(function () {
var thisTop = $(this).offset().top - $(window).scrollTop();
if (thisTop > gridTop && (thisTop + $(this).height()) < gridBottom) {
$(this).addClass('on');
}
});
});
});
I am seeing that if a user scrolls too fast, the below jQuery function does not fire. Is this a performance issue/bug within jQuery detection of the event or do I need to do something with my code?
...Or, is there a better way [at least performance reliability wise] to call it with pure JavaScript? If so, how do I code it?
$(window).scroll(function() {
var st = $(this).scrollTop();
if(st < 50){
$('.header_wrapper').css({'marginTop':-50});
} if(st < 40){
$('.header_wrapper').css({'marginTop':0});
}
});
You can see it in action here: http://www.walkingfish-grainboards.com/privacy-policy/
Thnx for your help - it would be greatly appreciated.
Since you are considering performance:
$(window).on('scroll',function(){
var st = $(this).scrollTop(),
mTop = ((st < 40) ? 0 : -50);
$('.header-wrapper').css({marginTop:mTop});
});
Rather than put the assignment in the if you can just put the value, then do the assignment once based on the value. With your current statement, the -50px value you remain no matter how far down you go (as you never clear this value), and would only return to 0 when you scrolled back to the top. Hence, you do not need to have the nested if statement.
If you really wanna kick it up a notch, include caching:
var scrollStuff = {
headerWrapper:$('.header-wrapper'),
onScroll:function(){
var self = this,
st = $(self).scrollTop(),
mTop = ((st < 40) ? 0 : -50);
self.headerWrapper.css({marginTop:mTop});
}
};
$(window).on('scroll',function(){
scrollStuff.onScroll();
});
By caching everything including the function, you won't need to requery the DOM every time for the element you are applying the marginTop to.
Well, I over thought it originally. This works great:
$(window).scroll(function(){
yos = (window.pageYOffset > 48);
$('.headerwrap').toggleClass('stick', yos);
$('.pagetitlewrap').toggleClass('headerwrap_stuck', yos);
});
If I want to make responsive text I would probably write something like that:
$(window).resize(function ()
{
if $(document).width() <= 320) {
$('#mydiv').html('something')
}
if $((document).width() > 320) && (document).width() <= 480)) {
$('#mydiv').html('something longer')
}
if $((document).width() > 480) && (document).width() <= 768)) {
}
//and so on
}
I don't think it is most efficient (and messy code) - I think that there must be a way to make it easier - Let's assume that I can write this object which stores all the data:
var divTextPerScreenWidthMap = {
{'360','click'},
{'480','click it'},
{'768','click it right'},
{'1024','you know you want to click it'},
{'1280','click this button which is very long will help you'}
}
After I have done so, is there a simple function I can write that takes this data and simplify my many-conditions function? some sort of way to tell javascript how to build me the specific function I need?
something like this thing but in real code:
for (objects in divTextPerScreenWidthMap) {
create If Statement for Nth Object(object)
}
thanks,
Alon
I think using a lookup table like that is a bit overkill. Note that your code becomes much simpler if you use else ifs properly.
if $(document).width() <= 320) {
$('#mydiv').html('something')
} else if ($(document).width() <= 480) {
$('#mydiv').html('something longer')
} else if ($(document).width() <= 768) {
...
}
Something like this should work - it'll set it once for the first screen width (360) then for each subsequent one, if the width is smaller than the document's width, it'll overwrite it.
var docWidth = $(document).width();
for (var i in divTextPerScreenWidthMap)
{
if (parseInt(divTextPerScreenWidthMap[i][0]) < docWidth || i == 0)
{
// Set something here
console.log( divTextPerScreenWidthMap[i][1] );
}
}