Why does my JS code act so intermittently? - javascript

The JS code below is meant to get the height of the browser and the height of the .banner div. If the banner height is greater than the browser height, append two divs (.title and .social) to the body otherwise don't do anything and leave .title and .social divs where they are.
I'm also wanting the .title and .social divs to fade out when a user scrolls down the page and fade in when they get back to the top of the page.
The problem
This code does work but not all the time. Sometimes it will display correctly other times it won't. By that I mean the height of div.banner can be greater than the height of the browser window yet .title and .social will not be appended to the body. Is there anything wrong with this code that could cause this issue to occur?
$(document).ready(function () {
// fade in/fade out banner titles
$(window).trigger('scroll');
var divs = $('.social, div.banner .title');
$(window).scroll(function(){
if($(window).scrollTop() < 10){
divs.fadeIn("fast");
} else {
divs.fadeOut("fast");
}
});
// Position feature image title and social icons according to browser window height
var windowHeight = $(window).height(); // Gets browser viewport height
var bannerHeight = $(".banner").height(); // Gets .banner height
if (bannerHeight > windowHeight) {
$("body").append($('.banner .title'));
$("body").append($('.social'));
}
else {
//Display .title and .social in .banner div (as originally in HTML)
}
});
My HTML code that is on page load for reference:
<div class="banner y1">
<div class="title" id="feature-title">
<!-- title content here -->
</div>
<div class="social" id="feature-social">
<!-- social content here -->
</div>
</div>

If height changes on images you should use onload method.
http://api.jquery.com/load-event/

Related

Image fade-in on exposure

