Prevent Javascript from executing in Safari - javascript

The following smooth scrolling script messes up my navigation in Safari (anchor tags don't work anymore). I'm a Javascript newbie, could anyone tell me how to detect Safari in this script and prevent it from executing when it detects Safari? Many thanks!
// JavaScript Document
$(document).ready(function() {
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;
$(this).click(function(event) {
event.preventDefault();
$(scrollElem).animate({scrollTop: targetOffset}, 1300, function() { // scroll speed
location.hash = target;
});
});
}
}
});
// use the first element that is "scrollable"
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;
}
}
}
return [];
}
});

var isSafari = navigator.userAgent.indexOf("Safari") > -1 && navigator.userAgent.indexOf("Chrome") == -1;
if(!isSafari){
// do your magic
}

Refer: http://api.jquery.com/jQuery.browser/, to detect browser and execute script only if it is not safari

Perhaps this:
$(document).ready(function()
{
if (navigator.appVersion.match(/WebKit/) && !navigator.vendor.match(/Google/))
{
return;
}
//rest of your code
});
if you have any code outside the $(document).ready callback, you could kill the script by throwing an error, by writing this at the top of your script(s):
if (navigator.appVersion.match(/WebKit/) && !navigator.vendor.match(/Google/))
{
throw new Error('Safari not supported');
}

Related

How to add a padding top to smooth scroll

