com web/php: fix for "scroll to page anchor": js/common.js
| From: | Peter Cowburn | Date: | Sun, 19 Apr 2015 18:19:57 +0000 |
| Subject: | com web/php: fix for "scroll to page anchor": js/common.js | ||
| Groups: | php.webmaster | ||
| Request: | Send a blank email to php-webmaster+get-21436@lists.php.net to get a copy of this message | ||
Commit: 72f7d11ff5a3de8cdf882f25177b10f8b55bada2
Author: Wes <netmosfera@gmail.com> Sun, 19 Apr 2015 20:19:57 +0200
Parents: 5739e82155fdc760a5b6865ae4f4f22a33e7a06f
Branches: master
Link: http://git.php.net/?p=web/php.git;a=commitdiff;h=72f7d11ff5a3de8cdf882f25177b10f8b55bada2
Log:
fix for "scroll to page anchor"
..and starting an attempt to clean this file.
Changed paths:
M js/common.js
Diff:
diff --git a/js/common.js b/js/common.js
index 84f739b..c4f7b82 100755
--- a/js/common.js
+++ b/js/common.js
@@ -10,40 +10,6 @@ String.prototype.toInt = function()
return parseInt(this);
}
-/* {{{ Hash Scroll */
-var jHtmlBody = $('html, body');
-function scroll(target, interval)
-{
- if (typeof interval == 'undefined') {
- interval = 400;
- }
-
- var hash = target;
- target = $('[id="' + target.substring(1) + '"]');
-
- var offsetTop =
- target.offset().top
- - 52
- - target.css('margin-top').toInt()
- ;
-
- jHtmlBody.animate(
- {scrollTop: offsetTop},
- interval,
- function()
- {
- if (window.location.hash != hash)
- {
- window.location.hash = hash;
- window.scrollTo(0, offsetTop);
- }
- }
- );
-
- return false;
-}
-/* }}} */
-
/** {{{
* jQuery.ScrollTo - Easy element scrolling using jQuery.
* Copyright (c) 2007-2013 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
@@ -54,6 +20,83 @@ function scroll(target, interval)
(function($){var
h=$.scrollTo=function(a,b,c){$(window).scrollTo(a,b,c)};h.defaults={axis:'xy',duration:parseFloat($.fn.jquery)>=1.3?0:1,limit:true};h.window=function(a){return
$(window)._scrollable()};$.fn._scrollable=function(){return this.map(function(){var
a=this,isWin=!a.nodeName||$.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!isWin)return
a;var
b=(a.contentWindow||a).document||a.ownerDocument||a;return/webkit/i.test(navigator.userAgent)||b.compatMode=='BackCompat'?b.body:b.documentElement})};$.fn.scrollTo=function(e,f,g){if(typeof
f=='object'){g=f;f=0}if(typeof
g=='function')g={onAfter:g};if(e=='max')e=9e9;g=$.extend({},h.defaults,g);f=f||g.duration;g.queue=g.queue&&g.axis.length>1;if(g.queue)f/=2;g.offset=both(g.offset);g.over=both(g.over);return
this._scrollable().each(function(){if(e==null)return;var
d=this,$elem=$(d),targ=e,toff,attr={},win=$elem.is('html,body');switch(typeof
targ){case'number':case'string':if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)){targ=both(targ);break}targ=$(targ,this);if(!targ.length)return;case'object':if(targ.is||targ.style)toff=(targ=$(targ)).offset()}$.each(g.axis.split(''),function(i,a){var
b=a=='x'?'Left':'Top',pos=b.toLowerCase(),key='scroll'+b,old=d[key],max=h.max(d,a);if(toff){attr[key]=toff[pos]+(win?0:old-$elem.offset()[pos]);if(g.margin){attr[key]-=parseInt(targ.css('margin'+b))||0;attr[key]-=parseInt(targ.css('border'+b+'Width'))||0}attr[key]+=g.offset[pos]||0;if(g.over[pos])attr[key]+=targ[a=='x'?'width':'height']()*g.over[pos]}else{var
c=targ[pos];attr[key]=c.slice&&c.slice(-1)=='%'?parseFloat(c)/100*max:c}if(g.limit&&/^\d+$/.test(attr[key]))attr[key]=attr[key]<=0?0:Math.min(attr[key],max);if(!i&&g.queue){if(old!=attr[key])animate(g.onAfterFirst);delete
attr[key]}});animate(g.onAfter);function
animate(a){$elem.animate(attr,f,g.easing,a&&function(){a.call(this,targ,g)})}}).end()};h.max=function(a,b){var
c=b=='x'?'Width':'Height',scroll='scroll'+c;if(!$(a).is('html,body'))return
a[scroll]-$(a)[c.toLowerCase()]();var
d='client'+c,html=a.ownerDocument.documentElement,body=a.ownerDocument.body;return
Math.max(html[scroll],body[scroll])-Math.min(html[d],body[d])};function both(a){return typeof
a=='object'?a:{top:a,left:a}}})(jQuery);
/*}}}*/
+
+var PHP_NET = {};
+
+PHP_NET.HEADER_HEIGHT = 52;
+
+/**
+ * Scrolls the page so that the given element will be shown into view.
+ *
+ * @param HTMLElement element The element to show.
+ * @param Number animationDuration Animation duration in milliseconds. Defaults to 400ms.
+ * @param Function callback Function to execute after the animation is complete.
+ * @return void
+ */
+PHP_NET.scrollElementIntoView = function(element, animationDuration, callback){
+ animationDuration = animationDuration || 400;
+ var destTop = $(element).offset().top - PHP_NET.HEADER_HEIGHT;
+ var callbackCalled = false;
+ $('html, body').animate(
+ {scrollTop: destTop},
+ animationDuration,
+ function(){
+ // prevents the callback to be called twice. temporary
+ // solution until further investigation is done
+ if(!callbackCalled) callback();
+ callbackCalled = true;
+ }
+ );
+};
+
+/**
+ * Enables "smooth scrolling to page anchor" for page <a> links.
+ */
+$(document).ready(function(){
+ $('a[href*=#]').click(function(e){
+ var urlTester = document.createElement("a");
+ urlTester.href = this.href;
+ urlTester.hash = location.hash;
+ var targetElement = document.getElementById(this.hash.substr(1));
+ // this <a> targets an id="" on this very page
+ // (the current URL and the target URL
+ // are identic not considering their #hash fragments)
+ if(urlTester.href == location.href && targetElement){
+ // temporarily disable the id="" attribute from such element
+ // so that UA's default scrolling is prevented
+ var wasID = targetElement.id;
+ targetElement.id = "";
+ PHP_NET.scrollElementIntoView(targetElement, null, function(){
+ // restore the id="" attribute to the element
+ targetElement.id = wasID;
+ });
+ }
+ });
+});
+
+/**
+ * Enables "smooth scrolling to page anchor" when page was just loaded.
+ */
+$(document).ready(function(){
+ var targetElm = location.hash ? document.getElementById(location.hash.substr(1)) : null;
+ // if the location.hash points to an element that is actually in the document
+ if(targetElm){
+ // temporarily disable the id="" attribute from such element so that UA's
default scrolling is prevented
+ var wasID = targetElm.id;
+ targetElm.id = "";
+ // so when page is fully loaded and after some delay for a smoother result
+ $(window).load(function(){
+ setTimeout(function(){
+ // animate the scrolling so that the element is shown into viewport
+ PHP_NET.scrollElementIntoView(targetElm, null, function(){
+ // finally restore the id="" attribute to the element
+ targetElm.id = wasID;
+ });
+ }, 300);
+ });
+ }
+});
+
Mousetrap.bind('up up down down left right left right b a enter', function() {
$(".brand img").attr("src", "/images/php_konami.gif");
});
@@ -313,15 +356,6 @@ Mousetrap.bind("l o g o enter", function(e) {
$(".brand img").attr("src", "/images/logo..php?refresh&time="
+ time);
});
-$(window).load(function()
-{
- // Fire our scroll, webkit needs onload
- if (window.location.hash)
- {
- scroll(window.location.hash, 0);
- }
-});
-
function fixTimeout() {
Mousetrap.trigger("m i r r o r enter");
setTimeout(function() {
@@ -376,19 +410,7 @@ $(document).ready(function() {
var $this = $(this);
$this.append("<a class='genanchor' href='#" +
$this.attr('id') + "'> ¶</a>");
});
-
- // Bind events for #[id]
- $(window).on('hashchange', function(e) {
- e.preventDefault();
- return false;
- });
-
- $('a[href^=#]').click(function(e) {
- e.preventDefault();
- scroll($.attr(this, 'href'), 400);
- return false;
- });
-
+
/* Don't load elephpants on browsers that don't support data: URIs.
* Unfortunately, the Modernizr test is asynchronous, so we have to spin
* until it actually gives us a yes or a no. */