Mobiles not detecting anchor change to toggle menu - javascript

Hi I have made a website using fullpage.js which is great and scrolls between sections (full pages) but on mobiles it can be difficult to navigate so I have made it continuos scrolling when the width is under 640px.
I have a menu which toggles down after the anchor changes from the main page and toggles back when the anchor is the main page. this is because there is a built in menu on the main page so it doesn't need a 2nd.
On mobiles after making it continuos scrolling this feature doesn't work but it still works on computer browsers. I don't know whether I am over looking something or if I could write a better script for the menu toggle.
Please look at www.themeltingpotkitchen.com to see what I mean.
Here is my menu js. I will point out that if your tap links via menus it will work but not by scrolling :s
// detect anchor change and hide or show menu
function locationHashChanged() {
var hash = location.hash;
var id = hash.replace(/^#/, '');
// logic
if (id == 'Home') {
$("#nav_hide").slideUp();
} else if (id == 'About') {
$("#nav_hide").slideDown();
} else if (id == 'Trailer') {
$("#nav_hide").slideDown();
} else if (id == 'Food') {
$("#nav_hide").slideDown();
} else if (id == 'Contact') {
$("#nav_hide").slideDown();
}
}
window.onhashchange = locationHashChanged;
// if loaded page is home hide menu
var hashVal = window.location.hash.split("#")[1];
var p = window.location.pathname.split("/");
var filename = p[p.length-1];
if(hashVal == 'Home', filename == 'index.html') {
$("#nav_hide").hide();
}

You should not be using the change in the URL to trigger any action. That's not the way to do it with fullPage.js.
You should be using the callbacks provided by the plugin such as onLeave or afterLoad.
Or you could even use the class added to the body element as suggested in this tutorial
The reason for it is because fullPage.js doesn't change the location hash but uses the HTML5 History API for mobile phones due to problems with the location hash behaviour in Mobile Chrome:
//Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :)
if (isTouchDevice || isTouch) {
history.replaceState(undefined, undefined, '#' + url);
} else {
var baseUrl = window.location.href.split('#')[0];
window.location.replace(baseUrl + '#' + url);
}

Related

Wordpress theme blocks target="_blank" on links. How do I reactivate it for some external links?

I'm building a photography portfolio website on Wordpress using this theme: http://wpshower.com/themes/expositio/ . The theme hasn't been updated in years but still works smoothly. I have an issue with assigning target="_blank" to some external links though. The option is there but it has no effect whatsoever.
I've looked for advice and have tried every available plugin that addresses the problem, with the best result being opening the external link in both a new tab and the current tab.
I've looked into all the theme files, they are not many, and thinking that this is a javascript issue, I have identified the following code. It deals with the mobile menu animations but it's the only mention of links.
It was also discussed in a similar thread in here: Wordpress navbar links using href="#" not working as a dummy link
$('a').on('click', function(e) {
e.preventDefault();
var _this = $(this);
// close mobile menu if it's open, redirect otherwise
if (_body.hasClass('toggled-on') && _this.parents('#page').length == 1
&& _this.parents('#primary-navigation').length == 0
) {
load_effect.menuOff();
} else {
load_effect.loader.show();
var href = $(this).attr('href');
$('.site').css('opacity', 0);
setTimeout(function() {
window.location = href;
}, load_effect.duration);
}
Finally, here is website using the same theme where the external links do open in a new tab: http://www.tokyogoodidea.com/
I'd be grateful for any advice on solving this little glitch. I'm not good at all with js and don't know what to change.
Here's my project's link: http://one.clrblnd.com/
Thanks in advance.
There seems to be no reliable way to open a new tab in Javascript (a quick search tells it could be tricky), and the code indeeed looks like it is blocking a new page being opened. You can probably try if this works.
Firstly after this line
var href = $(this).attr('href');
add another line that says (this line gets the value of target attribute/properties from the tag, and assumed to be _self if undefined)
var target = $(this).prop('target') || '_self';
Then look for this line
$('.site').css('opacity', 0);
What it does is to make the whole page blank essentially. You may want to do something with this, for example wrap it in a if statement so it doesn't execute when target="_blank". A quick way to fix it is by replacing it to
target === '_blank' || $('.site').css('opacity', 0);
Next replace (just a few lines after the previous one)
window.location = href;
with
window.open(href, target)
The respective block should look like
load_effect.loader.show();
var href = $(this).attr('href');
var target = $(this).prop('target') || '_self';
target === '_blank' || $('.site').css('opacity', 0);
setTimeout(function() {
window.open(href, target)
}, load_effect.duration);
This is asuming window.open works as expected (documentation is here). What happens in the code is that the author stopped the default behavior after clicking a link with
e.preventDefault();
in order to allow some fancy animation to complete before the browser proceeds to load the intended page. However by simplifying the page load with
window.location = href;
it ignores the target attribute/property of the respective <a /> tag.

Add/remove class to video element

I'm working on a kiosk-style web page to display a menu of options. Clicking on a title opens a fullscreen video which then closes back to the menu when the video ends.
To keep the page clean, I'd like to hide the video element until the video is actually called by a click. I did this with a CSS class. The video opens fullscreen and when finished, closes and adds the hide class again.
Working script
$(document).ready(function() {
$('.cell').on('click', function() {
var element = this.getElementsByTagName('video');
var m = element[0].getAttribute('id');
console.log(m);
var v = document.getElementById(m);
if (v.webkitRequestFullscreen) {
v.className = "";
v.webkitRequestFullscreen();
}
v.play();
$("#" + m).on("ended", function() {
this.webkitExitFullscreen();
this.className = "hide";
});
})
})
I'm running into a problem of the video not hiding if the user exits full screen video on their own. I tried using $("#" + m).on("ended" || "resize", function()... based on the HTML5 video API, but that didn't work. I'd also considered disabling clicks or overlaying a full-screen div to grab any clicks and force the video to play all the way through, but that seems shady to me. Any ideas on how to approach this?
Here's a CodePen demo of the content and script
Space separated list:
$("#" + m).on("ended resize"
To make it work you might need this trick: How to detect DIV's dimension changed?
Update: I was able to catch the fullscreen event:
$(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function(e){
console.log("fullscreen change");
});

Prevent browser scroll to hash on document ready, then animate slowly

I have a problem with my script.
It was working perfectly until last week, when my client talked about it.
My website has some links with an hash added to scroll smoothly to id when page is loaded. Now it doesn't scroll smoothly anymore. I did check my variables, and it gets the hash has id (e.g. #content) and also the height of the header nav.
I can't find the problem.
Here's the script:
if (window.location.hash) {
//bind to scroll function
$(document).scroll( function() {
var hash = window.location.hash;
//var hashName = hash.substring(1, hash.length);
var element;
//if element has this id then scroll to it
if ($(hash).length !== 0) {
element = $(hash);
}
//if we have a target then go to it
if (element !== undefined) {
window.scrollTo(0);
}
//unbind the scroll event
$(document).unbind("scroll");
$("html, body").animate({scrollTop: ($(element).offset().top - $('header nav ul').height()) }, 500);
});
}
Thanks in advance
Native scrollers dont work nice. Handling different browsers and mobile devices is realy difficult. Use iScroll my friend http://cubiq.org/iscroll-5 .. it works like a charm and comes with a lot of features!!!

Track sections of content on single page as virtual page view in Google Analytics

I'm trying to track when a "section" of a single page website is in the viewport and send that to Google Analytics as a virtual page view.
A few notes:
I'm not a javascript coder (or any coder for that matter...)
Already calling jquery 1.8
Google analytics is working on the site and tracking menu clicks and time on page etc all very well.
The sections are defined by div's with unique IDs e.g. #section-about
I'm now trying to capture tracking info for people that do not use the menu
but just scroll down the page and view each section
I'd only want to capture a "page view" if the section was in view for longer than say
2 seconds.
I found this which looks to get me part of the way there but I'm at a loss at so how to customise it:
$(function(){
var tracking_active = '';
var tracking = {
'section-approach': '/testing/section-approach',
'section-about': '/testing/section-about'
};
function scrollTrackPageview(){
var section = '';
$.each(tracking, function(key, value) {
section = value;
if($(window).scrollTop() >= $('.'+key).offset())
return false;
return true;
});
if(!section || section == tracking_active)
return false;
_gaq.push(['_trackPageview', section]);
//console.log('Bereich: '+section);
tracking_active = section;
}
scrollTrackPageview();
$(window).on("scroll", scrollTrackPageview);
});
Thanks in advance for the time and effort.

Prevent automatic browser scroll on refresh

If you go to a page a and scroll around then refresh the page will refresh at the spot where you left it. This is great, however this also occurs on pages where there is a anchor location in the url. An example would be if you clicked on a link http://example.com/post/244#comment5 and refreshed the page after looking around you would not be at the anchor and the page jumps around. Is there any way to prevent this with javascript? So that no-matter-what you would always navigate to the anchor.
On Chrome, even if you force scrollTop to 0 it will jump afterwards after the first scroll event.
You should bind the scroll to this:
$(window).on('beforeunload', function() {
$(window).scrollTop(0);
});
So the browser is tricked to believe that it was on the beginning before the refresh.
To disable automatic scroll restoration just add this tag to head section.
<script>history.scrollRestoration = "manual"</script>
Supported by all modern browsers
After number of failures finally I managed to do the trick. anzo is correct here as using beforeunload will make the page jump to top when a user reloads the page or clicks a link. So unload is the clearly way to do this.
$(window).on('unload', function() {
$(window).scrollTop(0);
});
Javascript way(Thanks ProfNandaa):
window.onunload = function(){ window.scrollTo(0,0); }
EDIT: 16/07/2015
The jump issue is still there with Firefox even with unload event.
This solution is no longer recommended due to changes in browser behavior. See other answers.
Basically, if an anchor is used we bind to the windows scroll event. The idea being that the first scroll event has to belong to the automatic repositioning done by the browser. When this occurs we do our own repositioning and then remove the bound event. This prevents subsequent page scrolls from borking the system.
$(document).ready(function() {
if (window.location.hash) {
//bind to scroll function
$(document).scroll( function() {
var hash = window.location.hash
var hashName = hash.substring(1, hash.length);
var element;
//if element has this id then scroll to it
if ($(hash).length != 0) {
element = $(hash);
}
//catch cases of links that use anchor name
else if ($('a[name="' + hashName + '"]').length != 0)
{
//just use the first one in case there are multiples
element = $('a[name="' + hashName + '"]:first');
}
//if we have a target then go to it
if (element != undefined) {
window.scrollTo(0, element.position().top);
}
//unbind the scroll event
$(document).unbind("scroll");
});
}
});
This works for me.
//Reset scroll top
history.scrollRestoration = "manual"
$(window).on('beforeunload', function(){
$(window).scrollTop(0);
});
Here's a a more general approach. Instead of trying to prevent the browser from scrolling (or jumping to the top as it would look like) I just restore the previous position on the page.
I.e. I'm recording the current y-offset of the page in localStorage and scroll to this position once the page has loaded.
function storePagePosition() {
var page_y = window.pageYOffset;
localStorage.setItem("page_y", page_y);
}
window.addEventListener("scroll", storePagePosition);
var currentPageY;
try {
currentPageY = localStorage.getItem("page_y");
if (currentPageY === undefined) {
localStorage.setItem("page_y") = 0;
}
window.scrollTo( 0, currentPageY );
} catch (e) {
// no localStorage available
}
You can just put a # at the end so the page will load at the top.
Works on all browsers, mobile and desktop, because it is so simple.
$(document).ready(function() {
var url = window.location.href;
console.log(url);
if( url.indexOf('#') < 0 ) {
window.location.replace(url + "#");
} else {
window.location.replace(url);
}
});
// This loads the page with a # at the end.
this works absolutely fine. Nice and clean javascript
var objDiv = document.getElementById("chatbox");
if ( window.history.replaceState ) {
objDiv.scrollTop = objDiv.scrollHeight;
window.history.replaceState( null, null, window.location.href );
}
You should be able to.
Onload, check if window.location.hash has a value. If it does, grab the element with an id that matches the hash value. Find the position of the element (recursive calls to offsetTop/offsetLeft) and then pass those values into the window.scrollTo(x, y) method.
This should scroll the page to the desired element.

Categories

Resources