Why is this slideUp function not smooth? - javascript

I want to implement a vanilla JS version of the jQuery slideUp()and slideDown() function.
My idea was to use CSS transition for the height property together with incrementing/decrementing the height using requestAnimationFrame().
I tried it with the following code, and slideDown is working as expected, but slideUp is not smoothly collapsing, instead, it is just suddenly gone.
Here is how it looks:
Here is a jsfiddle.
function toggleSlide(element) {
// Check if the element is currently visible
if (element.style.display== '' || element.style.display== 'none') {
// If the element is not visible, slide it down
slideDown(element);
} else {
// If the element is visible, slide it up
slideUp(element);
}
}
function slideDown(element) {
// If the element is not visible, set the display and height properties
if (element.style.display !== 'block') {
element.style.display = 'block';
element.style.height = 0;
}
// Get the height of the element's content
const contentHeight = element.scrollHeight;
// Set a variable to keep track of the element's height
let currentHeight = 0;
// Start an animation loop
function animate() {
// Increase the element's height by 10px
currentHeight += 10;
// Update the element's height
element.style.height = `${currentHeight}px`;
// If the element's height is less than the content height, request another animation frame
if (currentHeight < contentHeight) {
requestAnimationFrame(animate);
}
}
// Start the animation
animate();
}
function slideUp(element) {
// Get the height of the element's content
const contentHeight = element.scrollHeight;
// Set a variable to keep track of the element's height
let currentHeight = contentHeight;
// Start an animation loop
function animate() {
// Decrease the element's height by 10px
currentHeight -= 10;
// Update the element's height
element.style.height = `${currentHeight}px`;
// If the element's height is greater than 0, request another animation frame
if (currentHeight > 0) {
requestAnimationFrame(animate);
} else {
// If the animation is complete, hide the element
element.style.display = 'none';
}
}
// Start the animation
animate();
}
.my-element {
background-color: #ddd;
transition: height 0.5s;
overflow: hidden;
display:none;
}
<button onclick="toggleSlide(document.querySelector('.my-element'))">Slide Down</button>
<!-- Create the element that we will slide down -->
<div class="my-element">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In et tellus in quam convallis dictum. Maecenas eget odio eget arcu accumsan porttitor. Ut elementum volutpat orci, sed tincidunt ipsum dictum at. Maecenas auctor tempus diam quis gravida. Aliquam at ultricies leo. Etiam euismod, nisi ac blandit placerat, diam turpis vestibulum diam, at ultricies turpis orci at elit. Mauris auctor dictum dolor, quis pretium nisi ultricies in. Aenean sollicitudin, quam non euismod porta, enim nisl laoreet velit, vel venenatis dui dui vel lacus. Aliquam erat volutpat. Donec et elit ut ipsum elementum volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent a nisi at est eleifend ullamcorper. Aenean porta, erat ac sagittis fermentum, leo magna tincidunt lectus, ac semper risus est et diam. Suspendisse auctor ipsum quam, id porta dui dictum sed. Vivamus ac diam non elit placerat iaculis vel at velit. Aliquam vel tincidunt velit. Duis imperdiet, dolor eu placerat luctus, ipsum quam laoreet dui, non suscipit nulla tellus et arcu. Donec dictum, massa non bibendum varius, leo urna condimentum diam, nec suscipit elit turpis vel turpis. Aenean ac nunc quis nisl tempus tincidunt a eu metus.</p>
</div>
Why is slideUp not collapsing smoothly?

