鼠标手势-【米】字

1、通过按下鼠标右键拖动,分别实现的【↑ 上移一屏】、【↓ 下移一屏】、【↗ 移到底部】、【↘ 移到顶部】、【← 后退上页】、【→ 前进下页】、【↖ 关闭页面】、【↙ 刷新页面】当前标签页的八大功能;当然,支持长按超过1秒取消操作;

当前为 2023-10-27 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         鼠标手势-【米】字
// @namespace    http://tampermonkey.net/
// @version      0.5.9
// @description  1、通过按下鼠标右键拖动,分别实现的【↑ 上移一屏】、【↓ 下移一屏】、【↗ 移到底部】、【↘ 移到顶部】、【← 后退上页】、【→ 前进下页】、【↖ 关闭页面】、【↙ 刷新页面】当前标签页的八大功能;当然,支持长按超过1秒取消操作;
// @author       Enjoy
// @icon         https://foruda.gitee.com/avatar/1698283059572409586/4867929_enjoy_li_1698283059.png!avatar200
// @match        *://*/*
// @match        file:///*
// @grant        GM_addElement
// @grant        GM_setClipboard
// @license      GPL License
// ==/UserScript==

/******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 158:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  codeIsNotExcutable: () => (/* binding */ codeIsNotExcutable),
  createElement: () => (/* binding */ createElement),
  createElementTipFn: () => (/* binding */ createElementTipFn),
  doCopy: () => (/* binding */ doCopy),
  findHasScrollbarDom: () => (/* binding */ findHasScrollbarDom),
  getSettingFromLocalStorage: () => (/* binding */ getSettingFromLocalStorage),
  isContentEditableOfDOM: () => (/* binding */ isContentEditableOfDOM),
  isExcutableBySetting: () => (/* binding */ isExcutableBySetting),
  isOperated: () => (/* binding */ isOperated),
  logSettingOptWithColor: () => (/* binding */ logSettingOptWithColor),
  numbericalInterval: () => (/* binding */ numbericalInterval),
  prependMetaUF8: () => (/* binding */ prependMetaUF8)
});

;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/typeof.js
function _typeof(o) {
  "@babel/helpers - typeof";

  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
    return typeof o;
  } : function (o) {
    return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
  }, _typeof(o);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/toPrimitive.js

function _toPrimitive(input, hint) {
  if (_typeof(input) !== "object" || input === null) return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== undefined) {
    var res = prim.call(input, hint || "default");
    if (_typeof(res) !== "object") return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js


function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return _typeof(key) === "symbol" ? key : String(key);
}
;// CONCATENATED MODULE: ./node_modules/.pnpm/registry.npmjs.org+@[email protected]/node_modules/@babel/runtime/helpers/esm/defineProperty.js

function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
;// CONCATENATED MODULE: ./tools/GM.js