How do I fade in an image once it's in view? I'm trying to make my website responsive, so having it fade in on the amount of pixels scrolled won't do. I need it to be exposed depending on the percent scrolled. Or if there's a way to have it fade in when it's in the field of vision?
Here's the code:
$(document).ready(function(){
$(window).bind("scroll", function() {
if ($(this).scrollTop() > 300) {
$("#bluprintdesign").fadeIn();
} else {
$("#bluprintdesign").stop().fadeOut();
}
Right now what I have going on is it fades in when scrolled 300px and fades out if you scroll back up. I like that, but I want it in percentages so it's responsive to all screen resolutions.
Thank you!
Here's a function showImages() that will measure your $.scrollTop() + $(window).height() to establish the scroll point of the bottom of the viewport, and will add a class to hidden images when half of the image has passed the bottom of the viewport. I'm calling it on $(document).ready(); and $(window).on('scroll'); so that it will load images in the viewport on page load and as you scroll.
Using opacity: 0 instead of display: none (what $.fadeIn()/$.fadeOut() will toggle) allows the image to still take up space in the document, allowing you to calculate it's height (needed to know when half of the image is in view) without having to do anything tricky, and will also maintain the page layout when the image fades in, versus the page jumping around if you toggle display.
There are also libraries that will do this for you. jQuery waypoints is a popular one.
function showImages() {
var $window = $(window),
thresh = $window.scrollTop() + $window.height();
$('img:not(.show)').each(function() {
if (thresh > $(this).offset().top + ($(this).outerHeight() / 2)) {
$(this).addClass('show');
}
});
}
$(window).on('scroll', function() {
showImages();
})
$(function() {
showImages();
})
section {
height: 200vh;
border-top: 1px solid black;
}
img {
opacity: 0;
transition: opacity .25s;
}
.show {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<img src="http://kenwheeler.github.io/slick/img/fonz1.png">
</section>
<section>
<img src="http://kenwheeler.github.io/slick/img/fonz1.png">
</section>
<section>
<img src="http://kenwheeler.github.io/slick/img/fonz1.png">
</section>

Div with dynamic header size and content with scroll bar

I am trying to create a container div with a fixed height which has two divs inside, a header div and a content div. The header can grow dynamically and I want the content div to take the rest of the space. The container div should not exceed the specified size and if the content grow to much then content div should scroll.
My current code is as follows but is not working:
<div id="container">
<div id="header">
<button id="btnHeader" type="button">Increase Header</button>MY HEADER</div>
<div id="content">
<button id="btnContent" type="button">Increase Content</button>MY CONTENT</div>
</div>
#container {
height: 300px;
width: 400px;
max-height: 300px;
background-color: grey;
}
#header {
width: 100%;
height: auto;
background-color: blue;
}
#content {
width: 100%;
height: 100%;
overflow-y: scroll;
background-color: red;
}
Example here: http://jsfiddle.net/ep1qab0v/
What is happening is that the content div always stays the same size and hence make the container div to grow. Any ideas?
http://jsfiddle.net/ep1qab0v/3/ ,
I have updated the fiddle with overflow:hidden on the container div. which keeps it the same size. increase in content adds scroll bar to the content div and increase in header pushes the content div down. If I have understood your requirement correctly this is what you are looking for ?
I have made a fiddle with the answer, but I will also try to explain. jsfiddle Example
For that level of dynamic sizing you will have to use javascript. Since the content is scrollable and the header is not, you will have to create an object or function that is called everytime the header size changes. This way you can test the height of the header against the main container, and change the content box to fit.
I created a simple object that you can use to initialize the boxes when the page loads. Also, that you can call every time the page is resized or the header size is changed.
var sizing = {
height: null,
header: null,
content: null,
//Initializes whatever you need
//just cacheing the header and content
//and setting the height restriction
init: function(){
//Set the height of the users window
//you can change this to whatever you want
//but this is dynamic to the browser window
this.height = window.innerHeight ? window.innerHeight : $(window).height();
//Set header and content elements
//for later use
this.header = $('#header');
this.content = $('#content');
this.resize();
},
//Ressize the boxes to fit
//this needs to be called after
// every change to the header
resize: function(){
this.content.css({
height: (this.height - this.header.height()) + "px"
});
}
};
You need to call the .init() to initialize the object when the page loads
$(document).ready(function(){
//Whatever you need to do
//Initialize the sizing
sizing.init();
});
then you can call it from inside events
$('body').on('click', '#some-element', function(e){
//Do some stuff
//Then resize the divs
sizing.resize();
});
Hope that helps!

Bring an element to top of the page even if the page does not scroll

Background:
Let's say you have a simple page which has a logo and a heading only and one paragraph
<img src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
<h1>Foo Bar</h1>
<p>ABC12345</p>
This is how that looks like
That page, obviously would not have vertical overflow / scroll bar for almost even tiny scale mobile devices, let alone computers.
Question
How can you bring that heading to the top left of the screen and move the logo out of focus unless someone scrolls up? Open to using any JavaScript library and any CSS framework
Attempts:
Tried using anchors but they only work if the page already had a scroll bar and anchor was out of focus.
Tried window.scrollTo but that also requires the page to have scroll already
Tried $("html, body").animate({ scrollTop: 90}, 100); but that also doesn't work when the page doesn't have overflow
Notes:
Please note that adding some extra <br/> to induce an overflow is not the way to go, it can be done that way but that's a very ordinary workaround
Why is it needed?
Its for a form for mobile devices, simple requirement is to take the first field of the form to top of the page and hide the logo (one can scroll up if they wish to see it) so it doesn't take attention away. Not using jQueryMobile for this particular task.
If you want the user to be able to scroll up and see the logo, then the logo must be within the top boundary of the body tag, because anything outside of that tag will not be viewable. This means you cannot use negative margins or offsetting like that. The only way to achieve this is to have the page scroll to the desired location that is within the top boundary of the body tag. You can set the time for this event to one millisecond, but there will still be a 'jump' in the page when it is loaded. So, the logic is: first make sure the page is long enough to scroll to the right place, then scroll there.
//Change the jQuery selectors accordingly
//The minimum height of the page must be 100% plus the height of the image
$('body').css('min-height',$(document).height() + $('img').height());
//Then scroll to that location with a one millisecond interval
$('html, body').animate({scrollTop: $('img').height() + 'px'}, 1);
View it here.
Alternatively, you can load the page without the image in the first place. Then your form field will be flush with the top of the document. Then you could create the element at the top and similarly scroll the page again. This is a round-a-bout way of doing the same thing though. And the page will still 'jump,' there is no way around that.
Only CSS and anchor link solution
With a pseudo element :
--- DEMO ---
First :
set : html,body{height:100%;}
Second :
Choose one of your existing tags. This tag mustn't have a relatively positioned parent (except if it is the body tag). Preferably the first element in the markup displayed after the logo. For your example it would be the h1 tag. And give it this CSS :
h1:before {
content:"";
position:absolute;
height:100%;
width:1px;
}
This creates an element as heigh as the viewport area. As it is displayed under the logo, the vertical scroll lenght is the same as the logo height.
Third :
Give the first element after logo an id (for this example I gave id="anchor").
Then you can use a link like this your_page_link#anchor and you will automaticaly scroll to the anchor (logo outside/above the viewport).
This works whatever height the logo is.
link to editable fiddle
Full code :
HTML
<img src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
<h1 id="anchor">Foo Bar</h1>
<p>ABC12345</p> Anchor link
CSS
html, body {
height:100%;
margin:0;
padding:0;
}
h1:before {
content:"";
position:absolute;
width:1px;
left:0;
height:100%;
}
You might need to add js functionality to hide the logo if user scrolls down but I guess following code will fullfill the first requirement.
Please see
<script src="js/jquery.js"></script>
<img id='logo' src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png" style="display:none">
<h1>Foo Bar</h1>
<p>ABC12345</p>
<script type="text/javascript">
var p = $( "p:first" );
var isScrolled=false;
/* For Firfox*/
$('html').on ('DOMMouseScroll', function (e) {
isScrolled = true;
if(p.scrollTop()==0 && isScrolled==true){
$('#logo').css('display','block');
}
});
/* For Chrome, IE, Opera and Safari: */
$('html').on ('mousewheel', function (e) {
isScrolled = true;
if(p.scrollTop()==0 && isScrolled==true){
$('#logo').css('display','block');
}
});
</script>
I have referred this question to find solution.
You could use touchmove event to detect swipe up or down. This is my example. You can try it on mobile device.
<style>
#logo {
position: absolute;
top: -100%;
-webkit-transition: top 0.5s;
-moz-transition: top 0.5s;
-ms-transition: top 0.5s;
-o-transition: top 0.5s;
transition: top 0.5s;
}
#logo.show {
top: 0;
}
</style>
<script>
var perY;
var y;
$(window).on('touchmove', function(e) {
e.preventDefault();
y = window.event.touches[0].pageY;
if(!perY)
perY = y;
else
{
if(y > perY)
$('#logo').addClass('show');
else
$('#logo').removeClass('show');
perY = null;
}
});
</script>
<img id="logo" src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
<h1>Foo Bar</h1>
<p>ABC12345</p>
This is the same problem i've encountered hiding the addressbar without the page overflowing. The only solution that fitted my needs was the following:
Set the min-height of the body to the viewportheight + your logo.
$('body').css('min-height', $(window).height() + 200);
This is a simple solution of getting the height of the contents to see if we can scroll to the part of the header, if not, we add height to the paragraph.
<img id="img" src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png" />
<h1 id="h" >Foo Bar</h1>
<p id="par" style="background:yellow;">
hello world
</p>
script:
function hola(){
var imgH = $("#img").outerHeight(true);
var titleH = $("#h").outerHeight(true);
var winH = $(window).height();
var parH = $('#par').outerHeight(true);
var contH = (imgH + titleH + parH);
var wishH = (imgH + winH);
console.log("wished height: " + wishH);
console.log("window height: " + winH);
console.log("content height: " + contH);
if(contH < wishH){
console.log("window is smaller than desired :(");
var newH = wishH - contH;
$("#par").height(parH + newH);
$(window).scrollTop(imgH);
}
}
Here is the working example:
http://jsfiddle.net/Uup62/1/
You may like this solution: http://jsfiddle.net/jy8pT/1/
HTML:
<div class="addScroll"></div>
<h1 class="logo"><img src="https://drupal.org/files/images/OQAAAI1PPrJY0nBALB7mkvju3mkQXqLmzMhxEjeb4gp8aujEUQcLfLyy-Sn4gZdkAas6-k8eYbQlGDE-GCjKfF5gIrUA15jOjFfLRv77VBd5t-WfZURdP9V3PdmT.png" height="100" alt="company logo"/></h1>
<h2>This is a sample page heading.</h2>
<p>This is a sample page text.</p>
JS:
function addScroll()
{
$(".addScroll").css({
"height": ($(window).height()+1) + "px",
"width": "100%"
});
}
$(document).ready(function(){
addScroll();
$(window).resize(function(){
addScroll();
});
$(window).scroll(function(){
if($(window).scrollTop() > 0)
{
$(".logo").animate({
marginTop: "-110px"
}, 500);
}
if($(window).scrollTop() == 0)
{
$(".logo").animate({
marginTop: "0"
}, 500);
}
});
});
CSS:
body
{
padding:0;
margin:0;
}
h1.logo
{
display:block;
margin:0 0 10px 0;
padding:0;
outline:0;
}
.addScroll
{
position:absolute;
display:block;
top:0;
left:0;
z-index:-1;
}

