Display reset/reveal button for collapsing header - javascript

I am using the collapsing header described here http://codepen.io/cbracco/pen/corFl
I'd like to enhance it with the following feature:
When the user has scrolled the content area all over the header I'd like to display a "reset" button that pushes the content area back to its initial position and reveals the header fully again.
I guess at least for the reset, I'd have to use javascript (or the CSS checkbox trick maybe?). Could the "reset" button made visible purely by using CSS or would I have to use window.onScroll to detect scrolling of the content area and display the button myself via javascript?

You can create an element with an id at the top of the page (i.e. <span id="top">), and then use Javascript to scroll to that element.
button.addEventListener('click', function() {
window.location.hash = "#top";
});
See this SO question.

Scroll to top can easily be done without javascript:
<div id="top">lorem ipsum</a>
go to top
http://codepen.io/anon/pen/PZBXyg
If you however want to smoothly scroll to the top, then I'd suggest to use this neat little snippet of jquery:
$('#top').click(function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
history.pushState({}, '', target.selector);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
http://codepen.io/anon/pen/xZJmyP
To reveal the "reset" button based on how much the user has scrolled, you might want to utilize the window.onscroll listener and then check the scrollTop value
With native javascript:
window.onscroll = function(){
console.log(document.body.scrollTop)
}
With jQuery
$(window).scroll(function (event) {
console.log($(window).scrollTop());
});

Related

Anchor scroll is scrolling to the anchor upon page load

Any help with this is greatly appreciated! I have a button at the top of my product page for a sizing chart which anchor scrolls to the sizing chart image at the bottom of the page. However, upon page load, the page automatically scrolls down to the sizing chart. What can I modify so that the page does not automatically scroll down to the anchor? Here is my JS:
// Select all links with hashes
$('a[href*="#"]')
// Remove links that don't actually link to anything
.not('[href="#"]')
.not('[href="#0"]')
.click(function(event) {
// On-page links
if (
location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
&&
location.hostname == this.hostname
) {
// Figure out element to scroll to
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
// Does a scroll target exist?
if (target.length) {
// Only prevent default if animation is actually gonna happen
event.preventDefault();
$('html, body').animate({
scrollTop: target.offset().top
}, 1000, function() {
// Callback after animation
// Must change focus!
var $target = $(target);
$target.focus();
if ($target.is(":focus")) { // Checking if the target was focused
return false;
} else {
$target.attr('tabindex','-1'); // Adding tabindex for elements not focusable
$target.focus(); // Set focus again
};
});
}
}
});
I assume you mean that the page scrolls down when it is reloaded.
It is default browsers behaviour to scroll the page down to the point the user were the last time she/he visited the page.
To avoid that scroll to top before the page is closed:
$(window).on('beforeunload', function() {
$(window).scrollTop(0);
});

How to hide the menu in mobile on click on the menu item?

I have a one-page website. I have a menu with the smooth scroll. When the user clicks on service then it will target the service section with the smooth scroll. There is no issue on the desktop.
Let's talk about mobile
In mobile, Menu is displaying like below
When I click hamburger icon then it's displaying like this
Now the issue is in the smooth scroll. When I click on service then it's targeting the service section with smooth scroll but the menu is still shown on the mobile.
I have to hide the menu when I click on the menu.
You can check my [code here][3]
https://jsfiddle.net/vqpyt5co/
Added the following code to trigger click event of closing the dropdown.
if ($(".x_mark_img").is(":visible")) {
$(".x_mark_img").click();
}
See updated fiddle
$(function() {
$('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) {
if ($(".x_mark_img").is(":visible")) {
$(".x_mark_img").click();
}
$('html, body').animate({
scrollTop: target.offset().top-80
}, 1000);
return false;
}
}
});
});

Scroll less then default when clicked navitem

I have navbar with items. When i click on item it scrolls me down to the div. For example i click on contact and it scrolls me to contact. My problem is that i have fixed navbar. And my navbar hide heading of section. So when i click on contact it scrolls me down to contact but heading is behind navbar.
This is my script i need to add something like scroll - 55px or something like that but i dont know how.
<script>
// Select all links with hashes
$('a[href*="#"]')
// Remove links that don't actually link to anything
.not('[href="#"]')
.not('[href="#0"]')
.click(function(event) {
// On-page links
if (
location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
&&
location.hostname == this.hostname
) {
// Figure out element to scroll to
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
// Does a scroll target exist?
if (target.length) {
// Only prevent default if animation is actually gonna happen
event.preventDefault();
$('html, body').animate({
scrollTop: target.offset().top
}, 1000, function() {
// Callback after animation
// Must change focus!
var $target = $(target);
$target.focus();
if ($target.is(":focus")) { // Checking if the target was focused
return false;
} else {
$target.attr('tabindex','-1'); // Adding tabindex for elements not focusable
$target.focus(); // Set focus again
};
});
}
}
});
</script>
You could first check if link clicked is /contact and then apply a different scroll like this:
if (target.length) {
// Only prevent default if animation is actually gonna happen
event.preventDefault();
let scrollOffset = 0;
if ($(this).attr('href') === '/contact') {
scrollOffset = 55;
}
$('html, body').animate({
scrollTop: target.offset().top + scrollOffset
}, 1000, function() {
// Callback after animation
// Must change focus!
var $target = $(target);
$target.focus();
if ($target.is(":focus")) { // Checking if the target was focused
return false;
} else {
$target.attr('tabindex','-1'); // Adding tabindex for elements not focusable
$target.focus(); // Set focus again
};
});
}
It's not the most elegant solution but that should do the trick.
If you could share html as well it would be easy to understand. Anyways, as i understood the problem is with fixed navbar. When Positioning absolute/fixed is used the div is then out of the flow of the document. To get elements start immediately after header you would need to give elements container a margin-top equal to the height of the header. This is the easiest solution. You do not need to do anything with js.

