Page Positioning Buttons

Add links to go to top, bottom or a user specified position of each page.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name           Page Positioning Buttons
// @author         Ziyu
// @namespace      http://userscripts.org/users/ziyu
// @description    Add links to go to top, bottom or a user specified position of each page.
// @include        *
// @grant          none
// @version        End
// ==/UserScript==

// "Forked" from http://userscripts.org/scripts/show/105473

(function (document, window) {
  'use strict';

  // USER VARIABLES

  var numberOfPositions = 3,  // Sets the number of recording positions
      bottomEdge = '40%',     // Sets the bottom edge position in % of the page height
      color = '#a8a8a8';

  // Extend object a with object b's properties.
  var extend = function (a, b) {
    for (var key in b) {
      if (b.hasOwnProperty(key)) {
        a[key] = b[key];
      }
    }
    return a;
  };

  var cssPropsCommon = {
    cursor : 'pointer',
    zIndex : '1000'
  };

  var cssPropsContainer = extend({
    borderTop   : '2px solid' + color,
    borderBottom: '2px solid' + color,
    width       : '24px',
    position    : 'fixed',
    right       : '10px',
    bottom      : bottomEdge
  }, cssPropsCommon);

  var cssPropsTopButton = extend({
    width       : '0',
    height      : '0',
    borderBottom: '12px solid' + color,
    borderLeft  : '12px solid transparent',
    borderRight : '12px solid transparent'
  }, cssPropsCommon);

  var cssPropsBtmButton = extend({
    transform : 'rotate(180deg)',
    marginTop : '4px'
  }, cssPropsTopButton);

  var cssPropsRecButton = extend({
    width       : '12px',
    height      : '12px',
    borderRadius: '50%',
    background  : color,
    marginLeft  : '6px',
    marginTop : '4px'
  }, cssPropsCommon);

  var cssPropsRwdButton = extend({
    width       : '0',
    height      : '0',
    borderRight : '12px solid' + color,
    borderTop   : '6px solid transparent',
    borderBottom: '6px solid transparent',
    marginLeft  : '5px',
    marginTop   : '4px'
  }, cssPropsCommon);

  // HELPER FUNCTIONS

  // pfx is a function that takes a standard CSS property name as a parameter
  // and returns it's prefixed version valid for current browser it runs in.
  // The code is heavily inspired by Modernizr http://www.modernizr.com/
  var pfx = (function () {

    var style = document.createElement('dummy').style,
    prefixes = 'Webkit Moz O ms Khtml'.split(' '),
    memory = {};

    return function ( prop ) {
      if ( typeof memory[ prop ] === "undefined" ) {

        var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
        props = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');

        memory[ prop ] = null;
        for ( var i in props ) {
          if ( style[ props[i] ] !== undefined ) {
            memory[ prop ] = props[i];
            break;
          }
        }

      }

      return memory[ prop ];
    };

  })();

  // css function applies the styles given in `props` object to the element
  // given as `el`. It runs all property names through `pfx` function to make
  // sure proper prefixed version of the property is used.
  // If rm is set to true, it removes the properties from the element.
  var css = function ( el, props, rm ) {
    var key, pkey;
    for ( key in props ) {
      if ( props.hasOwnProperty(key) ) {
        pkey = pfx(key);
        if ( pkey !== null ) {
          el.style[pkey] = rm ? null : props[key];
        }
      }
    }
    return el;
  };

  // PAGE POSITIONING BUTTONS API

  var createPositionButton = function () {
    var position = 0,
        isset = 0,
        button = document.createElement('div');

    var setPosition = function (yOffset) {
      position = yOffset;
      isset = 1;

      return position;
    };

    var getPosition = function () {
      return position;
    };

    var rewind = function () {
      if(isset) {
        window.scrollTo(0, position);
      }
    };

    var record = function () {
      setPosition(window.pageYOffset);

      css(button, cssPropsRecButton, true);
      css(button, cssPropsRwdButton);
      button.removeEventListener('click', record, false);
      button.addEventListener('click', rewind, false);
    };

    css(button, cssPropsRecButton);
    button.addEventListener('click', record, false);

    return {
      button      : button,
      isset       : isset,
      getPosition : getPosition
    };
  };

  var buttons = function () {

    var intervalHandle = null,
        container = document.createElement('div'),
        positionButtonContainer = document.createElement('div');

    var pageGoToTop = function () {
      window.scrollTo(0, 0);
    };

    var pageGoToBottom = function () {
      window.scrollTo(0, 999999);
    };

    var pageScrollUp = function () {
      if (intervalHandle === null) {
        intervalHandle = setInterval(function(){window.scrollBy(0,-3);}, 60);
      }
    };

    var pageScrollDown = function () {
      if (intervalHandle === null) {
        intervalHandle = setInterval(function(){window.scrollBy(0,3);}, 60);
      }
    };

    var stopScroll = function () {
      clearInterval(intervalHandle);
      intervalHandle = null;
    };

    var addPos = function () {

      while (numberOfPositions--) {
        positionButtonContainer.appendChild(createPositionButton().button);
      }
    };

    var init = function () {

      var topButton = document.createElement('div'),
      btmButton = document.createElement('div');

      css(container, cssPropsContainer);
      css(topButton, cssPropsTopButton);
      css(btmButton, cssPropsBtmButton);

      topButton.addEventListener('click', pageGoToTop, false);
      topButton.addEventListener('mouseover', pageScrollUp, false);
      topButton.addEventListener('mouseout', stopScroll, false);

      btmButton.addEventListener('click', pageGoToBottom, false);
      btmButton.addEventListener('mouseover', pageScrollDown, false);
      btmButton.addEventListener('mouseout', stopScroll, false);

      container.appendChild(topButton);
      container.appendChild(positionButtonContainer);
      container.appendChild(btmButton);
      document.body.appendChild(container);

      addPos();
    };

    return {
      container : container,
      init      : init
    };
  };

  // START PAGE POSITIONING BUTTONS

  if (window.top == window.self) { // if not iframe

    var de = document.documentElement;
    if(de.scrollHeight > de.clientHeight && document.body) {
      buttons().init();
    }
  }

})(document, window);