Update: the script and scrollTo animation now work fine. I've uploaded the correct solution.
I'm working on a Bootstrap 3 based website and I'm having some scrollTo issues, this is the code for a navbar (links from the nav lead to three different sections within the page):
HTML:
<header id="page-header" class="container">
<h1> NMS website </h1>
<img src="assets/images/group-logo.png" alt="group logo">
<nav class='navbar navbar-default navbar-fixed-top' role='navigation'>
<h2> Page navigation </h2>
<div class='navbar-header'>
<button type='button' class='navbar-toggle' data-toggle='collapse' data-target='#collapse'>
<span class='sr-only'>Toggle navigation</span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
</button>
</div>
<div class='collapse navbar-collapse' id='collapse'>
<div class="container">
<ul class="nav navbar-nav">
<li>Brands</li>
<li>About Us</li>
<li>Contact</li>
</ul>
</div>
</div>
</nav>
</header> <!-- end of page header -->
JavaScript (Modernizr library included for media query support, also I've used offset because the navbar is fixed and is overlapping the content area after scrollTo animation by default):
$(function () {
// making our anchors "scrollable"
var x;
$('a[href*=#]:not([href=#])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top-x
}, 700);
return false;
}
}
});
function responsive () {
if(Modernizr.mq('(min-width: 768px)')) {
x = 85;
}
if(Modernizr.mq('(max-width: 767px)')) {
x = 180;
}
}
responsive();
$(window).resize(function () {
responsive();
});
});
and as you can see, I'm using this piece of code - https://css-tricks.com/snippets/jquery/smooth-scrolling/ for making scrollTo effects. Scrolling doesn't work that great, the problem occurs when I resize the browser window. When I go from desktop to mobile (without refreshing the page) the scrolling animation won't work that well (it doesn't recognize the "mobile" script first, so when I click on a link in the menu it will first run the offset from non-mobile script, and then it will run the offset for mobile script, which makes a non-pretty animation). But if I resize the window to mobile and then refresh the page (just like opening the page from a mobile device for the first time), my scrolling works great. Same thing goes for non-mobile window sizes as well. I hope I made this question clear? Thanks.
Related
I’m a beginner and I’m stuck. And I would really use some help. Have two questions regarding js.
Namely, I have a sidebar on the left that has a toggle option. In order to solve the problem of keeping my sidebar in sight when scrolling, I added javascript code that constantly raises it to the top of the page. But that doesn't seem like the optimal solution.
Is there a way to use javascript to set the menu to be fixed to the top of the page whenever the toggle is open.
Here is the following js code:
$(function() {
var $sidebar = $("#menu"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 60;
$window.scroll(function() {
if ($window.scrollTop() > offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
});
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});
Here is the html:
<!-- Sidebar -->
<div class="bg-light border-right" id="sidebar-wrapper" style="background-image: url('geogebra6.png'); scroll-margin: 120px;"> <!--Dodao side baru scroll marginu -->
<div class="sidebar-heading">Sadržaj</div>
<div class="list-group list-group-flush" style="background-image: url('geogebra1.png');" id="menu">
<b>1. Uvod</b>
<b>2. Realni nizovi </b>
<!-- class="dropdown-toggle" style="color: black; "-->
<b>3. Funkcionalni nizovi</b>
<ul class="collapse list-unstyled" id="homeSubmenu" >
<li>
<b>3.1. Obična konvergencija</b>
</li>
<li>
<b>3.2. Ravnomerna konvergencija</b>
</li>
</ul>
</div>
</div>
Of course, using position:fixed does not get the job done because it breaks the flow and mu side bar has the toggle option.
While we are here, is there any way of editing this line of code to make sidebar closed by default and then to open when clicked on the button? I've tried several different solutions but none of them seems optimal.
Here is the code in question:
<!-- Menu Toggle Script -->
// $("#wrapper").toggleClass("toggled");
$("#menu-toggle").click(function(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
Here is the actual link of the site:
http://alas.matf.bg.ac.rs/~ml05184/
I'm creating a website using Django, and I want the link in the navbar (when clicked) to smoothscroll to the element that I want. This is what I have:
base.html
<li>
<a class="nav-item nav-link" href = '' class='scroll-about'>About</a>
</li>
//unrelated elements
<script>
// scroll into view
document.querySelector('.scroll-about').addEventListener('click', function(e) {
e.preventDefault();
document.querySelector('.about').scrollIntoView({ behavior: 'smooth' });
});
home.html
<div class="about col-12 col-md-6">
<div class="d-flex flex-column align-items-center py-5 text-uppercase">
<h3 class="h3-responsive bg-primary text-center text-white rounded font-weight-bold w-50 px-4 py-2 shadow">About</h3>
<h1 data-easy-reveal = "" class = " h1-reponsive font-weight-bold my-5 ml-3">Our vision is for every business to leave its mark on the digital world</h1>
<h1 data-easy-reveal = "" class = "down h1-reponsive font-weight-bold ml-3">Our vision is to bring them to the next level </h1>
</div>
</div>
The rest of the code works fine, the Django templating is all fine. I just can't seem to get this scroll function to work. I've tried moving the script around the bottom of the html file, and as well as putting it in the head element of the html file. I've also tried using jQuery smooth scroll and it doesn't work either.
the jQuery code I tried (in this case I put scroll-about and about as the respective IDs):
<script>
$("#scroll-about").click(function() {
$([document.documentElement, document.body]).animate({
scrollTop: $("#about").offset().top
}, 2000);
});
</script>
i think that this is what you are trying to do. note that it works just with a tags with href="#something"
$(document).ready(function(){
// Add smooth scrolling to all links
$("a").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="height: 100vh; background: #00ced1">
<a id="1" href="#2">Go to Section 2</a>
</div>
<div style="height: 100vh; background: red;">
<a id="2" href="#1">Go to Section 1</a>
</div>
I've found the solution to the issue, adding this allows it to work:
html {
scroll-behavior: smooth;
}
So I am trying to use the smooth scrolling animation used in this template:
https://blackrockdigital.github.io/startbootstrap-scrolling-nav/
After adding the js files to my directory, including the basic JQuery files, I've seen the custom .js file that adds the scrolling uses the .class parameter in an anchor tag to detect if clicking it should trigger the smoothscrolling. So I added those to my anchor tags.
Below is the relevant code.
I will include a live preview too.
index.html file
<!-- Navigation section -->
<section class="nav" id="nav">
<div class="container">
<div class="row" style="width: 100%; text-align: center;">
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4">
<a class="js-scroll-trigger btn btn-lg btn-nav" href="#about">About me</a>
</div>
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4">
<a class="js-scroll-trigger btn btn-lg btn-nav" href="#work">My work</a>
</div>
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4">
<a class="js-scroll-trigger btn btn-lg btn-nav" href="#contact">Contact</a>
</div>
</div>
</div>
</section>
Script imports in index.html
<!-- Import js -->
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="vendor/jquery/jquery.min.js"></script>
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
<script src="js/scrolling-nav.js"></script>
Scrolling-nav.js
(function($) {
"use strict"; // Start of use strict
// Smooth scrolling using jQuery easing
$('a.js-scroll-trigger[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 1000, "easeInOutExpo");
return false;
}
}
});
})(jQuery); // End of use strict
I have nearly no experience with JQuery / JS, so it's hard for me to understand where it might be going wrong.
Here is a live preview of the website with above code in it:
Live preview
Full code:
Github link
If there's any information missing, let me know.
jQuery is missing, and you're using jQuery in your click event...
Add this code in you jquery
$(document).ready(function(){
// Add smooth scrolling to all links
$("a").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
});
I have a page where you can click to slideDown an element from the top of the page.
I am trying to create a rule that says if the push down is visible and the screen has scrolled further than the height of the push down then it should be hidden again. Meaning the user will have to push the button to get it to show again.
In my HTML I have:
<div class="row" id="learn-more" style="display:none">
<div class="small-12 columns" id="close">
<p id="close-learn">
<i class="fa fa-times pull-right fa-2x"></i>
</p>
</div>
<div class="small-12 columns" id="learn-content">
<h1>Content for Pushdown</h1>
</div>
</div>
<div class="row" id="hero">
<div class="small-12 columns small-centered">
<p id="learn"><a class="transition">Learn More</a></p>
</div>
</div>
In my Javascript I have:
// Open and close learn more section
$("#learn").on("click", function() {
$("#learn-more").slideDown();
});
$("#close-learn").on("click", function() {
$("#learn-more").slideUp();
});
// Close learn-more based on scroll position
$(window).on("scroll", function() {
var scrollPosition = $(window).scrollTop();
if ($("#learn-more").is(":visible") && scrollPosition > $("#learn-more").height()) {
$("#learn-more").slideUp()
}
});
This all works but when the #learn-more element slides up the page jumps down about 500 pixels which is the height of the #learn-more element. I would like mine to work in the same way as Airbnb's new homepage when you click the 'how it works' button and then scroll below the push down element.
Any advice would be much appreciated.
Seems that this situation occurs because $(window).scrollTop position is preserved after the the slideUp() is called.
But we can memorize the visible position of Learn More button relative to the top of the window and after text block is hidden return to this position. Also, i suggest to use hide() instead of slideUp() here.
Here is what I suggest to do on scroll:
$(window).on("scroll", function(event) {
var scrollPosition = $(window).scrollTop();
var learnMore = $("#learn-more");
if (learnMore.is(":visible") && scrollPosition > learnMore.height()) {
var learnMoreButtonTop = $("#learn").offset().top - scrollPosition;
learnMore.hide();
$(window).scrollTop(learnMoreButtonTop);
}
});
Working example
I'm trying to get my jQuery animations to work properly in older versions of IE but for some reason it will skip the second .animate() process when first attempted for each div. I'm guessing it must have to do with the order of how I apply css and assign classes but I can't figure out how to fix it.
Essentially what I want to have happen is:
1. user clicks on a name/label for a customer testimonial
2. the current testimonial fades out (opacity:0)
3. the height of the testimonial's containing div adjusts to either the height of the sidebar menu or the height of target testimonial (whichever is larger)
4. the targeted testimonials fades in (opacity:1)
I have a demo page online here.
Here's my code:
Javascript::
jQuery(document).ready(function($){
var targetTestimonial = $('div.current');
$('#testimonialMenu a').click(function(e){
e.preventDefault(); // disable default link behavior (no page change)
targetTestimonial = $('#' + $(this).attr('rel'));
if (!targetTestimonial.hasClass('current')){
var tempHeight = Math.max($('#testimonialMenuMask').outerHeight(), $(targetTestimonial).outerHeight());
$('div.current').animate({opacity:0}, 500, function(){
$('#testimonialContainer').animate({height: tempHeight}, 500, function(){
$('div.current').removeClass('current').css({display:'none'});
$(targetTestimonial).css({display:'block'}).animate({opacity:1.0}, 500, function(){
$(this).addClass('current');
});
});
});
}
$('#testimonialMenu a').removeClass('current');
$(this).addClass('current');
});
});
HTML::
<div id="testimonialMenuMask">
<h3>Select a Testimonial:</h3>
<ul id="testimonialMenu">
<li>
<ul>
<li>Marianne</li>
<li>Dillon</li>
</ul>
</li>
</ul>
</div>
<div id="testimonialContainer">
<div id="marianne" class="testimonialMask current">
<!-- HTML CONTENT -- >
</div><div id="dillon" class="testimonialMask">
<!-- HTML CONTENT -- >
</div>
</div>