I'm having an odd problem on Safari (Mac OS only, Windows works fine), where my smooth scroll is not scrolling. It just jumps to the link, but works in all other browsers, even on windows Safari.
My jQuery is
<script type="text/javascript">
(function($){
$.extend({
smoothAnchors : function(speed, easing, redirect){
speed = speed || "slow";
easing = easing || null;
redirect = (redirect === true || redirect == null) ? true : false;
$("a").each(function(i){
var url = $(this).attr("href");
if(url){
if(url.indexOf("#") != -1 && url.indexOf("#") == 0){
var aParts = url.split("#",2);
var anchor = $("a[name='"+aParts[1]+"']");
if(anchor){
$(this).click(function(){
if($(document).height()-anchor.offset().top >= $(window).height()
|| anchor.offset().top > $(window).height()
|| $(document).width()-anchor.offset().left >= $(window).width()
|| anchor.offset().left > $(window).width()){
$('html, body').animate({
scrollTop: anchor.offset().top,
scrollLeft: anchor.offset().left
}, speed, easing, function(){
if(redirect){
window.location = url
}
});
}
return false;
});
}
}
}
});
}
});
})(jQuery);
</script>
and my HTML looks like this
<nav id="nav">
<ul id="navigation">
<li> ABOUT</li>
<a name="About"></a>
If anybody knows what the issue, please let me know!
Much appreciated.
Works great for me!
(function($) {
$.fn.SmoothAnchors = function() {
function scrollBodyTo(destination, hash) {
// Change the hash first, then do the scrolling. This retains the standard functionality of the back/forward buttons.
var scrollmem = $(document).scrollTop();
window.location.hash = hash;
$(document).scrollTop(scrollmem);
$("html,body").animate({
scrollTop: destination
}, 200);
}
if (typeof $().on == "function") {
$(document).on('click', 'a[href^="#"]', function() {
var href = $(this).attr("href");
if ($(href).length == 0) {
var nameSelector = "[name=" + href.replace("#", "") + "]";
if (href == "#") {
scrollBodyTo(0, href);
}
else if ($(nameSelector).length != 0) {
scrollBodyTo($(nameSelector).offset().top, href);
}
else {
// fine, we'll just follow the original link. gosh.
window.location = href;
}
}
else {
scrollBodyTo($(href).offset().top, href);
}
return false;
});
}
else {
$('a[href^="#"]').click(function() {
var href = $(this).attr("href");
if ($(href).length == 0) {
var nameSelector = "[name=" + href.replace("#", "") + "]";
if (href == "#") {
scrollBodyTo(0, href);
}
else if ($(nameSelector).length != 0) {
scrollBodyTo($(nameSelector).offset().top, href);
}
else {
// fine, we'll just follow the original link. gosh.
window.location = href;
}
}
else {
scrollBodyTo($(href).offset().top, href);
}
return false;
});
}
};
})(jQuery);
$(document).ready(function() {
$().SmoothAnchors();
});
https://github.com/alextrob/SmoothAnchors
Related
var tab = null;
var menuSelector = null;
jQuery(function ($) {
console.log('test');
//howtos tab
function changeMenuSelector() {
if ($( document ).width() > 967) {
menuSelector = 'top-menu-nav';
} else {
menuSelector = 'mobile_menu';
}
}
changeMenuSelector();
$( window ).resize(function() {
changeMenuSelector();
});
$('#'+menuSelector+' a[href*="howtos"]').on('click', function(event){
var e = event;
var $ = jQuery;
setTimeout(function () {
e.preventDefault();
console.log('pluto');
window.localStorage.setItem('tab', 'et_pb_tab_0');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
window.localStorage.removeItem('tab');
}
},1000);});
$('#'+menuSelector +' a[href*="projects"]').on('click', function(e){
e.preventDefault();
console.log('pluto');
localStorage.setItem('tab', 'et_pb_tab_1');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
localStorage.removeItem('tab');
}
});
$('#'+menuSelector +' a[href*="reviews"]').on('click', function(e){
e.preventDefault();
console.log('pluto');
localStorage.setItem('tab', 'et_pb_tab_2');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
localStorage.removeItem('tab');
}
});
$('#'+menuSelector +' a[href*="elearning"]').on('click', function(e){
e.preventDefault();
console.log('pluto');
localStorage.setItem('tab', 'et_pb_tab_3');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
localStorage.removeItem('tab');
}
});
$('#'+menuSelector +' a[href*="others"]').on('click', function(e){
e.preventDefault();
console.log('pluto');
localStorage.setItem('tab', 'et_pb_tab_4');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
localStorage.removeItem('tab');
}
});
if (!!localStorage.getItem('tab')) {
tab = localStorage.getItem('tab');
console.log(tab);
setTimeout(function(){$("li."+tab+">a")[0].click();}, 1)
$("html, body").animate({ scrollTop: $('.et_pb_module.et_pb_tabs.et_pb_tabs_0').offset().top },
1000);
localStorage.removeItem('tab');
}
});
I have created a script to show tabs in Divi when you click on a menu entry. Divi does not use ids and hrefs for this, so I had to use a script.
The problem that I am facing is that this script that I made does not work with Divi's mobile menu.
I checked if menuSelector changed properly and if changeMenuSelector got executed as expected.
Furthermore, $('#'+menuSelector+' a[href*="howtos"]').length returns 1 in console and if I run $('#'+menuSelector+' a[href*="howtos"]')[0] in console I obtain the expected DOM element whehter I have the browser window sized for mobile or for desktop devices.
I also tried using setTimeout in case the issue was that it needed some time to accomplish an earlier action without any luck.
Therefore, is there anyone that could tell me why this does not work when the website is running in mobile mode?
I solved the issue by refactoring the code like this:
jQuery(function ($) {
console.log('test');
var tab = null;
var menuSelector = null;
var guard = false;
function changeMenuSelector() {
if ($(document).width() > 967) {
menuSelector = 'top-menu-nav';
guard = false;
initEventListeners(guard);
} else {
menuSelector = 'mobile_menu';
guard = true;
initEventListeners(guard);
}
}
function initEventListeners(guard) {
var localGuard = null;
if (localGuard != guard) {
var hrefs = ['howtos', 'projects', 'reviews', 'elearning', 'others'];
hrefs.forEach(
function (element, index, array) {
$('#' + menuSelector + ' a[href*="' + element + '"]').off();
console.log(element);
$('#' + menuSelector + ' a[href*="' + element + '"]').on('click', function (e) {
e.preventDefault();
console.log('pluto');
window.localStorage.setItem('tab', 'et_pb_tab_' + index);
if (window.location.pathname.indexOf('blog-posts') === -1) {
window.location.href = 'http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li." + tab + ">a")[0].click();
$("html, body").animate({ scrollTop: $('.et_pb_module.et_pb_tabs.et_pb_tabs_0').offset().top },
1000);
window.localStorage.removeItem('tab');
}
});
});
localGuard = guard;
}
}
changeMenuSelector();
initEventListeners();
$(window).resize(function () {
changeMenuSelector();
});
if (!!localStorage.getItem('tab')) {
tab = localStorage.getItem('tab');
console.log(tab);
setTimeout(function(){$("li."+tab+">a")[0].click();}, 1)
$("html, body").animate({ scrollTop: $('.et_pb_module.et_pb_tabs.et_pb_tabs_0').offset().top },
1000);
localStorage.removeItem('tab');
}
});
i've got problem with scroll script for menu on my github page. Each browser constantly block js script due to pop-up window. Everything works like a charm on localhost and mobile devices like tablet or smartphone
There's code and i am wondering how to fix that issue cuz its just nav scroll script with anchors and i have no idea why whole browsers are recognizing it as pop-up window
$(function() {
$('#sidenav a').click(function (e) {
e.preventDefault();
simpleScrollTo($(this).attr('href'), 500);
});
$(window).scroll(function() {
var ds = $(document).scrollTop();
if (ds == 0) {
$('#sidenav a').removeClass('active');
$('#sidenav a[href=#' + $('.anchor').eq(0).attr('id') + ']').addClass('active');
return false;
}
$('.anchor').each(function() {
var $this = $(this), offset = Math.round($this.offset().top), height = $this.outerHeight() + offset;
if (offset <= ds && height > ds) {
$('#sidenav a').removeClass('active');
$('#sidenav a[href=#' + $this.attr('id') + ']').addClass('active');
if (document.location.hash != '#' + $this.attr('id')) {
var cds = $(document).scrollTop();
document.location.hash = $this.attr('id');
$(document).scrollTop(cds);
}
return false;
}
return true;
});
return true;
});
var ds = $(window).scrollTop();
if (ds == 0) {
$('#sidenav a').removeClass('active');
$('#sidenav a[href=#' + $('.anchor').eq(0).attr('id') + ']').addClass('active');
} else {
$('.anchor').each(function() {
var $this = $(this), offset = Math.round($this.offset().top), height = $this.outerHeight() + offset;
if (offset <= ds && height > ds) {
$('#sidenav a').removeClass('active');
$('#sidenav a[href=#' + $this.attr('id') + ']').addClass('active');
return false;
}
return true;
});
}
if (document.location.hash != '') {
var el = $(document.location.hash);
if (el.length > 0) {
$(window).scrollTop(0);
$(window).load(function() {
simpleScrollTo('#' + el.attr('id'), 1000);
});
}
}
});
function simpleScrollTo(element, speed) {
$('html:not(:animated), body:not(:animated)').animate({scrollTop: $(element).offset().top}, speed, function() {
document.location.hash = $(element).attr('id');
});
}
I've forgotten to mention. My github page is shown as "unsafe". When i allow to use unsafe script then it works. Is it caused by Github security restriction?
Solved, hadn't noticed there was "http" link for jquery instead of "https" :)
I'm looking for the way to translate this block of code from jQuery to pure javascript. Is it possible?
jQuery(".menu2").each(function(){
$menu = jQuery(this);
$menu.find("li").unbind('mouseenter mouseleave').filter(".deeper").children("span.separator").addClass("parent");
$menu.find("li.deeper>a.parent, li.deeper>span.separator").unbind('click').bind('click', function(e) {
e.preventDefault();
jQuery(this).parent("li").children("ul").animate({height: 'toggle'}, 300, "jswing");
});
$menu.find("li a.parent > span.linker").click(function(){
if((typeof jQuery(this).parent().attr("href") != 'undefined') && jQuery(this).parent().attr("href") != "#"){
jQuery(this).parent().unbind('click');
myLink = jQuery(this).parent().attr("href");
window.location.href = myLink;
}
});
}
Thanks!
Of course it's possible. Whether it's a good idea or not is debatable, but here...
[].forEach.call(document.querySelectorAll(".menu2"),function(menu){
[].forEach.call(menu.getElementsByTagName("li"),function(li) {
li.__events = li.__events || {};
if( li.__events.mouseenter) {
li.removeEventListener('mouseenter',li.__events.mouseenter);
delete li.__events.mouseenter;
}
if( li.__events.mouseleave) {
li.removeEventListener('mouseleave',li.__events.mouseleave);
delete li.__events.mouseleave;
}
if( li.className.match(/\bdeeper\b/)) {
[].forEach.call(li.querySelectorAll("span.separator"),function(span) {
if( !span.className.match(/\bparent\b/)) span.className += " match";
});
}
});
[].forEach.call(menu.querySelectorAll("li.deeper>a.parent, li.deeper>span.separator"),function(elem) {
elem.__events = elem.__events || {};
if( elem.__events.click) {
elem.removeEventListener('click',elem.__events.click);
delete elem.__events.click;
}
elem.addEventListener('click',elem.__events.click = function(e) {
[].forEach.call(this.parentNode.getElementsByTagName('ul'),function(ul) {
if( ul.style.height == "auto") ul.style.height = "0px";
else ul.style.height = "auto";
// TODO: Implement animation here
});
return false;
},false);
});
[].forEach.call(menu.querySelectorAll("li a.parent>span.linker"),function(elem) {
elem.__events = elem.__events || {};
if( elem.__events.click) {
elem.removeEventListener('click',elem.__events.click);
delete elem.__events.click;
}
elem.addEventListener('click',elem.__events.click = function(e) {
if( this.parentNode.getAttribute("href") != "#") {
window.location.href = this.parentNode.href;
}
return false;
},false);
});
});
... I think it's fairly obvious why people use jQuery. Of course, I would have my own toolbox to make a lot of this code easier to manage ;)
I use the following script for a smooth scroll effect minus an amount of pixel on one page. The problem is, i click on one anchor link, the scroll effects works as it should but then i scroll back to the top of the page where the links are and click on another page. It doesnt work. I just copied the script from a webpage my javascript is very bad.
Thx for your help.
function filterPath(string) {
return string
.replace(/^\//,'')
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
}
var locationPath = filterPath(location.pathname);
var scrollElem = scrollableElement('html', 'body');
$('a[href*=#]').each(function() {
var thisPath = filterPath(this.pathname) || locationPath;
if ( locationPath == thisPath
&& (location.hostname == this.hostname || !this.hostname)
&& this.hash.replace(/#/,'') ) {
var $target = $(this.hash), target = this.hash;
if (target) {
var targetOffset = $target.offset().top - 70;
$(this).click(function(event) {
if(event != 'undefined') {
event.preventDefault();}
$(scrollElem).animate({scrollTop: targetOffset}, 400, function(e) {
e.preventDefault();
location.hash = target;
});
});
}
}
});
function scrollableElement(els) {
for (var i = 0, argLength = arguments.length; i <argLength; i++) {
var el = arguments[i],
$scrollElement = $(el);
if ($scrollElement.scrollTop()> 0) {
return el;
} else {
$scrollElement.scrollTop(1);
var isScrollable = $scrollElement.scrollTop()> 0;
$scrollElement.scrollTop(0);
if (isScrollable) {
return el;
}
}
}
}
There's an error in the code.
Where it says:
$(scrollElem).animate({scrollTop: targetOffset}, 400, function(e) {
e.preventDefault();
location.hash = target;
});
You are calling preventDefault() on nothing. Leave it as this and it will work:
$(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
location.hash = target;
});
The error was at the beggining of the code. Instead of using an each loop, you should add a clickevent to the anchor elements. By using the each loop, you only add the click event once, and thus on the second click the event is undefined and the code runs into an error.
Here's your code rewritten as a click event:
$('a[href*=#]').click(function(e){
var thisPath = filterPath(this.pathname) || locationPath;
if ( locationPath == thisPath && (location.hostname == this.hostname || !this.hostname) && this.hash.replace(/#/,'') ) {
var $target = $(this.hash), target = this.hash;
if (target) {
var targetOffset = $target.offset().top - 70;
$(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
if( e != 'undefined' ) {
e.preventDefault();
}
location.hash = target;
});
}
}
});
Hope this helps ;-)
I'm using a smooth scroll script for a site I'm currently working on, and I've got a really annoying problem what I've experienced before with the same script. It works nice and smoothly but when I click on one of the navigation points what should lead me to the div(or a) I'm trying to target, it shows me the targeting area for like 0.1 seconds, and then it starts to scroll. It doesn't happen everytime, but often enough to be annoying. How could I prevent this? Here is the script I'm talking about:
$(window).load(function(){
$(".contactLink").click(function(){
if ($("#contactForm").is(":hidden")){
$("#contactForm").slideDown("slow");
}
else{
$("#contactForm").slideUp("slow");
}
});
});
function closeForm(){
$("#messageSent").show("slow");
setTimeout('$("#messageSent").hide();$("#contactForm").slideUp("slow")', 2000);
}
$(window).load(function() {
function filterPath(string) {
return string
.replace(/^\//,'')
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
}
$('a[href*=#]').each(function() {
if ( filterPath(location.pathname) == filterPath(this.pathname)
&& location.hostname == this.hostname
&& this.hash.replace(/#/,'') ) {
var $targetId = $(this.hash), $targetAnchor = $('[name=' + this.hash.slice(1) +']');
var $target = $targetId.length ? $targetId : $targetAnchor.length ? $targetAnchor : true;
if ($target) {
var targetOffset = $target.offset().top - 110;
$(this).click(function() {
$('html, body').animate({scrollTop: targetOffset}, 1400);
var d = document.createElement("div");
d.style.height = "101%";
d.style.overflow = "hidden";
document.body.appendChild(d);
window.scrollTo(0,scrollToM);
setTimeout(function() {
d.parentNode.removeChild(d);
}, 10);
return false;
});
}
}
});
});
setTimeout(function() {
d.parentNode.removeChild(d);
}, 10);
return false;
});
move the return false out of the setTimeOut
Found the solution:
$(this).click(function(e) {
e.preventDefault();
Now it rolls fine.