I have implemented a javascript smooth scroll in a one page site and works perfectly. However, because I have a fixed nav at the top of the page, when the page scrolls to the anchor, the top of the page disappears behind the nav. How can I offset the scroll of 90px?
Here is the code:
var ss = {
fixAllLinks: function() {
// Get a list of all links in the page
var allLinks = document.getElementsByTagName('a');
// Walk through the list
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if ((lnk.href && lnk.href.indexOf('#') != -1) &&
( (lnk.pathname == location.pathname) ||
('/'+lnk.pathname == location.pathname) ) &&
(lnk.search == location.search)) {
// If the link is internal to the page (begins in #)
// then attach the smoothScroll function as an onclick
// event handler
ss.addEvent(lnk,'click',ss.smoothScroll);
}
}
},
smoothScroll: function(e) {
// This is an event handler; get the clicked on element,
// in a cross-browser fashion
if (window.event) {
target = window.event.srcElement;
} else if (e) {
target = e.target;
} else return;
// Make sure that the target is an element, not a text node
// within an element
if (target.nodeName.toLowerCase() != 'a') {
target = target.parentNode;
}
// Paranoia; check this is an A tag
if (target.nodeName.toLowerCase() != 'a') return;
// Find the <a name> tag corresponding to this href
// First strip off the hash (first character)
anchor = target.hash.substr(1);
// Now loop all A tags until we find one with that name
var allLinks = document.getElementsByTagName('a');
var destinationLink = null;
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if (lnk.name && (lnk.name == anchor)) {
destinationLink = lnk;
break;
}
}
if (!destinationLink) destinationLink = document.getElementById(anchor);
// If we didn't find a destination, give up and let the browser do
// its thing
if (!destinationLink) return true;
// Find the destination's position
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent &&
(thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
// Stop any current scrolling
clearInterval(ss.INTERVAL);
cypos = ss.getCurrentYPos();
ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
ss.INTERVAL =
setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',20);
// And stop the actual click happening
if (window.event) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (e && e.preventDefault && e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
}
},
scrollWindow: function(scramount,dest,anchor) {
wascypos = ss.getCurrentYPos();
isAbove = (wascypos < dest);
window.scrollTo(0,wascypos + scramount);
iscypos = ss.getCurrentYPos();
isAboveNow = (iscypos < dest);
if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
// if we've just scrolled past the destination, or
// we haven't moved from the last scroll (i.e., we're at the
// bottom of the page) then scroll exactly to the link
window.scrollTo(0,dest);
// cancel the repeating timer
clearInterval(ss.INTERVAL);
// and jump to the link directly so the URL's right
location.hash = anchor;
}
},
getCurrentYPos: function() {
if (document.body && document.body.scrollTop)
return document.body.scrollTop;
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
if (window.pageYOffset)
return window.pageYOffset;
return 0;
},
addEvent: function(elm, evType, fn, useCapture) {
// addEvent and removeEvent
// cross-browser event handling for IE5+, NS6 and Mozilla
// By Scott Andrew
if (elm.addEventListener){
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent){
var r = elm.attachEvent("on"+evType, fn);
return r;
} else {
alert("Handler could not be removed");
}
}
}
ss.STEPS = 25;
ss.addEvent(window,"load",ss.fixAllLinks);
Thanks in advance for your help!
You can do a calculation when setting the destination coordinates:
// Find the destination's position
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent &&
(thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
//subtract nav from offset position
desty = desty - 90;
if(desty < 0){ desty = 0; }
That being said, using a static number is dangerous business. Might make more sense to calculate minus the header's actual height instead.
Simply make changes in the CSS:
html{
scroll-behavior: smooth;
scroll-padding-top: 50px;
}
This will handle your fixed header issue.

Easy Smooth Scroll Plugin: How do I offset scroll?

I am using the Easy Smooth Scroll Plugin for Wordpress.
Below is the .js file that the plugin uses:
var ss = {
fixAllLinks: function() {
var allLinks = document.getElementsByTagName('a');
for (var i = 0; i < allLinks.length; i++) {
var lnk = allLinks[i];
if ((lnk.href && lnk.href.indexOf('#') != -1) && ((lnk.pathname == location.pathname) || ('/' + lnk.pathname == location.pathname)) && (lnk.search == location.search)) {
ss.addEvent(lnk, 'click', ss.smoothScroll);
}
}
},
smoothScroll: function(e) {
if (window.event) {
target = window.event.srcElement;
} else if (e) {
target = e.target;
} else return;
if (target.nodeName.toLowerCase() != 'a') {
target = target.parentNode;
}
if (target.nodeName.toLowerCase() != 'a') return;
anchor = target.hash.substr(1);
var allLinks = document.getElementsByTagName('a');
var destinationLink = null;
for (var i = 0; i < allLinks.length; i++) {
var lnk = allLinks[i];
if (lnk.name && (lnk.name == anchor)) {
destinationLink = lnk;
break;
}
}
if (!destinationLink) destinationLink = document.getElementById(anchor);
if (!destinationLink) return true;
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent && (thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
clearInterval(ss.INTERVAL);
cypos = ss.getCurrentYPos();
ss_stepsize = parseInt((desty - cypos) / ss.STEPS);
ss.INTERVAL = setInterval('ss.scrollWindow(' + ss_stepsize + ',' + desty + ',"' + anchor + '")', 10);
if (window.event) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (e && e.preventDefault && e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
}
},
scrollWindow: function(scramount, dest, anchor) {
wascypos = ss.getCurrentYPos();
isAbove = (wascypos < dest);
window.scrollTo(0, wascypos + scramount);
iscypos = ss.getCurrentYPos();
isAboveNow = (iscypos < dest);
if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
window.scrollTo(0, dest);
clearInterval(ss.INTERVAL);
location.hash = anchor;
}
},
getCurrentYPos: function() {
if (document.body && document.body.scrollTop) return document.body.scrollTop;
if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop;
if (window.pageYOffset) return window.pageYOffset;
return 0;
},
addEvent: function(elm, evType, fn, useCapture) {
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent) {
var r = elm.attachEvent("on" + evType, fn);
return r;
} else {
alert("Handler could not be removed");
}
}
}
ss.STEPS = 25;
ss.addEvent(window, "load", ss.fixAllLinks);
The live page is here: http://iamjoepro.com/album/promaha/
I have the smooth scroll scrolling to an anchor, but I would like to offset it by the height of my fixed header (120px)
I am no javascript expert, I'm hoping this is easy for someone, but I can't decipher where to add the offset in my .js file?
I had a similar issue and found that the following solution worked for me.
Change the line:
var desty = destinationLink.offsetTop;
to read:
var desty = destinationLink.offsetTop - 120;
(where '120' is the height in pixels of your fixed header)
Then, remove the line:
location.hash = anchor;
(otherwise, the page will scroll to your 120px offset but then return back to the location of the anchor)
Hope this helps!

Custom checkbox not working in Chrome and Safari browser

