I have this code so that each element make the scroll effect when done: I keep repeating the function to each element, the problem that are 8 elements with different classes to add functions, the code would be very large.
$(window).scroll(function () {
$('#section6').each(function () {
var imagePos = $(this).offset().top;
var topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + 200) {
svgEstatua.start();
}
});
});
$(window).scroll(function () {
$('#section2').each(function () {
var imagePos = $(this).offset().top;
var topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + 225) {
svgBrain.start();
}
});
});
// must 5
array:
var groupSvg = [svgManos, svgSuper, svgInnovation, svgEstatua, svgBrain, svgBalanza];
Take out the common code and do something like this
function common(selector, svgObject, offset) {
$(selector).each(function () {
var imagePos = $(this).offset().top,
topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + offset) {
svgObject.start();
}
});
}
$(window).scroll(function () {
common('#section6', svgEstatua, 200);
});
$(window).scroll(function () {
common('#section2', svgBrain, 225);
});
You can then use your array or an object to loop though.
Related
I want to change the scrollTop to specific section and else to remove class if it surpass the section.
I'm a beginner, any help will be appreciated. Thank you! :)
$(document).on("scroll", function () {
if ($(document).scrollTop() > 5000) {
$(".span-s").addClass("shrink");
} else {
$(".span-s").removeClass("shrink");
}
});
I tried this but the else doesn't remove the class when it surpass the section.
var bottom = $('.construction').offset().top;
$(window).scroll(function () {
if ($(this).scrollTop() > bottom) {
$('.sidebar_list').addClass('shrink');
}
else {
$('.sidebar_list').removeClass('shrink');
}
});
You can check if the element is in viewport
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
$(window).scroll(function () {
if ($('.constructor').isInViewport()) {
$('.sidebar_list').addClass('shrink');
}
else {
$('.sidebar_list').removeClass('shrink');
}
});
I am trying to write this code more efficiently. I've tried about 25 different permutations and it only seems to break it.
Basically, I am adding various classes to elements to trigger a css/keyframes animation when the window width is 1025px or greater.
And then there is another class being adding when it is less than 1024px which is intended to reveal the element without the element.
<script type="text/javascript">
var width = $(window).width();
if(width >= 1025) {
$(window).scroll(function() {
$('#about .image img.flex').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("slideLeft"); }
});
$('#author .image img.flex').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("slideRight"); }
});
$('#feed .blog_01').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("oneUp"); }
});
$('#feed .blog_02').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("twoUp"); }
});
$('#feed .blog_03').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("thrUp"); }
});
$('#feed .more').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+1000) { $(this).addClass("moreUp"); }
});
});
}
else {
$('#about .image img.flex').addClass('visible');
$('#author .image img.flex').addClass('visible');
$('#feed .blog_01').addClass('visible');
$('#feed .blog_02').addClass('visible');
$('#feed .blog_03').addClass('visible');
$('#feed .more').addClass('visible');
}
</script>
EDIT
Maybe it would be better to visualize it like this:
Perhaps it would be better to say how can I make this portion more efficient...
var width = $(window).width();
if(width >= 1025) {
$(window).scroll(function() {
$('#about .image img.flex').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("slideLeft"); }
});
$('#author .image img.flex').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("slideRight"); }
});
$('#feed .blog_01').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("oneUp"); }
});
$('#feed .blog_02').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("twoUp"); }
});
$('#feed .blog_03').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+600) { $(this).addClass("thrUp"); }
});
$('#feed .more').each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
if (position < top+1000) { $(this).addClass("moreUp"); }
});'
#icicleking's answer looks pretty great, but if you need to preserve you addClasses, you could iterate over the important values.
DEMO
var width = $(window).width();
// Make an array of data objects
var data = [
{ el: '#about .image img.flex', plus: 600, newClass: "slideLeft" },
{ el: '#author .image img.flex', plus: 600, newClass: "slideRight" },
{ el: '#feed .blog_01', plus: 600, newClass: "oneUp" },
{ el: '#feed .blog_02', plus: 600, newClass: "twoUp" },
{ el: '#feed .blog_03', plus: 600, newClass: "thrUp" },
{ el: '#feed .more', plus: 1000, newClass: "moreUp" }
];
if(width >= 1025) {
$(window).scroll(function() {
// Loop over the array of data objects
data.forEach(function(d) {
// For each object, target the el attribute for more looping...
$(d.el).each(function() {
var position = $(this).offset().top;
var top = $(window).scrollTop();
// ...use the plus attribute in this condition...
if (position < (top + d.plus)) {
// ...and add the newClass attribute
$(this).addClass(d.newClass); }
});
});
});
} else {
data.forEach(function(d) {
$(d.el).addClass('visible');
});
}
Caveat, triggering animation directly on scroll events is not an efficient way of animating. Others have written much more than I can say about this. When you say "efficient", I'm assuming here that you mean shorter, easier to read.
You could try something like this, sorry I didn't transpose your classes.
$(window).scroll(function() {
var top = $(window).scrollTop();
$('.all, .the, .selectors, .belong, .to, .us').each(function(e) {
var position = $(this).offset().top;
if ($(this).hasClass('.all') && position < top+1000) {
$(this).addClass('.slideThisClass');
}
else if($(this).hasClass('.the') && position < top+600) {
$(this).addClass('.theOtherSlideClass');
}
// etc.
}
}
I have a little problem with the script that I wrote.
Well, for some reason, it not refers to TopDistance which is declared to 850. Just one clicked on the down arrow and the animation starts.
Can you help with this early boot animation?
$(window).on('scroll', function () {
var scrollTop = $(this).scrollTop();
$('.projekt').each(function () {
var topDistance = $(this).offset().top;
if ((topDistance - 850) < scrollTop) {
$(this).addClass("animated fadeInRight");
}
});
});
$(window).on('scroll', function () {
var scrollTop = $(this).scrollTop();
$('.projekt').each(function () {
var topDistance = $(this).offset().top;
if ((topDistance - 850) < scrollTop) {
$(this).removeClass("projekt");
}
});
});
Take a look at this jsfiddle.
I've made one function instead of two and it works.
$(window).on('scroll', function () {
var scrollTop = $(this).scrollTop();
$('.projekt').each(function () {
var topDistance = $(this).offset().top;
if ((topDistance - 850) < scrollTop) {
$(this).addClass("animated fadeInRight").removeClass('projekt');
}
});
});
hi guys so i have this code ive done which when scrolling the sidebar moves up from bottom to top but im stuck with how to stop the scrolling once the sidebar hits the top of the main conatiner - can someone maybe help me with this?
code is:
$(window).bind('scroll', function () {
var scrolledY = $(window).scrollTop();
$('.parallax-sidebar').css('bottom', '+' + ((scrolledY * 1.3)) + 'px');
});
I have a fiddle example here: http://jsfiddle.net/06qwtgt6/1/
Many thanks!
$(document).ready(function () {
/********************************************************************************/
/* Parallax Scrolling */
// Cache the Window object
var $window = $(window);
$('[data-type]').each(function () {
$(this).data('offsetY', parseInt($(this).attr('data-offsetY')));
$(this).data('Xposition', $(this).attr('data-Xposition'));
$(this).data('speed', $(this).attr('data-speed'));
});
// For each element that has a data-type attribute
$('div[data-type="background"]').each(function () {
var $self = $(this),
offsetCoords = $self.offset(),
topOffset = offsetCoords.top;
$(window).bind('scroll', function () {
if (($window.scrollTop() + $window.height()) > (topOffset) &&
((topOffset + $self.height()) > $window.scrollTop())) {
var yPos = -($window.scrollTop() / $self.data('speed'));
if ($self.data('offsetY')) {
yPos += $self.data('offsetY');
}
var coords = '50% ' + yPos + 'px';
$self.css({ backgroundPosition: coords });
};
});
});
// For each element that has a data-type attribute
$('div[data-type="content"]').each(function () {
$(window).bind('scroll', function () {
var scrolledY = $(window).scrollTop();
$('.parallax-content').css('bottom', '+' + ((scrolledY * 1.3)) + 'px');
});
});
$(window).scroll(function(){
if ($(this).scrollTop() > 150) {
$('.sidebar').addClass('fixed');
} else {
$('.sidebar').removeClass('fixed');
}
});
});
CSS
.fixed {position:fixed; top:0;}
DEMO
I have this code so that each element make the scroll effect when done:
I keep repeating the function to each element, the problem that are 30 elements with different classes to add, the code would be very large.
jQuery:
$(window).scroll(function () {
$('.regalos').each(function () {
var imagePos = $(this).offset().top;
var topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + 400) {
$(this).addClass("stretchLeft");
}
});
$('.sprite-Layer-2').each(function () {
var imagePos = $(this).offset().top;
var topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + 400) {
$(this).addClass("slideLeft");
}
});
// ... must 28
});
I would use:
$(window).scroll(function () {
var topOfWindow = $(window).scrollTop();
function _checkOffset(className) {
return function () {
var $this = $(this),
imagePos = $this.offset().top;
$this.toggleClass(className, (imagePos < topOfWindow + 400));
};
}
$('.regalos').each(_checkOffset('stretchLeft'));
$('.sprite-Layer-2').each(_checkOffset('slideLeft'));
});
However, you might be better off re-thinking your structure to avoid adding different class names based on the offset.
You could create a HashMap of Key/Value pairs (key = ID / Class, value = your string inside of .addClass()). However, this would only work if you only had a single class that you wanted to add via addClass for each key that you had.
Or you could have a complex HashMap, where the value was a an array, that you further iterated through if you really wanted to....
You can use something like this, as a global function and you pass array via the items.
var fn = function(args) {
for (var i = 0; i < args.elements.length; i++) {
var el = args.elements[i];
$(el).each(function() {
var imagePos = $(this).offset().top;
var topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + 400) {
$(this).addClass(args.cls);
}
});
}
};
$(window).scroll(function() {
fn({
elements: ['.regalos', '.sprite-layer-2']
cls: 'stretchLeft'
});
});
1st, create the function once:
var myfunction = function(that, whichway) {
var imagePos = $(that).offset().top;
var topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + 400) {
$(that).addClass(whichway); }
};
Then call it as often as you'd like:
$('.regalos').each(myfunction(this, 'stretchLeft'));
$('.sprite-layer-2').each(myfunction(this, 'slideLeft'));
You can pass a list of classes to the jQuery selector.
$(window).scroll(function () {
$('.regalos, .sprite-Layer-2').each(function () {
var imagePos = $(this).offset().top;
var topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + 400) {
$(this).addClass("stretchLeft");
}
});
});
But, I would add one class to all the elements and access them by that.
How about the following, where the key in the rules object is the class to add and the value is the selector for the items to get the class:
var rules = {
"slideLeft": ".sprite-Layer-2",
"stretchLeft": ".regalos",
"someOtherClass" : ".abc, .def, .ghi" // Multiple elements get this class
};
$(window).scroll(function () {
$.each(rules, function( className, selector) {
$(selector).each(function () {
var imagePos = $(this).offset().top;
var topOfWindow = $(window).scrollTop();
if (imagePos < topOfWindow + 400) {
$(this).addClass(className);
}
});
});
});
try the code below:
$(window).scroll(function () {
var topOfWindow = $(window).scrollTop();
$('.regalos').each(function () {
foo(this, 'stretchLeft');
});
$('.sprite-Layer-2').each(function () {
foo(this, 'slideleft');
});
});
function foo(that, classToBeAdded){
var imagePos = $(that).offset().top;
if (imagePos < topOfWindow + 400) {
$(that).addClass(classToBeAdded);
}
}