plugin.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. (function () {
  2. 'use strict';
  3. let global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  4. let Global = typeof window !== 'undefined' ? window : Function('return this;')();
  5. let offset = {};
  6. let runtime = {};
  7. let toolbar_sticky_type = !0;
  8. let cfyun_toolbar_sticky = !1;
  9. let toolbar_sticky_elem = null;
  10. let toolbar_sticky_elem_height = 0;
  11. let toolbar_sticky_wrap = null;
  12. class ToolbarSticky {
  13. constructor(editor) {
  14. cfyun_toolbar_sticky = editor.getParam('cfyun_toolbar_sticky', !1, 'bool');
  15. if (!cfyun_toolbar_sticky) {
  16. return;
  17. }
  18. toolbar_sticky_type = editor.getParam('toolbar_sticky_type', !0, 'bool');
  19. toolbar_sticky_elem = editor.getParam('toolbar_sticky_elem', '', 'string');
  20. toolbar_sticky_wrap = editor.getParam('toolbar_sticky_wrap', '', 'string');
  21. toolbar_sticky_elem_height = editor.getParam('toolbar_sticky_elem_height', 0, 'number');
  22. this.editor = editor;
  23. runtime.wrap = window;
  24. runtime.editor = editor.$(editor.container);
  25. runtime.header = runtime.editor.find('.tox-editor-header');
  26. runtime.container = runtime.editor.find('.tox-editor-container');
  27. runtime.elemHeight = toolbar_sticky_elem_height;
  28. if(toolbar_sticky_wrap && typeof toolbar_sticky_wrap === 'string' && toolbar_sticky_wrap != 'body') {
  29. runtime.wrap = document.querySelector(toolbar_sticky_wrap) || window;
  30. }
  31. let _this = this;
  32. if(toolbar_sticky_type) {
  33. editor.on('focus', () => {
  34. _this.bind();
  35. });
  36. editor.on('blur', () => {
  37. _this.restore();
  38. _this.unBind();
  39. });
  40. } else {
  41. this.bind();
  42. }
  43. return this;
  44. }
  45. sticky() {
  46. // 防止全屏冲突
  47. if(runtime.editor.hasClass('tox-fullscreen')) {
  48. this.restore();
  49. return !1;
  50. }
  51. this.position();
  52. if(offset.isSticky) {
  53. runtime.container.css('padding-top', runtime.header[0].clientHeight);
  54. runtime.editor.removeClass('tox-tinymce--toolbar-sticky-off').addClass('tox-tinymce--toolbar-sticky-on');
  55. runtime.header.css({
  56. position: 'fixed',
  57. width: offset.width,
  58. left: offset.left,
  59. top: runtime.elemHeight || 0,
  60. borderTop: '1px solid #ccc'
  61. });
  62. return !1;
  63. }
  64. this.restore();
  65. }
  66. position() {
  67. let elemOffsetHeight = runtime.elemHeight;
  68. if (toolbar_sticky_elem) {
  69. var elem = document.querySelector(toolbar_sticky_elem);
  70. if(!elem) {
  71. // 防止配置不正确报错
  72. this.editor.notificationManager.open({
  73. text: 'ToolbarSticky未获取到:预留位置DOM节点,请查看配置toolbar_sticky_elem。',
  74. type: 'info',
  75. });
  76. return !1;
  77. }
  78. elemOffsetHeight = elem.offsetHeight;
  79. runtime.elemHeight = elem.clientHeight;
  80. }
  81. offset.width = this.editor.container.clientWidth;
  82. offset.left = runtime.editor.offset().left + 1;
  83. offset.isSticky = this.scrollTop() >= this.editor.$(runtime.container).offset().top - elemOffsetHeight;
  84. }
  85. bind() {
  86. runtime.wrap.addEventListener('scroll', this.throttle(this.sticky.bind(this), 60), !1);
  87. runtime.wrap.addEventListener('resize', this.throttle(this.sticky.bind(this), 60), !1);
  88. this.sticky()
  89. }
  90. unBind() {
  91. runtime.wrap.removeEventListener('scroll', this.throttle(this.sticky.bind(this), 60));
  92. runtime.wrap.removeEventListener('resize', this.throttle(this.sticky.bind(this), 60));
  93. }
  94. restore() {
  95. runtime.header.attr('style', '');
  96. runtime.container.css('padding-top', 0);
  97. runtime.editor.removeClass('tox-tinymce--toolbar-sticky-on').addClass('tox-tinymce--toolbar-sticky-off')
  98. }
  99. destroy() {
  100. offset = runtime = {};
  101. this.unBind();
  102. this.restore()
  103. }
  104. scrollTop() {
  105. return document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset
  106. }
  107. now() {
  108. return Date.now() || new Date().getTime()
  109. }
  110. /**
  111. * 函数节流
  112. * @param {func} fn
  113. * @param {number} delay
  114. */
  115. throttle(fn, delay) {
  116. let _this = this, context, args, result;
  117. let timeout = null;
  118. let previous = 0;
  119. const later = () => {
  120. previous = 0;
  121. timeout = null;
  122. result = fn.apply(context, args);
  123. if (!timeout) {
  124. context = args = null;
  125. }
  126. };
  127. return () => {
  128. let now = _this.now();
  129. if (!previous) {
  130. previous = now;
  131. }
  132. let remaining = delay - (now - previous);
  133. context = this;
  134. args = arguments;
  135. if (remaining <= 0 || remaining > delay) {
  136. if (timeout) {
  137. clearTimeout(timeout);
  138. timeout = null;
  139. }
  140. previous = now;
  141. result = fn.apply(context, args);
  142. if (!timeout) {
  143. context = args = null;
  144. }
  145. } else if (!timeout) {
  146. timeout = setTimeout(later, remaining);
  147. }
  148. return result;
  149. };
  150. }
  151. }
  152. function Plugin () {
  153. global.add('toolbarsticky', function (editor) {
  154. editor.on('init', function (e) {
  155. new ToolbarSticky(editor)
  156. });
  157. });
  158. }
  159. Plugin();
  160. }());