scrollfix

JQuery辅助文本框在浏览器中固定位置,不随浏览器滚动条滚动

目前為 2019-08-10 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/388372/723755/scrollfix.js

  1. // ==UserScript==
  2. // @name scrollfix
  3. // @version 0.0.1
  4. // @namespace tsharp.js
  5. // @description JQuery辅助文本框在浏览器中固定位置,不随浏览器滚动条滚动
  6. // @author jimbo
  7. // @license GPLv3
  8. // @match *
  9. // @icon none
  10. // @require http://code.jquery.com/jquery-3.4.1.min.js
  11. // ==/UserScript==
  12. /*
  13. * fixedScroll.js 滚动固定插件
  14. * @DH
  15. * https://denghao.me
  16. *
  17. * 示例:
  18. * $('.box').fixedScroll()
  19. */
  20. ;
  21. (function () {
  22. var fixedScroll = function ($fixedEl, opts) {
  23. this.defaults = {
  24. navEls: '', //nav (注意: navEls和hookEls两个参数必须成对出现)
  25. hookEls: '', //nav要滚动到的对应元素
  26. hookOffset: 0, //hook区域顶部偏移量
  27. offset: 0, //固定元素顶部偏移量
  28. stickEndEl: '', //固定结束位置的元素
  29. callback: ''
  30. };
  31. $.extend(this, this.defaults, opts);
  32. this.flag = true;
  33. this.stickTop = 0; //固定元素的原始位置
  34. this.init_stickTop = 0; //用于重计算高度
  35. this.stickBottom = 9999999; //固定元素的结束位置
  36. this.fixedEl = $fixedEl; //固定元素
  37. this.fixedElH = $fixedEl.height();
  38. this.fixedElW = $fixedEl.width();
  39. this.fixedElL = $fixedEl.offset().left;
  40. this.winEl = $(window);
  41. this.offset = parseInt(this.offset || 0);
  42. this.hookArea = [];
  43. this.isClickSwitch = false;
  44. }
  45. fixedScroll.prototype = {
  46. init: function () {
  47. if (this.fixedEl.length > 0) {
  48. this.stickTop = this.fixedEl.offset().top;
  49. this.init_stickTop = this.stickTop;
  50. }
  51.  
  52. if (this.stickEndEl.length > 0) {
  53. this.stickBottom = this.stickEndEl.offset().top;
  54. }
  55. // 限定起始位的距顶高度
  56. this.distance = this.stickBottom - this.stickTop - this.fixedElH - this.offset / 2;
  57. this.calcArea();
  58. this.flag && this.events();
  59. this.flag = false;
  60. },
  61. // 固定
  62. stickHandle: function () {
  63. if (this.winEl.scrollTop() > this.stickTop - this.offset) {
  64. if (this.winEl.scrollTop() < this.stickBottom - this.fixedElH - this.offset) {
  65. this.fixedEl.css({
  66. "position": "fixed",
  67. "top": this.offset,
  68. "left": this.fixedElL,
  69. "width": this.fixedElW,
  70. "height": this.fixedElH,
  71. "transform": "translateY(0)"
  72. });
  73. typeof this.callback == 'function' && this.callback(1);
  74. } else {
  75. this.fixedEl.css({
  76. "top": "auto",
  77. "left": "auto",
  78. "position": "static",
  79. "transform": "translateY(" + this.distance + "px)"
  80. });
  81. typeof this.callback == 'function' && this.callback(0);
  82. }
  83. } else {
  84. this.fixedEl.css({
  85. "top": "auto",
  86. "position": "static"
  87. });
  88. typeof this.callback == 'function' && this.callback(0);
  89. }
  90. },
  91.  
  92. // 动态计算高度
  93. resizeHeight: function (hasNewTop) {
  94. if (this.fixedEl.length > 0) {
  95. this.stickTop = hasNewTop ? this.fixedEl.offset().top : this.init_stickTop;
  96. }
  97. if (this.stickEndEl.length > 0) {
  98. this.stickBottom = this.stickEndEl.offset().top;
  99. }
  100. this.distance = this.stickBottom - this.stickTop - this.fixedElH - this.offset / 2;
  101. this.calcArea();
  102. },
  103.  
  104. // 计算滚动区
  105. calcArea: function () {
  106. if (this.hookEls.length <= 0) return;
  107. var areas = [];
  108. this.hookEls.each(function (i, ele) {
  109. var start = $(this).offset().top;
  110. var end = start + $(this).height();
  111. areas.push([start, end]);
  112. })
  113. this.hookArea = areas;
  114. },
  115.  
  116. // 区域判断
  117. hookScroll: function () {
  118. var t = this.winEl.scrollTop();
  119. for (var i in this.hookArea) {
  120. if ((t > this.hookArea[i][0] - this.hookOffset) && t < this.hookArea[i][1]) {
  121. this.navStatus(i)
  122. } else {
  123. this.navStatus()
  124. }
  125. }
  126. },
  127.  
  128. // nav状态
  129. navStatus: function (i) {
  130. if (i || +i === 0) {
  131. this.navEls.eq(i).addClass('active').siblings().removeClass('active');
  132. } else {
  133. this.navEls.eq(i).removeClass('active');
  134. }
  135. },
  136.  
  137. // 滚动到指定位置
  138. refresh: function (i) {
  139. this.calcArea();
  140. var top = this.hookArea[i][0] - this.hookOffset;
  141. this.scrollTop(top, 120);
  142. },
  143.  
  144. scrollTop: function (scrollTo, time) {
  145. var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
  146. var scrollFrom = parseInt(scrollTop),
  147. i = 0,
  148. step = 5;
  149. scrollTo = parseInt(scrollTo);
  150. time /= step;
  151. var interval = setInterval(function () {
  152. i++;
  153. var top = (scrollTo - scrollFrom) / time * i + scrollFrom;
  154. document.body.scrollTop = top;
  155. document.documentElement.scrollTop = top;
  156. if (i >= time) {
  157. clearInterval(interval);
  158. }
  159. }, step)
  160. },
  161.  
  162. events: function () {
  163. var _this = this;
  164. // 切换nav
  165. if (_this.navEls.length > 0) {
  166. this.navEls.on('click', function () {
  167. var i = $(this).index();
  168. _this.isClickSwitch = true;
  169. _this.refresh(i);
  170. _this.navStatus(i);
  171. setTimeout(function () {
  172. _this.isClickSwitch = false;
  173. }, 300);
  174. })
  175. }
  176. // 滚动监听
  177. this.winEl.on("scroll", function () {
  178. (_this.fixedEl.length > 0) && _this.stickHandle();
  179. (_this.hookEls.length > 0 && !_this.isClickSwitch) && _this.hookScroll();
  180. });
  181. }
  182. }
  183.  
  184. $.fn.fixedScroll = function (opts) {
  185. var drag = new fixedScroll(this, opts);
  186. drag.init();
  187. return drag;
  188. }
  189.  
  190. //兼容模块
  191. if (typeof module !== 'undefined' && typeof exports === 'object') {
  192. module.exports = fixedScroll;
  193. } else if (typeof define === 'function' && (define.amd || define.cmd)) {
  194. define(function () {
  195. return fixedScroll;
  196. })
  197. } else {
  198. window.fixedScroll = fixedScroll;
  199. }
  200. }).call(function () {
  201. return (typeof window !== 'undefined' ? window : global)
  202. }, $)