JavaScript animated smooth-scroll - javascript

By default when you have fragment links like this:
some text
the browser just, scrolls down to that fragment instantly. How do i program it to smoothly move down to that fragment with standard JS?
Here's an example:
Example (To see the working example, just click on the 3 arrows inside the 3 circles and watch the smooth animated scrolling)

okay, i think i found my answer, posting it here to help others with the similar doubt:
<html>
<head>
<script type="text/javascript">
var singleton = {};
var timeout = singleton;
window.onscroll = windowScroll;
function windowScroll ()
{
var toTop = document.getElementById('toTop');
toTop.style.display = ((window.scrollY > 0) ? "block" : "none");
}
function scrollStep ()
{
var y1 = window.scrollY - 1000;
window.scrollTo(0, y1);
if (y1 > 0)
{
timeout = window.setTimeout(scrollStep, 100);
}
else if (timeout != singleton)
{
window.clearTimeout(timeout);
}
}
</script>
<style type="text/css">
#toTop {
display: block;
position: fixed;
bottom: 20px;
right: 20px;
font-size: 48px;
}
#toTop {
-moz-transition: all 0.5s ease 0s;
-webkit-transition: all 0.5s ease 0s;
-o-transition: all 0.5s ease 0s;
transition: all 0.5s ease 0s;
opacity: 0.5;
display: none;
cursor: pointer;
}
#toTop:hover {
opacity: 1;
}
</style>
</head>
<body>
<p id="top">your text here</p>
<a href="#top" onclick="scrollStep(); return false" id="toTop"
><img src="images/go-to-top.png" alt="Go to top" title="Go to top"></a>
</body>
</html>

Well you should try something like this
$('html,body').animate({
scrollTop:$("#ctl00_ctl00_ContentPlaceHolder1_Conten
tPlaceHolder1_txtcomment").offset().top
},'slow');
where *#ctl00_ctl00_ContentPlaceHolder1_ContentPlaceHolder1_txtcomment* is the id where you want to move or scroll
another approch is to put this in a function
function scrollme() {
$('html,body').animate({
scrollTop:$("#ctl00_ctl00_ContentPlaceHolder1_ContentPlaceHolder1_txtcomment").offset().top
},'slow');
} <a onclick="javascript:scrollme();">some text</a>
I hope this will help you.
Regards..:)
[Updated]
A URI hash is a great way to make JavaScript/AJAX pages with dynamic
content bookmarkable. It can be used in a manner similar to query
strings, but changes will not cause a new page request. This allows
you to store data in the URI which can be read and changed by
JavaScript without ever reloading the page.
For the uninitiated, a URI location hash is everything after the #
sign in the URI:
http://domain.com/page.html#i-am-a-hash A side note: URI hashes are
not transferred back to the server, you can only access them
client-side.
check this blog
http://ole.michelsen.dk/blog/using-uri-hash-instead-of-query-strings/

Related

Making an image visible/invisible depending on the scroll position

