鼠标手势-【米】字

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         鼠标手势-【米】字
// @namespace    http://tampermonkey.net/
// @version      0.5.8
// @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;
  }
}
})();

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