Kaskus-Head-Scroller

simple script do scroll to top at header (*.kaskus.co.id)

  1. // ==UserScript==
  2. // @name Kaskus-Head-Scroller
  3. // @namespace http://userscripts.org/scripts/show/Kaskus-Head-Scroller
  4. // @include *.kaskus.co.id/*
  5. // @version 0.1
  6. // @dtversion 1404260001
  7. // @timestamp 1398534731798
  8. // @description simple script do scroll to top at header (*.kaskus.co.id)
  9. // @author tuxie.forte;
  10. // @license (CC) by-nc-sa 3.0
  11. //
  12. // -!--latestupdate
  13. //
  14. // v0.1 - 2014-04-26
  15. // init
  16. //
  17. // -/!latestupdate---
  18. //
  19. //
  20. //
  21. // ==/UserScript==
  22. //
  23.  
  24. (function(){
  25. // Initialize Global Variables
  26. var gvar=function() {};
  27.  
  28. /*
  29. window.alert(new Date().getTime());
  30. */
  31. //========-=-=-=-=--=========
  32. gvar.__DEBUG__ = !1; // development
  33. //========-=-=-=-=--=========
  34.  
  35.  
  36.  
  37. // =====
  38. // START
  39. function start_Main(){
  40. var $el = $D(gvar.target_selector);
  41. if( !$el ){
  42. clog('missing target node');
  43. return;
  44. }
  45. if( !gvar.is_mobile )
  46. $el = $el[0];
  47. else{
  48. GM_addGlobalStyle(rSRC.getMobCSS_patch(), 'patch_head', 1);
  49.  
  50. if( $D('#mqr-content-wrapper') ){ // mqr already has something todo w/ design and event
  51.  
  52. }
  53. else{
  54. GM_addGlobalStyle(rSRC.getMobCSS(), 'fixed_head', 1);
  55.  
  56. Dom.Ev(window, 'scroll', function(){
  57. var nVScroll = document.documentElement.scrollTop || document.body.scrollTop,
  58. el_ = $D('#site-header');
  59. if( nVScroll > 0 ){
  60. !hasClass('fx', el_) && addClass('fx', el_);
  61. }
  62. else{
  63. removeClass('fx', el_);
  64. }
  65. });
  66. }
  67. }
  68.  
  69. if( $el )
  70. _o('click', $el, function(e){
  71. var el = e.target||e;
  72. if(el && el.nodeName == 'A')
  73. return !1;
  74.  
  75. nat_scrollTo(document.body, 0, 234);
  76. });
  77. }
  78.  
  79.  
  80.  
  81. // -
  82. // -
  83. // -
  84. // -
  85. //=========
  86. // code below should adapting current QR Engine for this plugins works
  87. // leave code below as wot it is, as long you know what todo
  88. //========= Common Functions && Global Var Init ====
  89. // static routine
  90. function isDefined(x) { return !(x == null && x !== null); }
  91. function isUndefined(x) { return x == null && x !== null; }
  92. function isString(x) { return (typeof(x)!='object' && typeof(x)!='function'); }
  93. function trimStr(x) { return (typeof(x)=='string' && x ? x.replace(/^\s+|\s+$/g,"") : '') };
  94.  
  95. function _o(m,e,f){Dom.Ev(e,m,function(e){typeof(f)=='function'?f(e):void(0)});}
  96. function hasClass(cName, Obj){
  97. if(cName=="" || !cName) return;
  98. var re, cCls = (Obj.className ? Obj.className : '');
  99. if( !cCls )
  100. return !1;
  101. else{
  102. re = new RegExp('\\b'+cName+'\\b', "i");
  103. return re.test( cCls );
  104. }
  105. }
  106. function addClass(cName, Obj){
  107. if(cName=="") return;
  108. var neocls = (Obj.className ? Obj.className : '');
  109. if(neocls.indexOf(cName)!=-1) return;
  110. neocls+=(neocls!=''?' ':'')+cName;
  111. Obj.setAttribute('class', neocls);
  112. }
  113. function removeClass(cName, Obj){
  114. if(!cName || !Obj) return;
  115. var neocls, rmvclss = getAttr('class', Obj);
  116. neocls = getAttr('class', Obj);
  117. rmvclss = cName.split(' ');
  118. for(var i=0; i<rmvclss.length; ++i)
  119. neocls = neocls.replace(rmvclss[i], '');
  120. neocls = trimStr(neocls);
  121. setAttr('class', neocls, Obj);
  122. }
  123. function createTextEl(a) {
  124. return document.createTextNode(a)
  125. }
  126. function createEl(type, attrArray, html){
  127. var node = document.createElement(type);
  128. for (var attr in attrArray)
  129. if (attrArray.hasOwnProperty(attr))
  130. node.setAttribute(attr, attrArray[attr]);
  131. if(html) node.innerHTML = html;
  132. return node;
  133. }
  134. function getAttr(name, Obj){
  135. if("string" === typeof name && "object" === typeof Obj && Obj)
  136. return Obj.getAttribute(name)||'';
  137. else
  138. return;
  139. }
  140. function setAttr(name, value, Obj){
  141. if("string" === typeof name && "object" === typeof Obj)
  142. return Obj.setAttribute(name, value);
  143. }
  144.  
  145.  
  146. var GM_addGlobalStyle = function (a, b, c) {
  147. var d, e;
  148. if (a.match(/^https?:\/\/.+/)) {
  149. d = createEl("link", { type: "text/css", rel:'stylesheet', href:a });
  150. }else{
  151. d = createEl("style", { type: "text/css" });
  152. d.appendChild(createTextEl(a));
  153. }
  154. if (isDefined(b) && isString(b)) d.setAttribute("id", b);
  155. if (isDefined(c) && c) {
  156. document.body.insertBefore(d, document.body.firstChild)
  157. } else {
  158. e = document.getElementsByTagName("head");
  159. if (isDefined(e[0]) && e[0].nodeName == "HEAD") gvar.$w.setTimeout(function () {
  160. e[0].appendChild(d)
  161. }, 100);
  162. else document.body.insertBefore(d, document.body.firstChild)
  163. }
  164. return d
  165. };
  166. // Get Elements
  167. var $D = function (q, root, single) {
  168. if (root && typeof root == 'string') {
  169. root = $D(root, null, true);
  170. if (!root) { return null; }
  171. }
  172. if( !q ) return false;
  173. if ( typeof q == 'object') return q;
  174. root = root || document;
  175. if (q[0]=='/' || (q[0]=='.' && q[1]=='/')) {
  176. if (single) { return document.evaluate(q, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; }
  177. return document.evaluate(q, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  178. }
  179. else if (q[0]=='.') { return root.getElementsByClassName(q.substr(1)); }
  180. else { return root.getElementById( (q[0]=='#' ? q.substr(1):q.substr(0)) ); }
  181. return root.getElementsByTagName(q);
  182. };
  183. // utk add - remove element
  184. var Dom = {
  185. g: function(el) {
  186. if(!el) return false;
  187. return ( isString(el) ? document.getElementById(el) : el );
  188. },
  189. add: function(el, dest) {
  190. var el = this.g(el);
  191. var dest = this.g(dest);
  192. if(el && dest) dest.appendChild(el);
  193. },
  194. remove: function(el) {
  195. var el = this.g(el);
  196. if(el && el.parentNode)
  197. el.parentNode.removeChild(el);
  198. },
  199. Ev: function() {
  200. if (window.addEventListener) {
  201. return function(el, type, fn, ph) {
  202. if(typeof(el)=='object')
  203. this.g(el).addEventListener(type, function(e){fn(e);}, (isUndefined(ph) ? false : ph));
  204. };
  205. }else if (window.attachEvent) {
  206. return function(el, type, fn) {
  207. var f = function() { fn.call(this.g(el), window.event); };
  208. this.g(el).attachEvent('on' + type, f);
  209. };
  210. }
  211. }()
  212. };
  213.  
  214. // native scrollTo
  215. function nat_scrollTo(element, to, duration) {
  216. var start = element.scrollTop,
  217. change = to - start,
  218. currentTime = 0,
  219. increment = 20;
  220.  
  221. var animateScroll = function(){
  222. currentTime += increment;
  223. var val = Math.easeInOutQuad(currentTime, start, change, duration);
  224. element.scrollTop = val;
  225. if(currentTime < duration) {
  226. setTimeout(animateScroll, increment);
  227. }
  228. };
  229. animateScroll();
  230. }
  231.  
  232. //t = current time
  233. //b = start value
  234. //c = change in value
  235. //d = duration
  236. Math.easeInOutQuad = function (t, b, c, d) {
  237. t /= d/2;
  238. if (t < 1) return c/2*t*t + b;
  239. t--;
  240. return -c/2 * (t*(t-2) - 1) + b;
  241. };
  242.  
  243.  
  244. var rSRC = {
  245. getMobCSS: function(){
  246. return ''
  247. +'#site-header.fx{ position:relative}'
  248. +'#site-header.fx #site-nav{ width:620px;position:fixed;top:0;z-index:99999}'
  249. +'#site-header.fx .main-h.r{margin-top:30px}'
  250. ;
  251. },
  252. getMobCSS_patch: function(){
  253. return ''
  254. +'#site-nav h1{ text-align:left}'
  255. +'#site-nav h1 > a{ display:inline-block; height:25px;}'
  256. ;
  257. }
  258.  
  259. };
  260.  
  261. // ----my ge-debug--------
  262. function show_alert(msg, force) {
  263. if(arguments.callee.counter) { arguments.callee.counter++; } else { arguments.callee.counter=1; }
  264. GM_log('('+arguments.callee.counter+') '+msg);
  265. if(force==0) { return; }
  266. }
  267. function clog(msg) {
  268. if(!gvar.__DEBUG__) return;
  269. show_alert(msg);
  270. }
  271. // -end static
  272. //=========
  273.  
  274.  
  275. function init(){
  276. gvar.is_mobile = /^https?:\/\/m\.kaskus\./i.test(location.href);
  277. gvar.head_id_desktop = 'site-header';
  278. gvar.head_class_mobile = 'meta-header';
  279.  
  280. gvar.target_selector = (gvar.is_mobile ? '#'+gvar.head_id_desktop : '.meta-header');
  281.  
  282.  
  283. start_Main();
  284. }
  285.  
  286.  
  287. // ------
  288. init();
  289. })()
  290. /* tF. */