So, i have a little arrow in my page:
<img src="images/arrow_up.png">
I wanna make it invisible when the page is at the top and then, as the user scrolls down, to make it visible so the user can click to go back to the top of the page.
This Javascript doesn't seem to be working:
$(document).ready(function(){
//Check to see if the window is top if not then display button
$(window).scroll(function(){
if ($(this).scrollTop() > 100) {
$('.scrollToTop').fadeIn();
} else {
$('.scrollToTop').fadeOut();
}
});
//Click event to scroll to top
$('.scrollToTop').click(function(){
$('html, body').animate({scrollTop : 0},800);
return false;
});
});
I also have this css (which is working):
.scrollToTop{
padding: 1em;
color: #444;
position: fixed;
right: 0;
bottom: 0;
-webkit-transition: -webkit-transform .3s ease-in-out;
-ms-transition: -ms-transform .3s ease-in-out;
transition: transform .3s ease-in-out;
z-index: 1;
}
.scrollToTop:hover{
-webkit-transform:rotate(360deg);
-moz-transform:rotate(360deg);
-o-transform:rotate(360deg);
}
I'd apreciate some help! :)
Not sure if your exact issue was this, but copying your code into a JS fiddle revealed that if the page was less than the window height, the arrow would always show.
A fix for this was to include a default display:none and then check window height on scroll. Checking it every time would allow the page to grow and shrink and still allow the arrow to only display when needed.
A working example can be seen at this JSFiddle.
$(document).ready(function(){
//Check to see if the window is top if not then display button
$(window).scroll(function(){
ShowScroll();
});
//Click event to scroll to top
$('.scrollToTop').click(function(){
$('html, body').animate({scrollTop : 0},800);
return false;
});
function ShowScroll() {
if (window.innerHeight < $("body").height())
{
var elem = $(".scrollToTop");
if (elem.css("display") == "none") elem.css("display","inline");
if ($(this).scrollTop() > 100) {
$('.scrollToTop').fadeIn();
} else {
$('.scrollToTop').fadeOut();
}
} else {
$(".scrollToTop").css("display","none")
}
}

How to make a div move smoothly?

I have a page where divs containing text appear one after one, and disappear as soon as they are followed by another, using CSS transition :
on JSFiddle : https://jsfiddle.net/5kp6qdgg/9/
HTML :
<body>
Click multiple times on this button:
<br />
<input type="button" value="Display one more div" />
<div id="div_container"></div>
</body>
CSS :
div#div_container {
position: relative;
}
.log {
position: relative;
display: inline-block;
margin-right: 50%;
opacity: 1;
-webkit-transition: all 2s;
-moz-transition: all 2s;
-ms-transition: all 2s;
-o-transition: all 2s;
transition: all 2s;
}
.hidden {
opacity: 0;
}
Javascript :
// Event listener
var button = document.getElementsByTagName("input")[0];
button.addEventListener ('click', oneMore);
// Spawn a div
function oneMore() {
var div = document.getElementById("div_container");
div.innerHTML += "<div class=log>Hello, I will soon disappear</div>";
clear ();
}
// Clear every div except the last
function clear () {
var logs = document.getElementsByClassName("log");
for (x=0; x<(logs.length-1); x++) {
var classes = logs[x].className.split(" ");
// Only thoses not already cleared
if (classes.length == 1) {
logs[x].className += (" waiting");
(function (x) {
window.setTimeout ( function () {
logs[x].className += (" hidden");
logs[x].addEventListener("transitionend", function () { logs[x].style.display = "none" });
logs[x].addEventListener("webkitTransitionend", function () { logs[x].style.display = "none" });
}, 500);
})(x);
}
}
}
So the remaining div move up to the top, but jerkily, whereas I would like it to translate smoothly.
Does anyone knows how to do this only with CSS and pure javascript ?
If you are able to change the display to block you can transition the height,margin, and padding so that they hide without taking up space. Then you do not need to do the ending display:none which is what is causing the sudden jerk.
Also you used .innerHTML+= this is inefficient and will cause all the elements to be recreated and rendered, and also makes it so you have to keep adding back the classes in clear.
Instead you could create an actual element, set all the appropriate attributes (class, innerText, etc) then appendChild it. This way you can keep the classes and event listeners you may want to put on them without having to continually re-add them.
// Event listener
var button = document.getElementsByTagName("input")[0];
button.addEventListener ('click', oneMore);
// Spawn a div
function oneMore() {
var div = document.getElementById("div_container");
var newDiv = document.createElement("div");
newDiv.classList.add("log");
newDiv.innerText = "Hello, I will soon disappear";
div.appendChild(newDiv);
if(newDiv.previousElementSibling){
newDiv.previousElementSibling.classList.add("hidden");
}
}
div#div_container {
position: relative;
}
.log {
position: relative;
display: block;
white-space: nowrap;
margin: 5px;
margin-right: 50%;
padding: 1px 10px;
border-radius: 20px;
opacity: 1;
background: rgba(250,0,0,0.7);
color: #fff;
width:190px;
height:20px;
-webkit-transition: all 2s;
-moz-transition: all 2s;
-ms-transition: all 2s;
-o-transition: all 2s;
transition: all 2s;
}
.hidden {
opacity: 0;
height:0px;
margin-top:0px;
margin-bottom:0px;
padding-top:0px;
padding-bottom:0px;
}
Click multiple times on this button:
<br />
<input type="button" value="Display one more div" />
<div id="div_container"></div>
It's a bit harder to hide an inline-block as even if you 0 out all the other style properties like height, margin, padding, etc the element is still going to effect the position of the other elements until display is set to none. You could do some tricks like setting display to block right before hiding it and then transitioning the previously mentioned styles, but that may again affect the positions of the other elements. Meaning when the display is set to block it will push the following elements down before transitioning.
There are other tricks you could use but they would require extra work and may affect the way you want your layout to be.