Fixed position element pushed out of relative position element?

So i have the following HTML markup;
<div id ="page_shadow">
<div id="blog_content">
<div id="main_content_container>
Main Content
</div>
<div id="swrapper">
<div id="blog_sidebar">
Sidebar Content
</div>
</div>
</div>
</div>
The following CSS;
#blog_sidebar.fixed {
position: fixed;
top: 0;
}
#swrapper {
position:absolute;
right:0;
}
#blog_sidebar {
width: 330px;
padding:10px;
padding-top:25px;
height:auto;
}
#main_content_container {
width:600px;
float:left;
height:auto;
padding-bottom:15px;
}
#blog_content {
position:relative;
width:960px;
margin-left:auto;
margin-right:auto;
min-height:1300px;
height:auto;
background:#FFFFFF;
z-index:5;
}
#page_shadow {
background:url('../images/background_shadow.png') top center no-repeat;
padding:10px;
margin-top:-60px;
}
The following javascript;
<script>
$(document).ready(function(){
var top = $('#blog_sidebar').offset().top - parseFloat($('#blog_sidebar').css('marginTop').replace(/auto/, 0));
var bottom = $('#blog_content').position().top+$('#blog_content').outerHeight(true) - $('#blog_sidebar').height() - 35;
$(window).scroll(function (event) {
// what the y position of the scroll is
var y = $(this).scrollTop();
// whether that's below the form
if (y >= top) { //&& y <= bottom
// if so, ad the fixed class
$('#blog_sidebar').addClass('fixed');
} else {
// otherwise remove it
$('#blog_sidebar').removeClass('fixed');
}
});
});
</script>
Ok so basically there are two scenarios which occur. IF the page is loaded with the browser viewport above the y position before #blog_sidebar's position is changed to fixed then the element stays within the blog_content container.
HOWEVER, if the page is loaded with if (y >= top) = True resulting in $('#blog_sidebar').addClass('fixed'); the element is then pushed outside the blog_content container.
Again this only occurs if the viewport is = or below the trigger when the page is loaded.
For example if i were to go half way down the page and then click for the page to refresh, the browser loads the page and the element and then jumps to the position it was previously. The fixed position element shown up in the correct position for a split second and then jumps outside #blog_content aligning with the left of the element.
Ive got a little example to show the basics of the layout etc, but i dont think i can show exactly whats happening within jsfiddle. http://jsfiddle.net/ce3V3/
TLDR
Since this is quite confusing. Short version is i am changing a static positioned element with a fixed position element within the DOM, which is resulting in the fixed positioned element being out of place if the window is refreshed and jumps past a certain point. I dont want the fixed position element to jump out of place if a user relaods the page and the window jumps halfway down the page.