The CSS Transition is the one taking effect before the toggle animation ends. Removing it solves the issue since your functions are taking care of the animating durations
function toggleSlide(element) {
// Check if the element is currently visible
if (element.style.display== '' || element.style.display== 'none') {
// If the element is not visible, slide it down
slideDown(element);
} else {
// If the element is visible, slide it up
slideUp(element);
}
}
function slideDown(element) {
// If the element is not visible, set the display and height properties
if (element.style.display !== 'block') {
element.style.display = 'block';
element.style.height = 0;
}
// Get the height of the element's content
const contentHeight = element.scrollHeight;
// Set a variable to keep track of the element's height
let currentHeight = 0;
// Start an animation loop
function animate() {
// Increase the element's height by 10px
currentHeight += 10;
// Update the element's height
element.style.height = `${currentHeight}px`;
// If the element's height is less than the content height, request another animation frame
if (currentHeight < contentHeight) {
requestAnimationFrame(animate);
}
}
// Start the animation
animate();
}
function slideUp(element) {
// Get the height of the element's content
const contentHeight = element.scrollHeight;
// Set a variable to keep track of the element's height
let currentHeight = contentHeight;
// Start an animation loop
function animate() {
// Decrease the element's height by 10px
currentHeight -= 10;
// Update the element's height
element.style.height = `${currentHeight}px`;
// If the element's height is greater than 0, request another animation frame
if (currentHeight > 0) {
requestAnimationFrame(animate);
} else {
// If the animation is complete, hide the element
element.style.display = 'none';
}
}
// Start the animation
animate();
}
.my-element {
background-color: #ddd;
/* Remove the transition */
overflow: hidden;
display:none;
}
<button onclick="toggleSlide(document.querySelector('.my-element'))">Slide Down</button>
<!-- Create the element that we will slide down -->
<div class="my-element">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In et tellus in quam convallis dictum. Maecenas eget odio eget arcu accumsan porttitor. Ut elementum volutpat orci, sed tincidunt ipsum dictum at. Maecenas auctor tempus diam quis gravida. Aliquam at ultricies leo. Etiam euismod, nisi ac blandit placerat, diam turpis vestibulum diam, at ultricies turpis orci at elit. Mauris auctor dictum dolor, quis pretium nisi ultricies in. Aenean sollicitudin, quam non euismod porta, enim nisl laoreet velit, vel venenatis dui dui vel lacus. Aliquam erat volutpat. Donec et elit ut ipsum elementum volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent a nisi at est eleifend ullamcorper. Aenean porta, erat ac sagittis fermentum, leo magna tincidunt lectus, ac semper risus est et diam. Suspendisse auctor ipsum quam, id porta dui dictum sed. Vivamus ac diam non elit placerat iaculis vel at velit. Aliquam vel tincidunt velit. Duis imperdiet, dolor eu placerat luctus, ipsum quam laoreet dui, non suscipit nulla tellus et arcu. Donec dictum, massa non bibendum varius, leo urna condimentum diam, nec suscipit elit turpis vel turpis. Aenean ac nunc quis nisl tempus tincidunt a eu metus.</p>
</div>

As Barmar stated, one should either use requestAnimationFrame() or CSS transitions. Cypherjac represents the solution of just using requestAnimationFrame() here comes the alternative CSS transitions solution:
See jsfiddle or
const button = document.querySelector('button')
button.addEventListener('click', (e) => {
const container = document.querySelector('div');
const active = container.style.height !== '' && container.style.height !== '0px';
if(active){
container.style.height = "0px"
container.addEventListener('transitionend', () => {
container.style.display = 'none';
}, {once: true})
return;
}
container.style.display = 'block';
container.style.height = "auto"
const height = container.clientHeight + "px"
container.style.height = "0px"
setTimeout(() => {
container.style.height = height
}, 0)
})
.box {
transition: height .5s ease;
overflow : hidden;
height:0;
}
<div class="box">
I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element.
</div>
<button>Slide Toggle</button>
The part with setting display to none/block could be omitted. Only added, as I assume for most scenarios, its useful to have it completly removed from flow when toggled.
The addEventListener:transitioned is necessary, so the display is set after the height has been changed to 0 and CSS transition has taken place.
The setTimeout is necessary, because otherwise, the height would be directly set to height and CSS would not get the change to animate.

Related

Collapsed div flashing when closed