AngularJs re-size/adjust two div's accordingly

I've two div covering whole page 50% each and on lower div click i want it to cover full screen and come back on click again example
JQuery equivalent
$('.wrapper div.green').click(function() {
$(this).toggleClass('go')
if($(this).hasClass('go')){
$(this).animate({'height':'100%'},{
duration:200,
step:function(gox){
var height = gox < 100 ? (100 - gox) / 1 : 0;
$(this).siblings().css('height', height + "%");
}
})
}else{
$('.wrapper div').animate({'height':'50.00%'},200)
}
});
Now I want this in AngularJS and being new to it I've problems, so looking for some guidance to move in right direction. So far what I've tried
AngularJs Attempt
All i want is a similar functionality as of JQuery.
Here is a solution based on your first example - http://jsfiddle.net/nz2vunLs/2/
It uses CSS transistions and the angular directives ngClass and ngClick. I guess it's not the cleanest solution but it works.
html
<div ng-app ng-controller="Controller" class="wrapper">
<div ng-class="{min: greenFullscreen}" class="blue animation"></div>
<div ng-class="{max: greenFullscreen}" ng-click="toggleGreen()" class="green animation"></div>
</div>
Controller
function Controller($scope) {
$scope.greenFullscreen = false;
$scope.toggleGreen = function() {
$scope.greenFullscreen = !$scope.greenFullscreen;
}
}
Additional CSS
.green.max {
height: 100%;
}
.blue.min {
height: 0%;
}
.animation {
-webkit-transition: height 200ms;
-moz-transition: height 200ms;
-o-transition: height 200ms;
transition: height 200ms;
}

How to hide/show the div using javascript with transition ease-in-out effect?