How to get the div top position value while scrolling

I am trying to run some script when div reaches to a certain point when it's scrolled. There is a fixed navigation and when the user scrolls the window it suppose change the nav name once it reaches close to the nav. I am using the $(window).scroll function but it only checking the div position once and not updating the value. How to make scroll check the window size every 5-10 px move so that it doesn't take too much memory/processing.
The code is set up at: http://jsfiddle.net/rexonms/hyMxq/
HTML
<div id="nav"> NAVIGATION
<div class="message">div name</div>
</div>
<div id="main">
<div id="a">Div A</div>
<div id ="b"> Div B</div>
<div id ="c"> Div C</div>
</div>​
CSS
#nav {
height: 50px;
background-color: #999;
position:fixed;
top:0;
width:100%;
}
#main{
margin-top:55px;
}
#a, #b, #c {
height:300px;
background-color:#ddd;
margin-bottom:2px;
}
SCRIPT
$(window).scroll(function() {
var b = $('#b').position();
$('.message').text(b.top);
if (b.top == 55) {
$('.message').text("Div B");
}
});​
Try this jsFiddle example
$(window).scroll(function() {
var scrollTop = $(window).scrollTop(),
divOffset = $('#b').offset().top,
dist = (divOffset - scrollTop);
$('.message').text(dist);
if (b.top == 55) {
$('.message').text("Div B");
}
});​
Your original code was only checking the position of the div relative to the top of the document which never changes. You need to calculate in the amount of scroll the window has incurred and calculate accordingly.
Also note the difference beyween jQuery's .position() and .offset() methods. The .position() method allows us to retrieve the current position of an element relative to the offset parent. Contrast this with .offset(), which retrieves the current position relative to the document.

Categories

Resources