function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/** @描述 函数文档 https://www.tampermonkey.net/documentation.php#api:GM_addElement */
// $GM.createElement
function createElement(tag) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var win = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window;
  if (!win.GM_createElement) {
    win.GM_createElement = GM_createElement;
  }
  return GM_createElement(tag, options);
  /**
   * @param {*} tag
   * @param {*}  options {
   * 			idPrefix = `enjoy_${ENV_CRX}_${tag}`,
   * 			el = 'html',
   * 			autoInsert = true,
   * 			randomType = 'single',
   * 			id = '',
   * 			addPrefix = true,
   * 			insertType = tag === 'style' ? 'appendChild' : 'prepend',
   * 		}
   * @returns {*} dom
   */
  function GM_createElement(tag, options) {
    var _options$idPrefix = options.idPrefix,
      idPrefix = _options$idPrefix === void 0 ? "enjoy_".concat("MouseShortcuts", "_").concat(tag, "_") : _options$idPrefix,
      _options$el = options.el,
      el = _options$el === void 0 ? 'html' : _options$el,
      _options$autoInsert = options.autoInsert,
      autoInsert = _options$autoInsert === void 0 ? true : _options$autoInsert,
      _options$randomType = options.randomType,
      randomType = _options$randomType === void 0 ? 'single' : _options$randomType,
      _options$id = options.id,
      id = _options$id === void 0 ? '' : _options$id,
      _options$addPrefix = options.addPrefix,
      addPrefix = _options$addPrefix === void 0 ? true : _options$addPrefix,
      _options$insertType = options.insertType,
      insertType = _options$insertType === void 0 ? tag === 'style' ? 'appendChild' : 'prepend' : _options$insertType;
    if (addPrefix) {
      id = "".concat(idPrefix).concat(id);
    }
    if (randomType !== 'single') {
      id = "".concat(id, "_").concat(Math.floor(Math.random() * 1000));
    }
    options.id = id;
    var dom = document.querySelector("#".concat(id));
    if (!dom) {
      dom = document.createElement(tag);
    }
    for (var key in options) {
      if (Object.hasOwnProperty.call(options, key) && key !== 'el') {
        dom[key] = options[key];
      }
    }
    if (autoInsert) {
      if (typeof el === 'string') {
        el = document.querySelector(el);
      }

      //insertType  prepend | appendChild
      el[insertType](dom);
    }
    return dom;
  }
}
/** @描述 进入可以操作的页面 */
function isOperated() {
  var urls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var currentUrl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : location.href;
  if (typeof urls === 'string') {
    urls = [urls];
  }
  return !!urls.find(function (regUrl) {
    return new RegExp(regUrl).test(currentUrl);
  });
}
function prependMetaUF8() {
  return document.querySelector('meta[charset="UTF-8"]') || createElement('meta', {
    charset: 'utf-8'
  });
}
function doCopy(newValue) {
  var _navigator;
  var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'textarea';
  if ((_navigator = navigator) !== null && _navigator !== void 0 && (_navigator = _navigator.clipboard) !== null && _navigator !== void 0 && _navigator.writeText) {
    // 读取剪贴板
    // navigator.clipboard.readText().then((clipText) => {console.log('clipText=',clipText)})

    // 写入剪贴板
    navigator.clipboard.writeText(newValue)["catch"](function (err) {
      return console.error("clipboard.writeText\uFF1A".concat(err));
    });
    return;
  }
  var textarea = createElement('textarea', {
    el: 'body',
    id: selector,
    style: 'position: absolute;left: -500px;top: -500px;max-width: 50px;opacity: 0;'
  });
  textarea.value = newValue;
  textarea.select();
  setTimeout(function () {
    document.execCommand('Copy');
  }, 200);
}
function createElementTipFn() {
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  var _options$setTimeoutSt = options.setTimeoutStep,
    setTimeoutStep = _options$setTimeoutSt === void 0 ? 1000 : _options$setTimeoutSt,
    _options$backgroundCo = options.backgroundColors,
    backgroundColors = _options$backgroundCo === void 0 ? {
      warn: 'rgb(181 156 51 / 60%)',
      success: 'rgb(3 113 3 / 60%)',
      error: 'rgb(165 2 2 / 60%)',
      info: 'rgb(67 62 62 / 60%)'
    } : _options$backgroundCo,
    _options$color = options.color,
    color = _options$color === void 0 ? '#ffffff' : _options$color,
    _options$opacity = options.opacity,
    opacity = _options$opacity === void 0 ? 1 : _options$opacity;
  var setTimeoutStamp = 0;
  return function createElementTip() {
    var configs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    var content = configs.content,
      e = configs.e,
      _configs$type = configs.type,
      type = _configs$type === void 0 ? 'info' : _configs$type,
      _configs$tagType = configs.tagType,
      tagType = _configs$tagType === void 0 ? 'span' : _configs$tagType;
    if (!content) return;
    console.log("content => %O ", content);
    clearTimeout(setTimeoutStamp);
    var contentDom = createElement(tagType, {
      id: 'createElementTip',
      innerText: content,
      style: "\n            font-size:14px;\n            font-weight:600;\n            color:".concat(color, ";\n            position: fixed;\n            left: ").concat(numbericalInterval(e.clientX - 46), "px;\n            top: ").concat(numbericalInterval(e.clientY - 30, [5, window.innerHeight - 35]), "px;\n            background-color:").concat(backgroundColors[type], ";\n            opacity: ").concat(opacity, ";\n            border-radius: 4px;\n            padding: 4px 8px;\n            box-shadow:0 0 5px 0 rgb(255 255 255 / 60%) inset;\n            z-index:").concat((Math.floor(Date.now() / 1000) + '').slice(-5), "\n            ")
    });
    setTimeoutStamp = setTimeout(function () {
      contentDom.remove();
    }, setTimeoutStep);
  };
}
/**
 * @description dom是否可编辑
 * @param {*} [dom=document.activeElement]
 * @returns {*}  {boolean}
 */
function isContentEditableOfDOM() {
  var dom = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document.activeElement;
  var activeElement = dom;
  if (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.contenEditable === 'true') return true;
  return false;
}
/**
 * @description 数字区间
 * @param {*} val
 * @param {*} [interval=[10, window.innerWidth]]
 * @returns {*}
 */
function numbericalInterval(val) {
  var interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [5, window.innerWidth - 130];
  var indexStart = interval[0];
  var indexEnd = interval[1];
  if (val < indexStart) return indexStart;
  if (val > indexEnd) return indexEnd;
  return val;
}