i used below code for custom checkbox,
HTML
<div class="agree">
<label for="agree_check" class="label_check"><input type="checkbox" class="agree_check" id="agree_check" />Agree</label>
</div>
CSS
.has-js .label_check { padding-left: 34px; }
.has-js .label_check { background: url(../images/box1.png) no-repeat; }
.has-js label.c_on { background: url(../images/box1-with-mark.png) no-repeat; }
.has-js .label_check input { position: absolute; left: -9999px; }
Script
<script type="text/javascript">
var d = document;
var safari = (navigator.userAgent.toLowerCase().indexOf('safari') != -1) ? true : false;
var gebtn = function(parEl,child) { return parEl.getElementsByTagName(child); };
onload = function() {
var body = gebtn(d,'body')[0];
body.className = body.className && body.className != '' ? body.className + ' has-js' : 'has-js';
if (!d.getElementById || !d.createTextNode) return;
var ls = gebtn(d,'label');
for (var i = 0; i < ls.length; i++) {
var l = ls[i];
if (l.className.indexOf('label_') == -1) continue;
var inp = gebtn(l,'input')[0];
if (l.className == 'label_check') {
l.className = (safari && inp.checked == true || inp.checked) ? 'label_check c_on' : 'label_check c_off';
l.onclick = check_it;
};
if (l.className == 'label_radio') {
l.className = (safari && inp.checked == true || inp.checked) ? 'label_radio r_on' : 'label_radio r_off';
l.onclick = turn_radio;
};
};
};
var check_it = function() {
var inp = gebtn(this,'input')[0];
if (this.className == 'label_check c_off' || (!safari && inp.checked)) {
this.className = 'label_check c_on';
if (safari) inp.click();
} else {
this.className = 'label_check c_off';
if (safari) inp.click();
};
};
var turn_radio = function() {
var inp = gebtn(this,'input')[0];
if (this.className == 'label_radio r_off' || inp.checked) {
var ls = gebtn(this.parentNode,'label');
for (var i = 0; i < ls.length; i++) {
var l = ls[i];
if (l.className.indexOf('label_radio') == -1) continue;
l.className = 'label_radio r_off';
};
this.className = 'label_radio r_on';
if (safari) inp.click();
} else {
this.className = 'label_radio r_off';
if (safari) inp.click();
};
};
</script>
now i need to check the checkbox is checked or not.. it is works in FF but not works in Chrome and Safari browser.
if (jQuery('#agree_check').is(':checked')) {
alert("checked");
}
else
{
alert("Not checked");
}
when i checked the checkbox it displays "checked" in FF.. but in Chrome and safari it displays "not checked".
what is the issue?
My solution, working also on server side - codebehind (runat="server" attribute for label and checkbox), consist to add checked/unchecked state for critical browser. Maybe this work for all browser, clearing if statement.
var check_it = function () {
var inp = gebtn(this, 'input')[0];
if (this.className == 'label_check c_off' || (!safari && inp.checked)) {
this.className = 'label_check c_on';
if (chrome) inp.checked = true;
if (safari) inp.click();
} else {
this.className = 'label_check c_off';
if (chrome) inp.checked = false;
if (safari) inp.click();
};
};
Finally i found answer for this, it is just check in another way to make that condition true,
if (jQuery('#agree_check').is(':checked') || (jQuery('div.agree label').hasClass('c_on'))) {
alert("checked");
}
else
{
alert("Not checked");
}
now it's works fine in all browsers.
Thanks,
Ravichandran

JavaScript Smooth Scroll not working on iPhone

For some reason, this doesn't work on the iPhone and some other mobile devices. This code makes it where when you click on a link such as..
About Section
..it will smooth scroll to the id of "about". How can I fix this issue?
I am currently using this on http://www.xblakej.com/
$(document).ready(function() {
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;
$(this).click(function(event) {
event.preventDefault();
$(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
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;
}
}
}
return [];
}
});

jQuery load and append issue

im getting a little issue here. I have a wordpress theme that i need to add an infinite scroll effect. Ok, its working, but it doesnt look work properly. I set the current page and the number of pages, but it keeps adding the second page every time i reach the bottom.
What im doing wrong?
Ps.: I have tried the inifite-scroll plugin for wordpress, and it dont works with my template. Thanks!
$(function() {
var currentPage = 1;
var numPages = Math.ceil(pages / 4);
var browserName = "";
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf("opera") != -1) {
browserName = "opera";
} else if (ua.indexOf("msie") != -1) {
browserName = "msie";
} else if (ua.indexOf("safari") != -1) {
browserName = "safari";
} else if (ua.indexOf("mozilla") != -1) {
if (ua.indexOf("firefox") != -1) {
browserName = "firefox";
} else {
browserName = "mozilla";
}
}
$(window).scroll(function() {
if (browserName != "safari") {
var curScrollPos = $('html').scrollTop();
}
else {
var curScrollPos = $('body').scrollTop();
}
if (curScrollPos > 218) {
$("#sidebar").addClass("open");
}
if (curScrollPos < 218) {
$("#sidebar").removeClass("open");
}
var scrollBottom = $(document).height() - $(window).height() - $(window).scrollTop();
if (scrollBottom == 0) {
if (currentPage < numPages) {
$("<div>").load("page/" + (currentPage + 1), function() {
var newPosts = $(this).find("#content").html();
$("#content").append(newPosts);
});
currentPage++;
}
else {
}
}
});
// Infinite Scroll
});​
Possibly try this:
$("<div>").load("page/"+(currentPage+1), function() {
var newPosts = $(this).find("#content").html();
$("#content").append(newPosts);
currentPage++;
});
And remove the currentPage++;

Categories

Resources