$("#my-container")
.each(function() {
var ol = document.createElement("ol");
ol.setAttribute("id", "anchor-navlist");
$("#anchor-navigation").append(ol);
var h2 = $("h2", ".node__content");
h2.each(function() {
var text = $(this).text();
var addId = text.replace(/\s/g, "-");
$(this).attr("id", addId);
$(this).attr("class", "anchor");
$("<li/>")
.append(
$("<a />", {
text: text,
href: "#" + text.replace(/\s/g, "-")
})
)
.appendTo("ol#anchor-navlist");
});
$("#anchor-navigation .heading, #anchor-navlist li a").click(function() {
if ($("#anchor-navigation").hasClass("closed")) {
$("#anchor-navigation").removeClass("closed");
} else {
$("#anchor-navigation").addClass("closed");
}
});
});
function handleScroll() {
var windowTop = $(window).scrollTop();
if (scrolling) return;
if (windowTop > 50) {
$("#anchor-navigation").addClass("closed");
scrolling = true;
setTimeout(function() {
scrolling = false;
$("#anchor-navigation").removeClass("closed");
}, 2000);
}
}
var scrolling = false;
$(window).scroll(handleScroll);
#my-container #anchor-navigation {
max-width: 942px;
margin: 0 auto;
position: sticky;
top: 10px;
background: #e8e8e8;
padding: 10px;
z-index: 100;
}
#my-container #anchor-navigation .heading {
cursor: pointer;
}
#my-container #anchor-navigation .heading h2 {
font-size: 20px;
margin-top: 5px;
margin-bottom: 5px;
}
#my-container #anchor-navigation ol {
margin-bottom: 0;
}
#my-container #anchor-navigation.closed ol {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<article id="my-container">
<div id="anchor-navigation" class="">
<div class="heading">
<h2>Explore this page</h2>
</div>
</div>
<div class="node__content">
<h2 id="Heading-1" class="anchor">Heading 1</h2>
<p>Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Cras ultricies ligula sed magna dictum porta. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus.
Curabitur arcu erat, accumsan id imperdiet et, porttitor at sem.</p>
<h2 id="Heading-2" class="anchor">Heading 2</h2>
<p>Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Vivamus suscipit tortor eget felis porttitor volutpat. Cras ultricies ligula sed magna dictum porta. Vestibulum ac
diam sit amet quam vehicula elementum sed sit amet dui.</p>
<h2 id="Heading-3" class="anchor">Heading 3</h2>
<p>Vivamus suscipit tortor eget felis porttitor volutpat. Curabitur aliquet quam id dui posuere blandit. Quisque velit nisi, pretium ut lacinia in, elementum id enim. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Nulla porttitor
accumsan tincidunt.</p>
<h2 id="Heading-4" class="anchor">Heading 4</h2>
<p>Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Nulla porttitor accumsan tincidunt. Donec rutrum congue leo eget malesuada. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Vivamus magna justo, lacinia
eget consectetur sed, convallis at tellus.</p>
</div>
</article>
I am trying to create a floating nav at the top of my page containing anchor links to the content in the page.
The nav will be open on page load and will close on scroll down the page > 200 and reopen when scroll back to top. The nav will also open or close based on click.
Currently if I scroll the nav it will close, clicks are also working. However, if I scroll and then click outside the window or focus on devtools, for example there is a flash of the closed menu on the screen. I believe it is being caused my timeout function.
The opening and closing of the div is being controlled by adding/removing a class "closed" on a given selector. I can see in inspector that the class is being removed on scroll but the timeout is then trying to re-add it each time and so causing the flash (but only when the window is blurred?), I believe that it shouldn't be doing this because it will hit the return first.
Try to use clearTimeout. It's possible that clicking to expand won't work - replacing the sticky position with fixed could solve this.
var timeout;
function handleScroll(event) {
clearTimeout(timeout);
timeout = setTimeout(function () {
var windowTop = $(window).scrollTop();
if (windowTop > 200) {
$("#anchor-navigation").removeClass("closed");
} else {
$("#anchor-navigation").addClass("closed");
}
}, 100);
}
$(window).scroll(handleScroll);

how to set a variable based on screen height