This is my code which hide/show the div...but I want transition effect while hide/show in javascript like ease-in-out. How to achieve this in javascript?
function showHide(shID) {
if (document.getElementById(shID)) {
if (document.getElementById(shID + '-show').style.display != 'none') {
document.getElementById(shID + '-show').style.display = 'none';
document.getElementById(shID).style.display = 'block';
window.scrollTo(0, 2346);
}
else {
document.getElementById(shID + '-show').style.display = 'inline';
document.getElementById(shID).style.display = 'none';
}
}
}
I am not sure, why you are not using CSS3 transitions.
But to keep it all strictly javascript probably this source code is helpful:
https://github.com/jquery/jquery/blob/master/src/effects.js#L107
As has been pointed out, you should use CSS3 transitions if you want to do this in a standard way which will also not cause a lot of trouble because of high maintenance.
However, the problem then is you're trying to use a transition on a property with no quantifiable transitional values. There is no middle ground between display: block; and display: none; so you must use something which does have transitional values. Usually a property such as width or height is appropriate, but you can also use it on opacity, left, top, etc. (so basically any property with a numeric value).
This CSS is for an element which fades and slides in and out of a document from the top.
.panel {
position: absolute;
top: 0px;
opacity: 0;
-moz-transition: opacity .25s ease-in-out , top .25s ease-in-out;
-o-transition: opacity .25s ease-in-out , top .25s ease-in-out;
-webkit-transition: opacity .25s ease-in-out , top .25s ease-in-out;
transition: opacity .25s ease-in-out , top .25s ease-in-out;
}
.panel.show {
top: 50px;
opacity: 100;
}
Here's a Javascript that goes through the elements, checks for a data-toggle attribute, and assigns a click handler if it finds it. The handler toggles the show class for the targeted element.
function toggleElem(evt) {
var cn = 'show';
var panel = document.getElementById(evt.target.getAttribute('data-toggle'));
var classes = panel.className.split(/\s+/);
var x = classes.indexOf(cn);
if(x >= 0)
{ classes.splice(x,1); }
else
{ classes.push(cn); }
panel.className = classes.join(' ');
}
var elems = document.body.getElementsByTagName('*');
for(var i=0,l=elems.length;i<l;i++) {
var elem = elems[i];
var toggle = elem.getAttribute('data-toggle');
if(toggle !== null)
{ elem.addEventListener('click',toggleElem,false); }
}
Example HTML.
<input type="button" data-toggle="foo" value="Toggle"/>
<div id="foo" class="panel">
<p>This is a transitioned panel.</p>
</div>
Because of the fact you would be using opacity instead of display you may also run into the snag that the element you want to toggle, though invisible, will still be there as far as your cursor is concerned. You may then want to use setTimeout() to change the display value in addition to performing the class change to keep your transitioned element from catching input when hidden.

jquery background color fade in on scroll