What is the best way to separate javascript functions?

I have two javascript files that come in conflict with each other. One is to open modals and uses links like open modal, and would then open the modal with id="modal". But the other script is for smooth scroll and it removes the anchor from the url (I'd like to keep that part!) but after adding the smooth scroll script, the modals don't work. any ideas how I can fix it?
modal.js:
$(".modal-wide").on("show.modal", function() {
var height = $(window).height() - 200;
$(this).find(".modal-body").css("max-height", height);
});
$('a[data-toggle="modal"]').bind('click',function(){
$('.modal').modal('hide');
});
scroll.js:
$(function() {
$('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
}, 500);
return false;
}
}
});
});
scroll.js source: https://css-tricks.com/snippets/jquery/smooth-scrolling/
Try adding your specific href tags to the not selector the the smooth scroll function.
$('a[href*="#"]:not([href="#"]):not([href="#modal"])').click(function()
Here is a fiddle showing the smoothscroll only works for the smooth scroll div which should preserve your modal functionality.
https://jsfiddle.net/bryangators/wjgu1vL9/

Remove anchor link after scrolling - works also on links from another page

I've set up a single page website with smooth scrolling that strips the anchor link from the URL after smooth scrolling. Here's the jQuery I'm using :
$(function() {
$('a.page-scroll').on('click', function(event) {
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top - 60
}, 1000, 'easeInOutExpo');
event.preventDefault();
});
});
Everything works great until I added other pages. I can't get the anchor link to strip out after a link like <a class="page-scroll" href="../#contact">Contact</a> on another external page.
I've searched high and low on SO but can't find a solution that works.
I don't totally care about the smooth scrolling if the link is from an external page. What I need most is to navigate / scroll to the id section of the main page (with offset to accommodate fixed navigation) and remove the anchor link from the browser URL window when the link is from an external page (from other pages on my website, or from other websites).
I've tried this also, but it likewise only works on internal links on to an id on the same page :
<script>
$(function() {
$('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 - 60
}, 1000);
return false;
}
}
});
});
</script>
I've also tried this with no luck :
<script type="text/javascript">
(function($) {
$(document).ready(function() {
var url=document.URL.split("#");
var ancher=url[1];
$('html, body').animate({
'scrollTop': $('#'+ancher).offset().top - 60
}, 5000);
});
})(jQuery);
</script>
Any New Year's Eve help would be most appreciated so I can get this project wrapped up!
It's possible I don't understand the extent of the question, but I believe you are trying to make it so the href doesn't fire on pages that are wanting to scroll but does on pages that are linking to other pages and not sections within the page itself. Perhaps something like this would work for you:
$(function() {
$('a.page-scroll').bind('click', function(event) {
var $anchor = $(this);
if ($anchor[0].href[0] === '#') {
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top - 60
}, 1000, 'easeInOutExpo');
event.preventDefault();
return false;
} else {
return true;
}
});
});
What this does is look to see that the leading character in the href is a # implying that its a link to a section within itself.
Let me know if that helps and/or if I'm on the right track.
ps: I left the .bind in there because I don't know what version of jQuery you are on, but the newer syntax is to use .on
Happy New Year
Just to append slightly in regards to making it so that deep links to the main page go to the appropriate section but don't have the hash tag:
You can remove that 'hash' variable from window.location, but if you attempt to remove the hashtag entirely, it will cause the browser to refresh. This will also cause the viewer to lose the spot (thus removing the deep link's purpose).
To change the hash tag value (keeps the #):
window.location.hash = ''; // clears the hash tag
To remove the hash tag and its value (clears the # and everything past it):
window.location.href = window.location.href.substr(0, window.location.href.indexOf('#')); // this causes a browser refresh
And if it's not wholly apparent, you would run it on page load
$(document).ready(function() {
if (typeof(window.location.hash) !== 'undefined' && window.location.hash.length > 0) {
window.location.hash = ''; // will clear the hash anytime someone arrives with a hash tag
}
});
For a page with smooth scrolling try to use replaceState().
It will remove the hashtag at anchor link from the browser URL window (without page reloading).
// smooth scrolling
function scrollTo(selectors)
{
if(!$(selectors).length) return;
var selector_top = $(selectors).offset().top - 0;
$('html,body').animate({ scrollTop: selector_top }, 'slow');
}
// do scroll and clear the hash tag
$(window).on('load', function(){
if( typeof(location.hash) !== 'undefined' && location.hash.length ) {
scrollTo(location.hash);
history.replaceState(null, null, location.pathname);
}
});

Categories

Resources