Using the code below a video plays as the user scrolls down the page. this creates an issue because i am using content blocks that are 100vh. When the window gets taller, the video is no longer playing at the speed and duration to line up with each html content block that plays over it.
How do I change the the variable playbackConst based on screen height?
enterView({
selector: '.home-slide',
enter: function(el) {
el.classList.add('entered');
},
exit: function(el) {
el.classList.remove('entered');
},
})
var frameNumber = 0, // start video at frame 0
// lower numbers = faster playback
playbackConst = 900,
// select video element
vid = document.getElementById('v0');
// var vid = $('#v0')[0]; // jquery option
// Use requestAnimationFrame for smooth playback
function scrollPlay() {
var scrollTop = document.querySelector(".home-slider-container").scrollTop;
var frameNumber = scrollTop / playbackConst;
vid.currentTime = frameNumber;
window.requestAnimationFrame(scrollPlay);
}
window.requestAnimationFrame(scrollPlay);
If you use your playbackConst as a ratio of the scrollTop / screenHeight, you can adjust it manually at a random screen size, and it should work the same at different sizes.
A ratio of 1 means that 1 second of video will play when scrolling by 100vh, a ratio of 1.5 means that 1.5 seconds will play when scrolling by 100vh, etc.
Demo:
var frameNumber = 0,
playbackConst = 1,
vid = document.getElementById('v0'),
homeSliderContainer = document.querySelector(".home-slider-container");
function scrollPlay() {
var scrollTop = homeSliderContainer.scrollTop,
screenHeight = window.innerHeight,
frameNumber = (scrollTop / screenHeight) * playbackConst;
vid.currentTime = frameNumber;
window.requestAnimationFrame(scrollPlay);
}
window.requestAnimationFrame(scrollPlay);
* { box-sizing: border-box; }
body { margin: 0; padding: 0; background: #222; }
#v0, .home-slider-container {
position: fixed;
width: 100%;
height: 100%;
}
.home-slider-container {
overflow: auto;
background: rgba(0,0,0,.4);
color: #fff;
font-family: Arial, Helvetica, sans-serif;
padding: .5em 2em;
}
<video id="v0">
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
<source src="https://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg">
</video>
<div class="home-slider-container">
<h1>Hello, world</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sodales sit amet mauris nec vulputate. Aliquam erat volutpat.</p><p>Suspendisse orci sem, iaculis sed ullamcorper non, vehicula vitae nisl. Phasellus vestibulum scelerisque lacinia. Ut a nisl dictum, cursus sem eget, dignissim eros. Maecenas eget dolor eget augue luctus cursus. </p><p>Sed faucibus pulvinar tincidunt. Donec a dolor elementum, lobortis est vel, blandit velit. </p><h1>Hello world, again</h1><p>Quisque facilisis tortor iaculis arcu dignissim, quis consectetur neque blandit. Pellentesque malesuada odio imperdiet velit ullamcorper, sit amet porta justo maximus. Aenean accumsan, tortor eget.</p><p>Scelerisque varius, nunc tellus malesuada lacus, ut interdum metus ante eu orci. Nullam porttitor vel neque vitae faucibus. Integer interdum pellentesque ligula sed aliquet.</p><h1>Hello, world once more</h1><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sodales sit amet mauris nec vulputate. Aliquam erat volutpat.</p><p>Suspendisse orci sem, iaculis sed ullamcorper non, vehicula vitae nisl. Phasellus vestibulum scelerisque lacinia. Ut a nisl dictum, cursus sem eget, dignissim eros. Maecenas eget dolor eget augue luctus cursus. </p><p>Sed faucibus pulvinar tincidunt. Donec a dolor elementum, lobortis est vel, blandit velit. </p><h1>Hello world, one last time</h1><p>Quisque facilisis tortor iaculis arcu dignissim, quis consectetur neque blandit. Pellentesque malesuada odio imperdiet velit ullamcorper, sit amet porta justo maximus. Aenean accumsan, tortor eget.</p><p>Scelerisque varius, nunc tellus malesuada lacus, ut interdum metus ante eu orci. Nullam porttitor vel neque vitae faucibus. Integer interdum pellentesque ligula sed aliquet.</p>
</div>

Changing height of <p> block to a fixed height equal to that of auto