/**
 * @description 可滚动的dom
 * @param {*} dom
 * @returns {*}
 */
function findHasScrollbarDom(dom) {
  while (dom) {
    if (dom.offsetHeight < dom.scrollHeight && window.getComputedStyle(dom).overflowY !== 'visible') {
      break;
    }
    dom = dom.parentElement;
  }
  if (!dom || dom === document.body) {
    // 始终是 documentElement等同于window
    dom = document.documentElement;
  }
  console.warn("\u9875\u9762\u6EDA\u52A8\u5143\u7D20\u7684tagName: ", dom.tagName.toLocaleLowerCase());
  return dom;
}

/**
 * @description 获取方法配置
 * @param {string} [key='']
 * @param {*} [defaultOpt={ includedUrls: [] }]
 * @returns {*} {Object}
 **/
function getSettingFromLocalStorage() {
  var _localStorage, _localStorage2;
  var fileName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  var defaultOpt = arguments.length > 1 ? arguments[1] : undefined;
  var mergedSettingOpt = _objectSpread({
    includedUrls: [],
    runType: '0'
  }, defaultOpt);
  var fullSettingKey = "\uD83C\uDF1F_enjoy_setting";
  var fullSettings = (_localStorage = localStorage) !== null && _localStorage !== void 0 && _localStorage[fullSettingKey] ? JSON.parse((_localStorage2 = localStorage) === null || _localStorage2 === void 0 ? void 0 : _localStorage2[fullSettingKey]) : {};
  var SETTING = _objectSpread(_objectSpread({}, mergedSettingOpt), fullSettings === null || fullSettings === void 0 ? void 0 : fullSettings[fileName]);
  fullSettings[fileName] = SETTING;
  fullSettings.runTypeDest = 'runType:0、执行默认规则includedUrls;1、强制执行(跳过校验规则);2、不执行';
  localStorage[fullSettingKey] = JSON.stringify(fullSettings || {});
  return SETTING;
}

/**
 * @description 是否执行该方法
 * @param {*} [settingOpt={}]
 * @returns {*}  {Boolean}
 */
function isExcutableBySetting() {
  var _includedUrls$find;
  var settingOpt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  var includedUrls = settingOpt.includedUrls,
    runType = settingOpt.runType;
  if (runType === '1') return true;
  if (runType === '2') return false;
  if (includedUrls === undefined) return true;
  if ((includedUrls === null || includedUrls === void 0 ? void 0 : includedUrls.length) === 0) return true;
  var HREF = location.href;
  var findOne = includedUrls === null || includedUrls === void 0 || (_includedUrls$find = includedUrls.find) === null || _includedUrls$find === void 0 ? void 0 : _includedUrls$find.call(includedUrls, function (url) {
    return new RegExp(url).test(HREF);
  });
  return !!findOne;
}
/**
 * @description 是否不执行
 * @param {*} fileName
 * @param {*} settingOpt
 * @returns {*}  {Boolean}
 */