I want the background of the header to fade in after a number of pixel scrolled. With the code below i kinda get it but not much right! Any idea? thanks!
$(function () {
$(window).scroll(function () {
$(document).scrollTop() > 100 ? $('header').css({
"background": 1
}).fadeIn() : $('header').css({
"background": 0
}).fadeOut();
});
})
A combination of Miquel Las Heras and Owen 'Coves' Jones's answers, who both submitted a not completely on-topic or not complete answer.
Use background trasitions (CSS3) and jQuery simultaneously.
JSFiddle
jQuery
$(document).ready(function () {
$(window).scroll(function () {
if ($(document).scrollTop() > 100) {
$("header").addClass("scrolled");
} else {
$("header").removeClass("scrolled");
}
});
});
CSS
header {
background-color:blue;
-webkit-transition: background-color 700ms linear;
-moz-transition: background-color 700ms linear;
-o-transition: background-color 700ms linear;
-ms-transition: background-color 700ms linear;
transition: background-color 700ms linear;
}
header.scrolled {
background-color: red;
}
Update February 3rd, 2017
browser support is very good, and the less performing jQuery solution below should not be used. Browser support.
Cross-browser solution
If you want to make it more cross-browser compatible, you can try the color plugin. But from what I've tested, it has quite a bad performance.
JSFiddle
$(document).ready(function () {
$(window).scroll(function () {
if ($(document).scrollTop() > 100) {
$("header").animate({
backgroundColor: "red"
}, 200);
} else {
$("header").animate({
backgroundColor: "blue"
}, 200);
}
});
});
Don't forget the plugin itself:
//cdnjs.cloudflare.com/ajax/libs/jquery-color/2.1.2/jquery.color.js
First, as was mentioned in the other answer, you will need to include jQuery UI or the jQuery Color plugin for color animation.
Second, and this is just winging it, but give this the old college try:
$(function(){
$(window).scroll(function(){
var $scrollPercent = ($(document).scrollTop() / 100);
if($scrollPercent <= 1){
$('header').css({backgroundColor:'rgba(0,0,0,'+$scrollPercent+')'});
}
});
});
This should give you a gradual fade in based on the amount down the page you scroll. This means that if you scroll 50 px down, your background color opacity would be set to 50% (50 px down / 100 px height wanted). You can also easily change the amount of height that you want to scroll down to reach full opacity very easily this way.
EDIT So it turns out you just want to fade in the color after 100px ... not my gradual fade in. No problem.
Others have pointed out the wonderful (and much better) CSS3 way to do it ... create a transition effect, and add a class on scroll. I won't steal their thunder, but I shall provide an alternative that works back to ancient browsers too.
Add an additional line of HTML inside of your header at the top:
<div class="header">
<div class="headerBackground"></div>
<!-- other header stuffs -->
</div>
Then set its CSS as such:
.header {
position:relative;
}
.headerBackground {
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background-color:rgb(0,0,0);
opacity:0;
filter:alpha(opacity=0); // for IE8 and below
}
Then use the following jQuery:
$(function(){
$(window).scroll(function(){
var $bg = $('.headerBackground');
if($(document).scrollTop() >= 100){
$bg.animate({opacity:1},500); // or whatever speed you want
} else {
$bg.animate({opacity:0},500);
}
});
});
This also has the added benefit of not requiring another library (jQuery UI / jQuery Color plugin). The downside is, of course, the non-semantic HTML. Like I said, just another alternative.
I prefer to create 2 css classes for this type of issues. One for when window is scrolled and one for when it's not:
header { background: transparent; }
header.scrolled { background: #f2f2f2; }
Then the javascript should be:
$(function () {
$(window).scroll(function () {
if($(document).scrollTop()>100){
$('header').addClass('scrolled');
}
else {
$('header').removeClass('scrolled');
}
});
})
your code is correct, but jQuery does not natively support color animation. you need a plugin or jquery-ui for that: http://jqueryui.com/animate/
EDIT: actually, your code is kinda wrong. you want to set the backgroundColor to something. background: 1 is invalid css:
so .css({'backgroundColor': 'red'}) and then .css({'backgroundColor': 'blue'})
If you don't need to support a lot of older browsers you can animate background colours with a combination of jQuery and css3 transitions:
Take the HTML:
<div id="myBox">Stuff here</div>
And the javascript:
var myBox = $('#myBox');
myBox.on('click', function (el) {
myBox.css('background-color', 'red');
}
Then click the element #myBox will change its background colour red. Instantly, with no fade.
If you also put in place the css code:
#myBox {
-webkit-transition: background-color 300ms ease-in-out;
-moz-transition: background-color 300ms ease-in-out;
transition: background-color 300ms ease-in-out;
}
Then any colour changes to the background will be faded over 300ms. Works on all latest version browsers, but not on IE 9 and below.
The solution that I ended up using is as follows:
I created a section that I'm fading in and out based on the scroll position.
CSS
.backTex {
width:100%;
height:500px;
margin-top:50px;
background-color: #myGreen;
//Height
transition: height 0.5s ease;
-webkit-transition: height 0.5s ease;
-moz-transition: height 0.5s ease;
-o-transition: height 0.5s ease;
-ms-transition: height 0.5s ease;
//Background-Color
transition: background-color 0.5s ease;
-webkit-transition: background-color 0.5s ease;
-moz-transition: background-color 0.5s ease;
-o-transition: background-color 0.5s ease;
-ms-transition: background-color 0.5s ease;
transition: background-color 0.5s ease;
}
jQuery
$(document).scroll(function() {
var positionScroll = $(this).scrollTop();
if(positionScroll <= 499) {
$(".backTex").css("background-color", "#fff");
} else if (positionScroll > 500 && positionScroll < 1100) {
$(".backTex").css("background-color", "#2ecc71");
} else {
$(".backTex").css("background-color", "#fff");
}
});
As far as compatibility, I haven't noticed any issues between browsers as of yet. Please reply to my post if you experience any. Thanks!

Categories