I am trying to make a show more / show less button which changes the height of a <p> block and slides to the correct size.
I know this can be done, and can only be done, between two fixed heights and the use of auto will stop the animation.
My question:
How can I get the px value of the auto height for the <p> block before the animation starts so that the height can be set to this <p> block explicitly for the animation to occur.
So far I am using:
function popupShow(id) {
var curCss = $('#results').find('a#'+id).parent().find('p').css("height");
var parent = $('#results').find('a#'+id).parent();
if(curCss == "136px") {
parent.find('p').css("height", "auto");
parent.find('a.show').html("...Show Less");
}
else {
parent.find('p').css("height", "136px");
parent.find('a.show').html("...Show More");
}
}
which works great how amending the size of the <p> to include the full text however I want to add in some animation. Following some googling I changed this too
function popupShow(id) {
var curCss = $('#results').find('a#'+id).parent().find('p').css("max-height");
var parent = $('#results').find('a#'+id).parent();
if(curCss == "136px") {
parent.find('p').css("max-height", "500px");
parent.find('a.show').html("...Show Less");
}
else {
parent.find('p').css("max-height", "136px");
parent.find('a.show').html("...Show More");
}
}
However I have noticed some blog posts can be bigger than 500px so I set it to 5000px as it said anything bigger than what you actually need but then the animation looks stupid.
For the css animation I am using:
-webkit-transition: max-height 0.8s;
-moz-transition: max-height 0.8s;
transition: max-height 0.8s;
html layout for 1 blog post (ignore php):
<div class="post-hold">
<div class="p-head">
<div class="p-title">
' . $posts[$i]['title'] . '
</div>
</div>
<div class="p-body">
<p>' . $posts[$i]['description'] . '</p>
<a id="' . $posts[$i]['id'] . '" class="show" onClick="popupShow(this.id)">...show more</a>
<div style="display: block; clear: both;"></div>
</div>
<div class="p-foot">
<div class="info">
<span class="p-time">' . \Core\View::time_since($posts[$i]['timeStamp']) . '</span>
<span class="p-user">' . $posts[$i]['user'] . '</span>
</div>
<div style="display: block; clear: both;"></div>
</div>
</div>
Thanks in advance.
EDIT
JSFiddle for the 136px -> 500px example.
you could use line-height (no need to know height):
p {
margin:0;
overflow:hidden;
line-height:0em;
transition:0.25s
}
a:hover + p ,
p:hover /* don't loose p once you want to hover it/select text or click an inside link */
{
line-height:1.2em;
}
link
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
link
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
link
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
You can hide paragraph in JS, get height and show again.
JS:
var p = $('p');
var pMaxHeight = $('p').css('max-height');
$(window).resize(function() {
p.css({
position: "absolute",
visibility: "hidden",
display: "block",
maxHeight: 'none'
});
pHeight = p.height();
p.css({
position: "",
visibility: "",
display: "",
maxHeight: '150px'
});
});
$(window).trigger('resize');
$('button').click(function() {
pMaxHeight = $('p').css('max-height');
if (pMaxHeight == '150px') {
p.css('max-height', pHeight);
} else {
p.css('max-height', '150px');
}
});
CODEPEN
Strictly speaking if you need get an element's height or width use the .offsetWidth and .offsetHeight properties.
Please note that the .offsetWidth and .offsetHeight properties belong to the element not the .style.
Example:
var width = document.getElementById('foo').offsetHeight;
Show more show less with JQuery
This should toggle the showing of the full div by clicking the actual div, you can add the click event to any trigger you want.
HTML:
<p id="blah">
Long...Content
</p>
Javascript:
$('#blah').css({height:'20px', overflow:'hidden'});
$('#blah').on('click', function() {
var $this = $(this);
if ($this.data('open')) {
$this.animate({height:'20px'});
$this.data('open', 0);
}
else {
$this.animate({height:'100%'});
$this.data('open', 1);
}
});
Showing less with javascript initially will not hide the div indefinitely for users w/o javascript enabled.

Hide JavaScript at a smaller screen