function codeIsNotExcutable(fileName, settingOpt) {
  return !isExcutableBySetting(getSettingFromLocalStorage(fileName, settingOpt));
}
function logSettingOptWithColor() {
  var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '🌟_enjoy_setting';
  console.log("%c".concat(key, " \u8BBE\u7F6ESETTING\uFF1A"), 'background:#4e0ab7d9;color:#fff;', '\n', JSON.parse(localStorage[key]), "\n\n".concat(key));
}

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__webpack_require__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	(() => {
/******/ 		// define __esModule on exports
/******/ 		__webpack_require__.r = (exports) => {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	})();
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
/* provided dependency */ var $GM = __webpack_require__(158);

run();
function run() {
  if ($GM.codeIsNotExcutable('OctagonalShortcuts', {
    includedUrls: []
  })) return;
  var createElementTip = $GM.createElementTipFn();
  document.addEventListener('contextmenu', onContextmenu);
  window.addEventListener('mousedown', onMousedown);
  window.addEventListener('mousemove', onMousemove);
  window.addEventListener('mouseup', onMouseup);
  window.addEventListener('beforeunload', function () {
    document.removeEventListener('contextmenu', onContextmenu);
    document.removeEventListener('mousedown', onMousedown);
    document.removeEventListener('mousemove', onMousemove);
    document.removeEventListener('mouseup', onMouseup);
  });

  // 禁用右击菜单 document.oncontextmenu=function(){return false }
  var isDisableContextmenu = false;
  function onContextmenu(e) {
    if (isDisableContextmenu) {
      e.preventDefault();
    }
  }
  var isPressing = false;
  var timestampAtMouseDown = 0;
  var ops = null;
  var offsetValue = 150;
  var domOfMousedown = null;
  var preCheckTimestamp = 0;
  var scrollbarDom = window;
  var scrollbarDomOffsetHeight = window.innerHeight;
  function onMousedown(e) {
    isPressing = true;
    if (e.button !== 2) return;
    isDisableContextmenu = false;
    preCheckTimestamp = timestampAtMouseDown = Date.now();

    // 浏览器视图容器高度
    // winSize = { width: window.innerHeight, height: window.innerHeight };

    ops = {
      x: e.clientX,
      y: e.clientY,
      screenY: e.screenY
    };
    domOfMousedown = e.target;
  }
  var setTimeoutStep = 1 * 1000;
  var y_x = 0.364; //对应20度
  var x_y = 1 / 0.364; //对应70度
  var checkStep = 0.1 * 1000;
  var callbackAfterMouseup = function callbackAfterMouseup() {
    return null;
  };
  function onMousemove(e) {
    if (!isPressing) return;
    // buttons
    if (e.buttons !== 2) return;
    if (Date.now() - preCheckTimestamp < checkStep) return;
    preCheckTimestamp = Date.now();
    var offsetX = e.clientX - ops.x;
    var offsetY = e.clientY - ops.y;

    // x:y=1:10 或 x:y=10:1 ,以浏览器左上角为原点,右下面积为正向区域,八边形

    /*
          window.history.back()
          window.history.forward()
          location.reload()
          window.close()
          window.scrollBy({ top: -window.innerHeight + 50,behavior: 'smooth' })
          window.scrollBy({ top: window.innerHeight - 50,behavior: 'smooth' })
          window.scrollTo({ top: 0,behavior: 'smooth' })
          window.scrollTo({ top: document.documentElement.scrollHeight,behavior: 'smooth' })
          */
    // ↑↓←→↖↗↙↘

    if (Math.abs(offsetX) >= 10 || Math.abs(offsetY) >= 10) {
      isDisableContextmenu = true;
      scrollbarDom = $GM.findHasScrollbarDom(domOfMousedown);
      console.log("\u9875\u9762\u6EDA\u52A8 dom => ", scrollbarDom);
      scrollbarDomOffsetHeight = $GM.numbericalInterval(scrollbarDom.offsetHeight, [0, window.innerHeight]);
      offsetValue = scrollbarDomOffsetHeight / 10;
      createHrByclass();
      var feature = '';
      if (offsetX < 0) {
        //X轴左方
        if (Math.abs(offsetY / offsetX) < y_x) {
          direction = '向左';
          feature = '← 后退上页';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return setTimeout(function () {
              return window.history.back();
            }, setTimeoutStep);
          };
        } else if (Math.abs(offsetY / offsetX) > y_x && Math.abs(offsetY / offsetX) < x_y && offsetY < 0) {
          direction = '向左上';
          feature = '↖ 关闭页面';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return setTimeout(function () {
              return window.close();
            }, setTimeoutStep);
          };
        } else if (Math.abs(offsetY / offsetX) > x_y && offsetY < 0) {
          direction = '向上';
          feature = '↑ 上移一屏';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return scrollEventFn(scrollbarDom, 'scrollBy', {
              top: scrollbarDomOffsetHeight - offsetValue,
              behavior: 'smooth'
            }, function (isEnableScroll) {
              return isEnableScroll ? createHrByclass(true, scrollbarDom) : feature = '已到底部';
            });
          };
        } else if (Math.abs(offsetY / offsetX) > y_x && Math.abs(offsetY / offsetX) < x_y && offsetY > 0) {
          direction = '向左下';
          feature = '↙ 刷新页面';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return setTimeout(function () {
              return location.reload();
            }, setTimeoutStep);
          };
        } else if (Math.abs(offsetY / offsetX) > x_y && offsetY > 0) {
          direction = '向下';
          feature = '↓ 下移一屏';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return scrollEventFn(scrollbarDom, 'scrollBy', {
              top: -scrollbarDomOffsetHeight + offsetValue,
              behavior: 'smooth'
            }, function (isEnableScroll) {
              return isEnableScroll ? createHrByclass(true, scrollbarDom) : feature = '已到顶部';
            });
          };
        }
      } else if (offsetX >= 0) {
        //X轴右方
        if (Math.abs(offsetY / offsetX) < y_x) {
          direction = '向右';
          feature = '→ 前进下页';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return setTimeout(function () {
              return window.history.forward();
            }, setTimeoutStep);
          };
        } else if (Math.abs(offsetY / offsetX) > y_x && Math.abs(offsetY / offsetX) < x_y && offsetY > 0) {
          direction = '向右下';
          feature = '↘ 移到顶部';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return scrollEventFn(scrollbarDom, 'scrollTo', {
              top: 0,
              behavior: 'smooth'
            }, function (isEnableScroll) {
              return isEnableScroll ? undefined : feature = '已到顶部';
            });
          };
        } else if (Math.abs(offsetY / offsetX) > x_y && offsetY > 0) {
          direction = '向下';
          feature = '↓ 下移一屏';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return scrollEventFn(scrollbarDom, 'scrollBy', {
              top: -scrollbarDomOffsetHeight + offsetValue,
              behavior: 'smooth'
            }, function (isEnableScroll) {
              return isEnableScroll ? createHrByclass(true, scrollbarDom) : feature = '已到顶部';
            });
          };
        } else if (Math.abs(offsetY / offsetX) > y_x && Math.abs(offsetY / offsetX) < x_y && offsetY < 0) {
          direction = '向右上';
          feature = '↗ 移到底部';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return scrollEventFn(scrollbarDom, 'scrollTo', {
              top: scrollbarDom.scrollHeight,
              behavior: 'smooth'
            }, function (isEnableScroll) {
              return isEnableScroll ? undefined : feature = '已到底部';
            });
          };
        } else if (Math.abs(offsetY / offsetX) > x_y && offsetY < 0) {
          direction = '向上';
          feature = '↑ 上移一屏';
          callbackAfterMouseup = function callbackAfterMouseup() {
            return scrollEventFn(scrollbarDom, 'scrollBy', {
              top: scrollbarDomOffsetHeight - offsetValue,
              behavior: 'smooth'
            }, function (isEnableScroll) {
              return isEnableScroll ? createHrByclass(true, scrollbarDom) : feature = '已到底部';
            });
          };
        }
      }
      createElementTip({
        content: feature,
        e: e
      });
    } else {
      isDisableContextmenu = true;
    }
  }
  var cancelTimeStep = 1 * 1000;
  function onMouseup(e) {
    if (e.button !== 2) return;
    if (Date.now() - timestampAtMouseDown < checkStep) return;
    if (Date.now() - timestampAtMouseDown > cancelTimeStep) return createElementTip({
      content: '取消操作',
      e: e
    });
    callbackAfterMouseup();
    callbackAfterMouseup = function callbackAfterMouseup() {
      return null;
    };
    isPressing = false;
  }
  function createSplitLineStyle(dom) {
    // dom.getBoundingClientRect().top
    $GM.createElement('style', {
      id: 'OctagonalShortcuts',
      innerHTML: "\n      .OctagonalShortcuts-horizontal::after {\n        content: '\uD83D\uDC49';\n        font-size:14px;\n        display: flex;\n        width:100vw;\n        height:4px;\n        background:#ff0000;\n        position: fixed;\n        z-index: 2000;\n        top: ".concat(offsetValue, "px;\n        left:10px;\n        opacity:0.2;\n      }\n      ")
    });
  }
  var setTimeoutStamp2 = 0;
  var containerContainSpanPre = null;
  var className2 = 'OctagonalShortcuts-horizontal';
  function createHrByclass(isAdd, dom) {
    if (isAdd) {
      if (dom === document.documentElement || dom === document.body) {
        clearTimeout(setTimeoutStamp2);
        if (isAdd) {
          createSplitLineStyle(dom);
          dom.classList.add(className2);
          containerContainSpanPre = dom;
          setTimeoutStamp2 = setTimeout(function () {
            dom.classList.remove(className2);
          }, 1 * 1000);
        }
      }
    } else {
      var _containerContainSpan;
      (_containerContainSpan = containerContainSpanPre) === null || _containerContainSpan === void 0 || _containerContainSpan.classList.remove(className2);
    }
  }
  function scrollEventFn(that, eventName, options, callback) {
    var nativeFn = that[eventName] || function () {
      return null;
    };
    var isEnableScroll = isScrolled(that, options);
    console.log('可以滚动', isEnableScroll);
    callback === null || callback === void 0 || callback(isEnableScroll);
    if (isEnableScroll) {
      return nativeFn.call(that, options);
    }
  }
  function isScrolled(that, options) {
    if (!options) return false;
    var top = options.top;
    var scrollTop = that.scrollTop;
    if (that === document.documentElement) return true;
    if (top > 0 && scrollTop === that.scrollHeight - that.offsetHeight) {
      return false;
    } else if (top <= 0 && scrollTop === 0) {
      return false;
    }
    return true;
  }
}
})();

/******/ })()
;