I have some gif images on my website that I want to animate once you scroll to that part of the page. I have some JavaScript code that hides those gifs then shows them once you get to that part of the page. The issue I am having is that those gifs start animating before I scroll to that part of the page. Another issue I am having is that once I refresh the page the gifs will sometimes animate, but I would like them to animate each time the page gets refreshed.
Here is the link to my website: http://lam-parker.github.io/my_portfolio_website/
This isn't all of the gifs but here's is the portion of my html where my gifs are:
<div class="row4">
<h1 id="title3">Software Skills</h1>
<div class="col-md-2 col-sm-4 col-xs-6">
<img src="img/software-skills/photoshop.gif">
</div>
<div class="col-md-2 col-sm-4 col-xs-6">
<img src="img/software-skills/indesign.gif">
</div>
</div>
Here is the .show()/.hide() JavaScript I added to the gifs section:
$(window).scroll(function() {
if ($(window).scrollTop() > 70) {
$('.row4').show("slow");
} else {
$('.row4').hide();
}
});
I would appreciate it if someone could help me. Thanks in advance.
I think the only way to 'control' them would be to reassign the src attribute :
Demo
img {
opacity: 0;
}
$(window).scroll(function() {
var current = $(this).scrollTop(),
path = 'animated.gif',
visible = $('img').css('opacity') != 0;
if (current > 200) {
if (!visible) $('img').attr('src', path).fadeTo(400,1);
}
else if (visible) $('img').fadeTo(0,0);
});
Update - by request some code that makes it possible to loop through all animated gifs :
Pen
$(function() {
var target = $('.anigif'),
path = [], zenith, nadir, current,
modern = window.requestAnimationFrame;
target.each(function() {
path.push(this.src);
});
$(window).on('load resize', storeDimensions).on('load scroll', function(e) {
current = $(this).scrollTop();
if (e.type == 'load') setTimeout(inMotion, 150);
else inMotion();
function inMotion() {
if (modern) requestAnimationFrame(checkFade);
else checkFade();
}
});
function storeDimensions() {
clearTimeout(redraw);
var redraw = setTimeout(function() {
zenith = []; nadir = [];
target.each(function() {
var placement = $(this).offset().top;
zenith.push(placement-$(window).height());
nadir.push(placement+$(this).outerHeight());
});
}, 150);
}
function checkFade() {
target.each(function(i) {
var initiated = $(this).hasClass('active');
if (current > zenith[i] && current < nadir[i]) {
if (!initiated) $(this).attr('src', path[i]).addClass('active').fadeTo(500,1);
}
else if (initiated) $(this).removeClass('active').fadeTo(0,0);
});
}
});
It will reinitiate them when they come into view (bottom and top) and fade them out when leaving the screen. All it needs is for the animated gifs to have a common class, assigned to the variable target. If the page contains only gifs and no other <img> tags you could even use $('img') and leave out the class. Looks like quite a bit of code but it has some debouncing and other optimisation.
B-)
You need to use CSS opacity 1 or 0 to show or hide your element. That is only way from "old-school". Second thing is to use relative position and move out of screen. Also you can resize image from original size to 1x1px to original size but that is a bad way.
Related
I'm currently making an element visible when my nav is at the top of the page. I'd like the element to be hidden if the page gets to max-width: 900px;. I've tried using modernizer for JS media queries but I ca't seem to get it to work.
Code:
var a = $(".menu").offset().top;
function scrollListener(){
if($(document).scrollTop() > a)
{$('.hidden-logo').css({"opacity": "1","display": "block"});
$('.menu').css({"margin-left": "-130px"})
} else {
$('.hidden-logo').css({"opacity": "0","display": "none"});
$('.menu').css({"margin-left": "0px"})
}
};
$(document).scroll(scrollListener);
You were checking the scroll position the wrong way - I think you want the logo to disappear when the current scroll is greater than the top of the logo, not less.
I added a msgS div (for demo purposes only) that will show you the current scroll value against the top-of-menu static value. I also added a 100px fudge factor to the menu location to make it more clear in the demo when the current scroll reaches that position. I use these temporary msg divs myself when working out my code, and then remove them when I've got it all sorted and ready for production.
And this is all you need to check the media query in javascript:
var winmed = window.matchMedia("(max-width: 700px)");
if (winmed.matches){ //do something }
And that can go into a listener function exactly like your scroll listener.
var gloShowLogo = true;
var a = $(".menu").offset().top;
var fudge = 100; //100px fudge factor so can SEE div disappear
function scrollListener(){
updateScrollMsg();
var currScroll = $(document).scrollTop();
var topOfMenu = a+fudge;
if( gloShowLogo && currScroll < topOfMenu ){
$('.hidden-logo').css({"opacity": "1","display": "block"});
$('.menu').css({"margin-left": "-130px"})
} else {
$('.hidden-logo').css({"opacity": "0","display": "none"});
$('.menu').css({"margin-left": "0px"})
}
};
function resizeListener(){
updateMediaMsg();
var winmed = window.matchMedia("(max-width: 500px)");
if (winmed.matches){
$('.hidden-logo').css({"opacity": "1","display": "block"});
gloShowLogo = true;
} else {
$('.hidden-logo').css({"opacity": "0","display": "none"});
gloShowLogo = false;
}
}
$(window).scroll(scrollListener);
$(window).resize(resizeListener);
function updateScrollMsg(){
$('#msgS').html( $(document).scrollTop() +' // ' + $(".menu").offset().top );
}
function updateMediaMsg(){
var winmed = window.matchMedia("(max-width: 500px)");
var medmsg = (winmed.matches) ? '< 500' : '> 500';
console.log(medmsg);
$('#msgM').html(medmsg);
}
.menu{background:green;text-align:center;}
.content{height:200vh;background:palegreen;text-align:center;}
.hidden-logo{position:fixed;top:1vh;right:1vw;padding:15px; background:pink;z-index:2;}
#msgS{position:fixed;top:0;left:0;padding:10px;background:wheat;z-index:2;}
#msgM{position:fixed;top:40px;left:0;padding:10px;background:lightblue;z-index:2;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div class="menu">Menu Div</div>
<div class="content">Lengthy content Div..<br><br><br><br>100<br></div>
<div class="hidden-logo">LOGO</div>
<div id="msgS"></div>
<div id="msgM"></div>
Update:
Sorry, I had the media query a bit backwards myself - I think you want the logo to display when the screen-size is < 900px and to be hidden if wider than 900px, yes?
I added a msgM div so you can watch the media query kick-in -- but getting the best width for the demo was a bit of a challenge. I finally settled at 500px as a width that can be demoed (StackOverflow resizes its StackSnippets container as the browser window resizes, which throws things into confusion at each of their resize breakpoints)
I have taken a reference of the below site and i want to add text effects ie opacity gets fade on page scroll. The above code is working properly if i use the below reference as it is but if i add many div then it gets faded early not reaching the required div
http://jsfiddle.net/HsRpT/134/
Here is what i have done and the text fade effects goes early without reaching the actual div. Is there any other way of solving this problem?
<div>
fsdfdfsdfffffffffff<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>><br><br><br>
</div>
<div class="block">
<h2>Fade this in / out as scroll down</h2>
</div>
<div class="content">
<div class="headerbar">
</div>
</div>
Try
$(window).scroll(function() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (scrollTop > 200) {
$('.block').stop(true, true).fadeOut();
}
else {
$('.block').stop(true, true).fadeIn('fast');
}
});
Fiddle
current_div="div1";
$(window).scroll(function() {
current_div = scroll_content();
console.log(current_div);
if(current_div=="last"){
don't fade out
}
});
function scroll_content(){
var winTop = $(this).scrollTop();
var $divs = $('section');
var top = $.grep($divs, function(item) {
return $(item).position().top <= winTop;
});
var cur=top[top.length - 1];
return $(cur).attr('id');
}
You can get the the id of the div which is going out of screen while scrolling. So you can do what ever you want to do with the divs after getting the id .
It worked for me.
Let me know if you any other query.
I'm currently trying to change my header logo when the user scrolls past the dark background to a lighter background. I got the add/remove class working, but right when the user loads the page the image doesn't show because it executes when the scroll is greater than 0 pixels scroll. How do I show the initial conditions from page load without the user having scrolled already?
$(function() {
var header = $(".logo");
var about = $(".angle").offset().top;;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= about) {
header.removeClass('lightLogo').addClass('darkLogo');
} else {
header.removeClass('darkLogo').addClass('lightLogo');
}
});
});
The simplest might be to just add the class initially, like so:
$(function() {
var header = $(".logo").addClass('lightLogo');
var about = $(".angle").offset().top;;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= about) {
header.removeClass('lightLogo').addClass('darkLogo');
} else {
header.removeClass('darkLogo').addClass('lightLogo');
}
});
});
Now the header will start out with .lightLogo at page load.
I have a responsive site that has an image slider that the user can look through.
Here is the link to that slider:
http://firehousecoffeeco.com
I was able to get the slideshow to return to the first slide when they click the "right" button on the last slide, without the right edge of the last slide ever coming too far into the window. This is done by checking the viewport width against the container div's width (see the left button's click handler below).
My question is: How do I make it so that the same thing that is happening with the last slide happens with the first slide. (no matter what, I never want the container's left edge to go above 0px). I tried to do the same with the first slide as with the last, but it didnt' work, please see below:
Here is the markup of the slider:
<section id="photoGallery">
<div id="slides">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
<!--left and right buttons-->
<div id="left" data-dir="left"></div>
<div id="right" data-dir="right"></div>
</section>
The container div is "slides" and it is what is being moved.
Here is my script's click handlers and transition function:
//click handlers
leftButton.on('click', function(){
var viewport = $(window).width();
var slidesContainerLeftEdge = $('#slides').get(0).getBoundingClientRect().left;
var slidesContainer = $('#slides').width();
if (slidesContainerLeftEdge == 0) { //if on first image (this is not working, help!)
slides.animate({marginLeft: ""+-(slideShowLimiter * 320)+"px"}, 200);
console.log("working");
} else {
transition("+=");
}
});
rightButton.on('click', function(){
var viewport = $(window).width();
var slidesContainerEdge = $('#slides').get(0).getBoundingClientRect().right;
var slidesContainer = $('#slides').width();
if (slidesContainerEdge < viewport + 320) { //if last slide
slides.animate({marginLeft:"0px"}, 200);
} else {
transition("-=");
}
});
function transition(direction) {
slides.animate({marginLeft: ""+direction+""+movement+"px"}, 200);
}
Hopefully you guys can help me out of a jam. Thanks in advance!
if(0 >=slidesContainerLeftEdge > -320){ // if first slide
slides.animate({marginLeft: ($(window).width()-$('#slides').width())+"px"}, 200);
}else{
//...
}
Just to follow the logic here you used for the rightClick, so when it's the first slide on the left, you'll move the slides to the left (by setting the margin-left) so its right matches the right of the window.
See Full Code:
leftButton.on('click', function(){
var viewport = $(window).width();
var slidesContainerLeftEdge = $('#slides').get(0).getBoundingClientRect().left;
var slidesContainer = $('#slides').width();
if (0 >=slidesContainerLeftEdge > -320) {
slides.animate({marginLeft: (viewport-slidesContainer)+"px"}, 200);
} else {
transition("+=");
}
});
I'm working on a website for a family friend. On it they wanted to have logos from all their associates on one row, that subtly fade to get replaced with additional logos that didn't fit the first time.
To achieve this i've assigned the <img>'s classes, that represent what cycle they should appear in, depending on how many of those images will fit on the row given its current width. This happens in my assignCycleNumbers function.
Then to actually fade them in and out i have another function called cycleAssociates which recursively fades the appropriate classes in and out. Well in theory, however it doesn't seem to be working properly, which is particularly odd because i tested the function here and it works fine. The only difference between them is that now i'm trying to assign the cycle numbers dynamically.
I'm really stumped and could do with some help!
You can see the website hosted here and if you scroll down to the bottom of the content you'll see the logos at the bottom, not behaving as expected. (First cycle appears okay but then subsequent cycles get muddled, more observable if you resize to a smaller screen width).
You can inspect the code thoroughly through your browser but here's everything you need to know, again i'd really appreciate any insight.
EDIT: The whole javascript file as requested. But all the relevant stuff is below:
JS:
//single global variable to represent how many logo cycles there is
var totalCycles = 0;
...
$(window).load(function() {
...
totalCycles = assignCycleNumbers();
cycleAssociates();
});
// window is resized
$(function(){
$(window).resize(function() {
...
totalCycles = assignCycleNumbers();
});
});
...
function cycleAssociates(){
var cycle = 0;
var recursiveCycling = function(cycle, totalCycles){
var currentAssociate = ".cycle" + cycle;
//fade in all img with the current cyle class over a second,
//wait 3 seconds before fading out over a second.
$(currentAssociate).delay(100).fadeIn(1000).delay(3000).fadeOut(1000,
function(){
cycle++;
if(cycle > totalCycles){
cycle = 0;
}
recursiveCycling(cycle, totalCycles);
});
};
recursiveCycling(cycle, totalCycles);
}
function assignCycleNumbers(){
//first remove any old cycle# classes (resized window case)
$('[class*="cycle"]').removeClass( function(unusedIdx,c){
return c.match(/cycle\d+/g).join(" ");
});
//measure div width
var divSpace = $("#bodies").innerWidth();
//assign a cycle number to a number of logos until no more will fit in that div
var cycleNum = 0;
$(".associate").each(function(){
if( divSpace - $(this).width() > 0){
$(this).addClass("cycle" + cycleNum);
divSpace = divSpace - $(this).width();
}
else{ //next logo won't fit current cycle, create next cycle
cycleNum++
$(this).addClass("cycle" + cycleNum);
divSpace = $("#bodies").innerWidth() - $(this).width();
}
});
return cycleNum;
}
html:
<img class="associate" src="IMG/spare.png" alt=""/>
<img class="associate" src="IMG/bcs_professional.jpg" alt="BCS Professional Member"/>
<img class="associate" src="IMG/climate_savers.jpg" alt="Climate Savers Smart Computing"/>
<img class="associate" src="IMG/code_of_conduct.jpg" alt="Data Centres Code Of Conduct Endorser"/>
<img class="associate" src="IMG/spare.gif" alt=""/>
<img class="associate" src="IMG/enistic.gif" alt="Enistic"/>
<img class="associate" src="IMG/greentrac_authorised.png" alt="Greentrac Authorised Reseller"/>
<img class="associate" src="IMG/very_pc.jpg" alt="Very PC Approved"/>
<img class="associate" src="IMG/spare.jpg" alt=""/>
css:
#bodies img.associate{
float: left;
max-width: 120px;
max-height: 80px;
display:none;
}
The issue is that your fadeOut function's callback is being executed even before all elements in the current cycle are faded out. Here's a modified version of your function that works as expected:
function cycleAssociates(){
var cycle = 0;
var recursiveCycling = function(cycle, totalCycles){
var currentAssociate = ".cycle" + cycle;
var n = $(currentAssociate).length; //How many images in current cycle?
$(currentAssociate).each(function() {
$(this).delay(100).fadeIn(1000).delay(3000).fadeOut(1000, function() {
n --;
if(n <= 0) { //current cycle done?
cycle++;
if(cycle > totalCycles){
cycle = 0;
}
recursiveCycling(cycle, totalCycles);
}
});
});
};
recursiveCycling(cycle, totalCycles);
}
To fix the issues that come up on window resize, try replacing your current $(window).resize handler with this:
$(function(){
$(window).resize(function() {
parallelNavbar();
$(".associate").stop(); //if there are any animations, stop 'em
$(".associate").hide(); //hide all associates
totalCycles = assignCycleNumbers(); //update the assignment
cycleAssociates(); //let's get cyclin' again!
});
});
Although I think you have some issues with scrolling. This should resolve the main cycling problem, though -- so I hope that helped!