I am setting up my website to be responsive, and I want to know how to hide my livechat JavaScript when the screen size is smaller than 700px.
My current livechat JavaScript is ,
<script type="text/javascript">
function wsa_include_js(){
var wsa_host = (("https:" == document.location.protocol) ? "https://" : "http://");
var js = document.createElement("script");
js.setAttribute("language", "javascript");
js.setAttribute("type", "text/javascript");
js.setAttribute("src",wsa_host + "tracking-v3.websitealive.com/3.0/?objectref=wsa3&groupid=12581&websiteid=0");
document.getElementsByTagName("head").item(0).appendChild(js);
}
if (window.attachEvent)
window.attachEvent("onload", wsa_include_js);
else if (window.addEventListener)
window.addEventListener("load", wsa_include_js, false);
else
document.addEventListener("load", wsa_include_js, false);
</script>
Can someone please show me how. Thanks
This can actually be solved pretty easily with CSS media queries, however I need to know how the LiveChat is added to the HTML in order to give you a good answer.
What you want to do is take the class or ID of the div that holds the chat window and add the following to your CSS file:
#media screen and (max-width: 700px) {
#LiveChatContainerID { display: none; }
}
or
#media screen and (max-width: 700px) {
.LiveChatContainerClass { display: none; }
}
If LiveChat requires you to add an iframe to your site, just wrap the iframe in div tags with a unique ID or class and use the above in your CSS.
EDIT:
After seeing your site, I think I have a solution that will work fine:
#media screen and (max-width: 700px) {
.wsa_window, .wsa_window_close { display: none !important; }
}
The '!important' is needed to overwrite the style the javascript puts on the elements directly, but doing this in the inspector seemed to work fine without removing anything else on the page.
Hope this helps!
check this out it will help you. Its easy with JFiddle
This particular code changes color on size change so you can simply restructure it for your purpose. Test what you want to achieve right there in the code editor and see your result.
function red() {
$('div').css('background','#B60C0C')
.text('Screen Size RED');
}
function orange() {
$('div').css('background','#EBAE10')
.text('Screen Size ORANGE');
}
function green() {
$('div').css('background','#83ba2b')
.text('Screen Size GREEN');
}
var bounds = [
{min:0,max:500,func:red},
{min:501,max:850,func:orange},
{min:851,func:green}
];
var resizeFn = function(){
var lastBoundry; // cache the last boundry used
return function(){
var width = window.innerWidth;
var boundry, min, max;
for(var i=0; i<bounds.length; i++){
boundry = bounds[i];
min = boundry.min || Number.MIN_VALUE;
max = boundry.max || Number.MAX_VALUE;
if(width > min && width < max
&& lastBoundry !== boundry){
lastBoundry = boundry;
return boundry.func.call(boundry);
}
}
}
};
$(window).resize(resizeFn());
$(document).ready(function(){
$(window).trigger('resize');
});
I'm also not sure how you have added your chat into you page but if you have it in a div-tag you could hide that div on smaller screens.
You could do it with a script like in this jsFiddle but I think it's better to use CSS media queries as Oceanity answered.
In the fiddle you can easily test it by changing the size of the output section with the handle at the center.
(The size is set to 400px in the demo for easier testing in jsFiddle.)
For checking the size I have used a script from this SO question. I'm doing the size checking in onload- and onresize event.
function getViewPortSize()
{ // source code form here https://stackoverflow.com/questions/10653019/how-to-find-the-screen-width-and-apply-it-to-a-particular-css
var viewportwidth;
var viewportheight;
// Standard browsers
if (typeof window.innerWidth != 'undefined')
{
viewportwidth = window.innerWidth,
viewportheight = window.innerHeight
}
// IE6
else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0)
{
viewportwidth = document.documentElement.clientWidth,
viewportheight = document.documentElement.clientHeight
}
//Older IE
else
{
viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
viewportheight = document.getElementsByTagName('body')[0].clientHeight
}
return { width: viewportwidth, height: viewportheight};
}
var hideChat = function(evt) {
console.log(getViewPortSize().width);
if ( getViewPortSize().width < 400) {
//console.log('hide div now');
document.getElementById('chatArea').style = 'display: none';
}
else {
document.getElementById('chatArea').style = 'display: block';
}
};
window.onresize = function(evt) {
console.log(evt);
hideChat(evt);
};
window.onload = function(evt) {
console.log(evt);
hideChat(evt);
};
<div id="chatArea">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,
</div>

Change Element Style On Page Scroll

