Smooth scrolling unit without using the attribute a [href ^ = "#"] - javascript

How to implement the transition when you click on the block with the class
<div class="btn">button-scroll </div>
Do not use aa [href ^ = "#"] One
<aside>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
<li>Six</li>
</ul>
</aside>
$(document).ready(function(){
// = Вешаем событие прокрутки к нужному месту
// на все ссылки якорь которых начинается на #
$('a[href^="#"]').bind('click.smoothscroll',function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top-($('ul').height()+ 100)
}, 900, 'swing', function () {
window.location.hash = target;
});
});
});
#main h2 {
margin-top:400px;
}
ul{
position:fixed;
top: 0px;
}
ul li{
display:inline-block;
}

Hi you can try with following
Instead of <div class="btn">button-scroll </div> add attribute 'target'like <div class="btn" target="targetDivId">button-scroll </div>
and in JavaScript
$(document).ready(function(){
$('.btn').bind('click',function (e) {
e.preventDefault();
var target = $(this).attr('target'),
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top-(100)
}, 900, 'swing');
});
});

Related

Read location in DOM (webpage) and change navmenu classes accordingly

I have a nav menu that links to certain parts of the page. I want to write some JS so that a class is added to each nav menu item when the scroll bar passes their respective part of the HTML. I believe I already know how to add classes to my navmenu items, so is there a specific way in JS to identify where in the DOM the user is?
To change the classes in the navbar dynamically, I use something like:
jQuery(document).ready(function ($) {
var menu_items_links = $(".menu li a");
menu_items_links.each(function () {
if ($(this).is('[href*="#CURRENT LOCATION IN DOM"]')) {
$(this).parent().addClass('current-location');
}
})
});
Where the class will add the highlight/underline to the navmenu item to show that the user is at the specific location.
You can use any scroll spy plugin for this or use the below implementation
$(window).bind('scroll', function() {
var currentTop = $(window).scrollTop();
var elems = $('.scrollspy');
elems.each(function(index){
var elemTop = $(this).offset().top;
var elemBottom = elemTop + $(this).height();
if(currentTop >= elemTop && currentTop <= elemBottom){ //Current location tracking
var id = $(this).attr('id');
var navElem = $('a[href="#' + id+ '"]');
navElem.parent().addClass('active').siblings().removeClass( 'active' );
}
})
});
.active{
color: red;
background-color: red;
}
#nav{
position:fixed;
top:0;
right:50%;
}
section{
min-height: 500px;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<nav id="nav" class="navbar navbar-template">
<div class="row col-xs-12 text-center">
<ul>
<li class="active">
Home
</li>
<li>
AboutUs
</li>
<li>
Images
</li>
<li>
Contact
</li>
</ul>
</div>
</nav>
<section class="scrollspy" id="Home">
Home
</section>
<section class="scrollspy" id="AboutUs">
AboutUs
</section>
<section class="scrollspy" id="Images">
Images
</section>
<section class="scrollspy" id="Contact">
Contact
</section>
</body>
Take a look at this scroll spy plugin https://github.com/r3plica/Scrollspy
So what finally worked for me was using WaypointJS. I basically just set waypoints at the specific parts of the DOM and then I could define what I want to happen at those places. Here's the code in the end:
jQuery(document).ready(function ($) {
var menu_items_links = $(".menu li a");
menu_items_links.each(function () {
if ($(this).is('[href*="#"]')) {
$(this).parent().removeClass('current-menu-item current-menu-ancestor');
}
})
new Waypoint({
element: document.getElementById('explore'),
direction: 'down',
handler: function() {
console.log("FIRST WAYPOINT IS ACTIVE.");
document.querySelector("a[href='/manitoba/#explore']").parentElement.classList.add('current-menu-item', 'current-menu-ancestor');
document.querySelector("a[href='/manitoba/#build']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
document.querySelector("a[href='/manitoba/#connect']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
},
offset: '25%',
continuous: false
});
new Waypoint({
element: document.getElementById('explore'),
direction: 'up',
handler: function() {
console.log("DEACTIVATING WAYPOINT.");
document.querySelector("a[href='/manitoba/#explore']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
},
offset: '35%',
});
new Waypoint({
element: document.getElementById('build'),
handler: function() {
console.log("SECOND WAYPOINT IS ACTIVE.");
document.querySelector("a[href='/manitoba/#build']").parentElement.classList.add('current-menu-item', 'current-menu-ancestor');
document.querySelector("a[href='/manitoba/#explore']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
document.querySelector("a[href='/manitoba/#connect']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
},
offset: '50%',
continuous: false
});
new Waypoint({
element: document.getElementById('connect'),
handler: function() {
console.log("THIRD WAYPOINT IS ACTIVE.");
document.querySelector("a[href='/manitoba/#connect']").parentElement.classList.add('current-menu-item', 'current-menu-ancestor');
document.querySelector("a[href='/manitoba/#build']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
document.querySelector("a[href='/manitoba/#explore']").parentElement.classList.remove('current-menu-item', 'current-menu-ancestor');
},
offset: '50%',
continuous: false
});
});

Previous and next buttons that navigate through a single page

Still a noob but I am slowly getting there.
I have a series of divs, all the same class and I have previous and next buttons that scroll to the top of the next or previous div when clicked. I would like to set an offset so that my header won't hide the div that scrolls underneath of it and I am unsure how to go about this. Code below.
<button class="prev link js-prev js-scroll-to">Previous</button>
<button class="next link js-next">Next</button>
<script>
$('.js-scroll-to').click(function(e) {
target = $($(this).attr('href'));
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
$('.js-next').click(function(e) {
var selected = $(".js-list-item.js-current-panel");
var anchors = $(".js-list-item");
var pos = anchors.index(selected);
var next = anchors.get(pos+1);
var prev = anchors.get(pos-1);
target = $(next);
$(selected).removeClass("js-current-panel");
$(next).addClass("js-current-panel");
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
$('.js-prev').click(function(e) {
var selected = $(".js-list-item.js-current-panel");
var anchors = $(".js-list-item");
var pos = anchors.index(selected);
var next = anchors.get(pos+1);
var prev = anchors.get(pos-1);
target = $(prev);
$(selected).removeClass("js-current-panel");
$(prev).addClass("js-current-panel");
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
</script>
For your case, I think you could just add the offset right into your animated scroll code (subtracting the height of the nav bar plus a little margin):
$('html, body').animate({scrollTop: target.offset().top - 54 + 'px'}, 1000);
I usually do this without a JS scroll by adding a span class to use as the anchor instead of anchoring on the div itself. This will work if someone links directly to the anchor point as well.
That way I can use position relative on the anchor to set an offset for the height of the nav bar.
In this case, I think you probably have some divs like this:
<div class="js-list-item js-current-panel">
content
</div>
<div class="js-list-item">
content
</div>
<div class="js-list-item">
content
</div>
I'd change it to:
<span class="anchor js-list-item js-current-panel"></span>
<div class="content">
content
</div>
<span class="anchor js-list-item"></span>
<div class="content">
content
</div>
<span class="anchor js-list-item"></span>
<div class="content">
content
</div>
With some CSS to position those new anchors (top depends on nav bar height):
.anchor {
position: relative;
top: -54px;
}
Example with some extra CSS to show how the anchors are positioned:
<style type="text/css">
.nav {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 44px;
background: black;
}
.main {
margin-top: 54px;
}
.js-list-item {
display: inline-block;
width: 5px;
height: 5px;
background: blue;
position: relative;
top: -54px;
}
.content {
background: red;
width: 100%;
height: 500px;
margin-bottom: 25px;
}
</style>
<div class="nav">
<button class="prev link js-prev js-scroll-to">Previous</button>
<button class="next link js-next">Next</button>
</div>
<div class="main">
<span class="js-list-item js-current-panel"></span>
<div id="one" class="content">content</div>
<span class="js-list-item"></span>
<div id="two" class="content">content</div>
<span class="js-list-item"></span>
<div id="three" class="content">content</div>
<span class="js-list-item"></span>
<div id="four" class="content">content</div>
<span class="js-list-item"></span>
<div id="five" class="content">content</div>
<span class="js-list-item"></span>
<div id="six" class="content">content</div>
<span class="js-list-item"></span>
<div id="seven" class="content">content</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
$('.js-scroll-to').click(function(e) {
target = $($(this).attr('href'));
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
$('.js-next').click(function(e) {
var selected = $(".js-list-item.js-current-panel");
var anchors = $(".js-list-item");
var pos = anchors.index(selected);
var next = anchors.get(pos+1);
var prev = anchors.get(pos-1);
target = $(next);
$(selected).removeClass("js-current-panel");
$(next).addClass("js-current-panel");
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
$('.js-prev').click(function(e) {
var selected = $(".js-list-item.js-current-panel");
var anchors = $(".js-list-item");
var pos = anchors.index(selected);
var next = anchors.get(pos+1);
var prev = anchors.get(pos-1);
target = $(prev);
$(selected).removeClass("js-current-panel");
$(prev).addClass("js-current-panel");
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
</script>

How to combine this scripts correctly?

I have 2 scripts which can't work parallel. The first one is for scrolling to the search bar when it's focused, the other one removes focus when youre scrolling (to remove keyboard on mobile).
Is there a way to combine these scripts, to have it scrolling first to the search bar and then have the second script get activated if you scroll again for removing the keyboard? Because right now it's scrolling to the search bar and then it loses focus.
To scroll it to the search bar:
$("#myInput").click(function () {
$("html, body").animate({ scrollTop: $("#osb").offset().top }, 300);
return true;
});
To remove focus when scrolling again:
document.addEventListener("scroll", function() {
document.activeElement.blur();
});
Thanks already!
Example:
$("#myInput").click(function() {
document.removeEventListener("scroll", blurElement);
$("html, body").animate({
scrollTop: $("#b").offset().top
}, 300, function() {
document.addEventListener("scroll", blurElement);
});
return true;
});
function blurElement() {
document.activeElement.blur();
}
document.addEventListener("scroll", blurElement);
#a {
height: 100px;
background: #aaa;
}
#b {
background: #bbb;
}
#c {
height: 1000px;
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a">
</div>
<div id="b">
<input type="text" id="myInput" placeholder="search.." title="">
</div>
<div id="c">
^ need this stay focused untill I scroll again
</div>
Maybe using a flag to prevent "blurring" while your animation is running;
var allowBlur = true;
$("#myInput").click(function () {
allowBlur = false;
$("html, body").animate({ scrollTop: $("#osb").offset().top }, 300, function() {
allowBlur = true;
});
return true;
});
document.addEventListener("scroll", function() {
if(!allowBlur) return;
document.activeElement.blur();
});
Attempt #2
$("#myInput").click(function () {
document.removeEventListener("scroll", blurElement);
$("html, body").animate({ scrollTop: $("#osb").offset().top }, 300, function() {
document.addEventListener("scroll", blurElement);
});
return true;
});
function blurElement() {
document.activeElement.blur();
}
document.addEventListener("scroll", blurElement);
Attempt #3
It appears that for some reason the "scroll" event is still being sent even when the animation is done. So based on this answer https://stackoverflow.com/a/8791175/1819684 I used a promise but I still needed a setTimeout to give the "scroll" time to end.
$("#myInput").click(function() {
document.removeEventListener("scroll", blurElement);
$("html, body").animate({
scrollTop: $("#b").offset().top
}, 300).promise().done(function() {
setTimeout(function() {
document.addEventListener("scroll", blurElement)
}, 100);
});
return true;
});
function blurElement() {
document.activeElement.blur();
}
document.addEventListener("scroll", blurElement);
#a {
height: 100px;
background: #aaa;
}
#b {
background: #bbb;
}
#c {
height: 1000px;
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a">
</div>
<div id="b">
<input type="text" id="myInput" placeholder="search.." title="">
</div>
<div id="c">
</div>

Scroll to id function jQuery

So I have been making onepage websites for a while now, and one thing witch is always annoys me is navigation functions witch i'm repeating for the amount of buttons and id's I have.
It looks like the following:
$('#homeB').click(function () {
$('html, body').animate({
scrollTop: $("#home").offset().top
}, 1000);
return false;
});
$("#aboutB").click(function() {
$('html, body').animate({
scrollTop: $("#about").offset().top
}, 1000);
return false;
});
$("#winesB").click(function() {
$('html, body').animate({
scrollTop: $("#wines").offset().top
}, 1000);
return false;
});
Question is, how do I change from here to a small function that does not need repeating.
Thanks.
Note: Preferably no 3rd party plugins etc. keep it in JavaScript/jQuery.
To avoid writing duplicate code, you could do a little something like this:
$(function() {
$('li').on('click', function(e) {
e.preventDefault();
$('html, body').animate({
scrollTop: $($(e.target).attr("href")).offset().top
}, 1000);
});
});
nav {
position: fixed;
top: 0;
left: 0;
}
div {
margin: 100px 0 0 0;
width: 100%;
height: 500px;
}
div:nth-child(even) {
background: #ccc;
}
div:nth-child(odd) {
background: #4c4c4c;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</nav>
<div id='1'></div>
<div id='2'></div>
<div id='3'></div>
<div id='4'></div>
function scrollTo($element) {
$('html, body').animate({
scrollTop: $element.offset().top
}, 1000);
return false;
}
then you can use it as
$('#homeB').click(function () {
scrollTo($("#home"));
});
$("#aboutB").click(function() {
scrollTo($("#about"));
});
$("#winesB").click(function() {
scrollTo($("#wines"));
});
There are a couple ways of tackling this. If I were to be doing it, I would make whatever is being clicked a class and then setting a data attribute to the destination id, like this
<span class='nav_link' data-dest='home2'>Click me to go to home 2</span>
Then you could do something like this
$('.nav_link').click(function() {
var dest = $(this).attr('data-dest');
$('html, body').animate({
scrollTop: $('#'+dest).offset().top
}, 1000);
})

Animate content in a list

I want to make it so that when I hover over one of the items in a list, it moves that element.
Here is my HTML code for the list:
<ul class="nav">
<li class="test">Home</li>
<li>News</li>
<li>About us</li>
<li>Venue</li>
<li>Affiliations</li>
<li>Players & Officers</li>
<li>Fixtures & Results</li>
<li>Coaching</li>
<li>Contact us</li>
</ul>
And here is my Jquery code:
$(document).ready(function() {
$('').mouseenter(function() {
$(this).animate({ left: '+=100px' });
});
$('').mouseleave(function() {
$(this).animate({ left: '-=100px' });
});
});
Basically, my question is what goes in the quote marks in the JQuery functions?
Use the on event
$(document).ready(function () {
$('.nav').on({
mouseenter : function(){
$(this).animate({left: '+=100px'});
},
mouseleave : function(){
$(this).animate({left: '-=100px'});
}
}, 'li');
});
Try this:
$(document).ready(function()
{
$('.nav li').mouseenter(function()
{
$(this).animate({left: '+=100px'});
});
$('.nav li').mouseleave(function()
{
$(this).animate({left: '-=100px'});
});
});
You can use $('.nav li') to target list items of your nav:
$(document).ready(function () {
$('.nav li').mouseenter(function () {
$(this).animate({
left: '+=100px'
});
});
$('.nav li').mouseleave(function () {
$(this).animate({
left: '-=100px'
});
});
});
Also, you need to set position: relative for your list items, so the left value can work:
.nav li {
position: relative;
}
Fiddle Demo
You might want to consider the .on and event map approach.
$('.nav').on({
mouseenter : function(){
$(this).animate({left: '+=100px'});
},
mouseleave : function(){
$(this).animate({left: '-=100px'});
}
}, 'li');
HTML Code:
<ul class="nav">
<li>Home</li>
<li>News</li>
<li>About us</li>
<li>Venue</li>
<li>Affiliations</li>
<li>Players & Officers</li>
<li>Fixtures & Results</li>
<li>Coaching</li>
<li>Contact us</li>
</ul>
Javascript:
$(document).ready(function () {
$('.nav li').mouseenter(function () {
$(this).animate({
left: '+=100px'
});
});
$('.nav li').mouseleave(function () {
$(this).animate({
left: '-=100px'
});
});
});
A little CSS tweek to make the list hover animation work:
.nav {
padding: 20px 0 0 20px;
}
.nav li {
position: relative;
}
Check the demo at: DEMO

Categories

Resources