I want to change the visibility of an element after the user scrolls down 100px.
I have some code already,
var fixed = false;
$(document).scroll(function() {
if( $(this).scrollTop() >= 100 ) {
if( !fixed ) {
fixed = true;
$('#logo-scroll').css({position:'fixed', display:'visible !important'});
}
} else {
if( fixed ) {
fixed = false;
$('#logo-scroll').css({display:'none'});
}
}
});​
JSFiddle.
The code has two problems.
It doesn't default to be invisible, I want it so it starts invisible.
It doesn't repeat, when the user scrolls back up, it doesn't go back being invisible.
More details,
I want to make something like this header, but, as you can see, there's a certain point where you see half of the small logo, and a PART of the bigger one. It doesn't affect techcrunch much as the header is small, but on my site, it does. I have made everything, I just need to start it in display:none, and become visible after 100px.
Use: display:block; and display:none;
jsFiddle DEMO
Add this to your CSS:
#logo-scroll{ display:none; position:fixed; }
jQ:
var $logo = $('#logo-scroll');
$(document).scroll(function() {
$logo.css({display: $(this).scrollTop()>100 ? "block":"none"});
});
BTW: on TC page it's just a CSS play with z-indexes. nothing more. all elements are visible at page load, it's just the scroll that makes appear a z-index lower element beneath the big logo.
In plain Javascript would be like this:
var win = window,
docEl = document.documentElement,
$logo = document.getElementById('logo-scroll');
win.onscroll = function(){
var sTop = (this.pageYOffset || docEl.scrollTop) - (docEl.clientTop || 0);
$logo.style.display = sTop > 100 ? "block":"none" ;
};
Well the question has already been answered. just adding a better example which might be useful for others and it's exactly what op wants.
code and demo
Edited: Added actual code from original source.
jQuery:
// This function will be executed when the user scrolls the page.
$(window).scroll(function(e) {
// Get the position of the location where the scroller starts.
var scroller_anchor = $(".scroller_anchor").offset().top;
// Check if the user has scrolled and the current position is after the scroller start location and if its not already fixed at the top
if ($(this).scrollTop() >= scroller_anchor && $('.scroller').css('position') != 'fixed')
{ // Change the CSS of the scroller to hilight it and fix it at the top of the screen.
$('.scroller').css({
'background': '#CCC',
'border': '1px solid #000',
'position': 'fixed',
'top': '0px'
});
// Changing the height of the scroller anchor to that of scroller so that there is no change in the overall height of the page.
$('.scroller_anchor').css('height', '50px');
}
else if ($(this).scrollTop() < scroller_anchor && $('.scroller').css('position') != 'relative')
{ // If the user has scrolled back to the location above the scroller anchor place it back into the content.
// Change the height of the scroller anchor to 0 and now we will be adding the scroller back to the content.
$('.scroller_anchor').css('height', '0px');
// Change the CSS and put it back to its original position.
$('.scroller').css({
'background': '#FFF',
'border': '1px solid #CCC',
'position': 'relative'
});
}
});
HTML
<div class="container">
<div class="test_content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum metus nec neque convallis id interdum nibh aliquet. Nulla eget varius diam. Ut ut dolor dolor. Mauris vehicula sodales mi quis euismod. In sem metus, volutpat nec fringilla sed, fermentum ac turpis. Cras aliquam venenatis rutrum. Donec pharetra ante sit amet justo pellentesque nec consequat ante elementum. Ut imperdiet iaculis tortor, id pretium urna pharetra sit amet. Aenean pharetra nunc risus, ac scelerisque urna. Morbi dictum egestas augue, in euismod metus commodo ac. Duis nisl ante, consequat et tincidunt id, eleifend eu ante. Integer lectus velit, tempus eu feugiat et, adipiscing ut mauris.
</div>
<!-- This div is used to indicate the original position of the scrollable fixed div. -->
<div class="scroller_anchor"></div>
<!-- This div will be displayed as fixed bar at the top of the page, when user scrolls -->
<div class="scroller">This is the scrollable bar</div>
<div class="test_content">
Quisque sollicitudin elit vitae diam consequat accumsan. Suspendisse potenti. Donec dapibus tortor at justo eleifend at pellentesque leo lobortis. Etiam ultrices leo et nulla iaculis eu facilisis augue fermentum. Pellentesque eu leo purus. Vestibulum bibendum, metus at bibendum blandit, lacus neque porttitor diam, id facilisis lectus mauris et leo. Donec adipiscing interdum lacus sed condimentum. In auctor sollicitudin orci, ac interdum risus aliquet ullamcorper. Curabitur mollis accumsan vulputate. Etiam adipiscing diam nec dui posuere ut tincidunt felis tristique. Vestibulum neque enim, placerat sed placerat commodo, consectetur ac mauris. Sed ultrices pretium nibh, a blandit libero imperdiet pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
</div>
...
</div>
CSS:
.container{font-size:14px; margin:0 auto; width:960px}
.test_content{margin:10px 0;}
.scroller_anchor{height:0px; margin:0; padding:0;}
.scroller{background:#FFF; border:1px solid #CCC; margin:0 0 10px; z-index:100; height:50px; font-size:18px; font-weight:bold; text-align:center; width:960px;}

Categories