ztree_toc.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*! ztree_toc - v0.2.2 - 2014-02-08
  2. * https://github.com/i5ting/jQuery.zTree_Toc.js
  3. * Copyright (c) 2014 alfred.sang; Licensed MIT */
  4. function encode_id_with_array(opts,arr) {
  5. var result = 0;
  6. for(var z = 0; z < arr.length; z++ ) {
  7. result += factor(opts, arr.length - z ,arr[z]);
  8. }
  9. return result;
  10. }
  11. /**
  12. * 1.1.1 = 1*100*100 + 1*100 + 1
  13. * 1.2.2 = 1*100*100 + 2*100 + 3
  14. *
  15. * 1 = 0*100 +1
  16. 1,1 = 100
  17. */
  18. function get_parent_id_with_array(opts,arr) {
  19. var result_arr = [];
  20. for(var z = 0; z < arr.length; z++ ) {
  21. result_arr.push(arr[z]);
  22. }
  23. result_arr.pop();
  24. var result = 0;
  25. for(var z = 0; z < result_arr.length; z++ ) {
  26. result += factor(opts,result_arr.length - z,result_arr[z]);
  27. }
  28. return result;
  29. }
  30. function factor(opts ,count,current) {
  31. if(1 == count) {
  32. return current;
  33. }
  34. var str = '';
  35. for(var i = count - 1;i > 0; i-- ) {
  36. str += current * opts.step+'*';
  37. }
  38. return eval( str + '1' );
  39. }
  40. ;(function($) {
  41. /*
  42. * 根据header创建目录内容
  43. */
  44. function create_toc(opts) {
  45. $(opts.documment_selector).find(':header').each(function() {
  46. var level = parseInt(this.nodeName.substring(1), 10);
  47. _rename_header_content(opts,this,level);
  48. _add_header_node(opts,$(this));
  49. });//end each
  50. }
  51. /*
  52. * 渲染ztree
  53. */
  54. function render_with_ztree(opts) {
  55. var t = $(opts._zTree);
  56. t = $.fn.zTree.init(t,opts.ztreeSetting,opts._header_nodes).expandAll(opts.is_expand_all);
  57. // alert(opts._headers * 88);
  58. // $(opts._zTree).height(opts._headers * 33 + 33);
  59. $(opts._zTree).css(opts.ztreeStyle);
  60. }
  61. /*
  62. * 将已有header编号,并重命名
  63. */
  64. function _rename_header_content(opts ,header_obj ,level) {
  65. if(opts._headers.length == level) {
  66. opts._headers[level - 1]++;
  67. } else if(opts._headers.length > level) {
  68. opts._headers = opts._headers.slice(0, level);
  69. opts._headers[level - 1] ++;
  70. } else if(opts._headers.length < level) {
  71. for(var i = 0; i < (level - opts._headers.length); i++) {
  72. // console.log('push 1');
  73. opts._headers.push(1);
  74. }
  75. }
  76. if(opts.is_auto_number == true) {
  77. //另存为的文件里会有编号,所以有编号的就不再重新替换
  78. if($(header_obj).text().indexOf( opts._headers.join('.') ) != -1){
  79. }else{
  80. $(header_obj).text(opts._headers.join('.') + '. ' + $(header_obj).text());
  81. }
  82. }
  83. }
  84. /*
  85. * 给ztree用的header_nodes增加数据
  86. */
  87. function _add_header_node(opts ,header_obj) {
  88. var id = encode_id_with_array(opts,opts._headers);
  89. var pid = get_parent_id_with_array(opts,opts._headers);
  90. // 设置锚点id
  91. $(header_obj).attr('id',id);
  92. log($(header_obj).text());
  93. opts._header_offsets.push($(header_obj).offset().top - opts.highlight_offset);
  94. log('h offset ='+( $(header_obj).offset().top - opts.highlight_offset ) );
  95. opts._header_nodes.push({
  96. id:id,
  97. pId:pid ,
  98. name:$(header_obj).text()||'null',
  99. open:true,
  100. url:'#'+ id,
  101. target:'_self'
  102. });
  103. }
  104. /*
  105. * 根据滚动确定当前位置,并更新ztree
  106. */
  107. function bind_scroll_event_and_update_postion(opts) {
  108. var timeout;
  109. var highlight_on_scroll = function(e) {
  110. if (timeout) {
  111. clearTimeout(timeout);
  112. }
  113. timeout = setTimeout(function() {
  114. var top = $(window).scrollTop(),highlighted;
  115. if(opts.debug) console.log('top='+top);
  116. for (var i = 0, c = opts._header_offsets.length; i < c; i++) {
  117. // fixed: top+5防止点击ztree的时候,出现向上抖动的情况
  118. if (opts._header_offsets[i] >= (top + 5) ) {
  119. console.log('opts._header_offsets['+ i +'] = '+opts._header_offsets[i]);
  120. $('a').removeClass('curSelectedNode');
  121. // 由于有root节点,所以i应该从1开始
  122. var obj = $('#tree_' + (i+1) + '_a').addClass('curSelectedNode');
  123. break;
  124. }
  125. }
  126. }, opts.refresh_scroll_time);
  127. };
  128. if (opts.highlight_on_scroll) {
  129. $(window).bind('scroll', highlight_on_scroll);
  130. highlight_on_scroll();
  131. }
  132. }
  133. /*
  134. * 初始化
  135. */
  136. function init_with_config(opts) {
  137. opts.highlight_offset = $(opts.documment_selector).offset().top;
  138. }
  139. /*
  140. * 日志
  141. */
  142. function log(str) {
  143. return;
  144. if($.fn.ztree_toc.defaults.debug == true) {
  145. console.log(str);
  146. }
  147. }
  148. $.fn.ztree_toc = function(options) {
  149. // 将defaults 和 options 参数合并到{}
  150. var opts = $.extend({},$.fn.ztree_toc.defaults,options);
  151. return this.each(function() {
  152. opts._zTree = $(this);
  153. // 初始化
  154. init_with_config(opts);
  155. // 创建table of content,获取元数据_headers
  156. create_toc(opts);
  157. // 根据_headers生成ztree
  158. render_with_ztree(opts);
  159. // 根据滚动确定当前位置,并更新ztree
  160. bind_scroll_event_and_update_postion(opts);
  161. });
  162. // each end
  163. }
  164. //定义默认
  165. $.fn.ztree_toc.defaults = {
  166. _zTree: null,
  167. _headers: [],
  168. _header_offsets: [],
  169. _header_nodes: [{ id:1, pId:0, name:"Table of Content",open:true}],
  170. debug: true,
  171. highlight_offset: 0,
  172. highlight_on_scroll: true,
  173. /*
  174. * 计算滚动判断当前位置的时间,默认是50毫秒
  175. */
  176. refresh_scroll_time: 50,
  177. documment_selector: 'body',
  178. is_posion_top: false,
  179. /*
  180. * 默认是否显示header编号
  181. */
  182. is_auto_number: false,
  183. /*
  184. * 默认是否展开全部
  185. */
  186. is_expand_all: true,
  187. /*
  188. * 是否对选中行,显示高亮效果
  189. */
  190. is_highlight_selected_line: true,
  191. step: 100,
  192. ztreeStyle: {
  193. width:'260px',
  194. overflow: 'auto',
  195. position: 'fixed',
  196. 'z-index': 2147483647,
  197. border: '0px none',
  198. left: '0px',
  199. bottom: '0px',
  200. // height:'100px'
  201. },
  202. ztreeSetting: {
  203. view: {
  204. dblClickExpand: false,
  205. showLine: true,
  206. showIcon: false,
  207. selectedMulti: false
  208. },
  209. data: {
  210. simpleData: {
  211. enable: true,
  212. idKey : "id",
  213. pIdKey: "pId",
  214. // rootPId: "0"
  215. }
  216. },
  217. callback: {
  218. beforeClick: function(treeId, treeNode) {
  219. $('a').removeClass('curSelectedNode');
  220. if(treeNode.id == 1){
  221. // TODO: when click root node
  222. console.log('click root table of content');
  223. }
  224. if($.fn.ztree_toc.defaults.is_highlight_selected_line == true) {
  225. $('#' + treeNode.id).css('color' ,'red').fadeOut("slow" ,function() {
  226. // Animation complete.
  227. $(this).show().css('color','black');
  228. });
  229. }
  230. },
  231. onRightClick: function(event, treeId, treeNode) {
  232. if(treeNode.id == 1){
  233. // TODO: when right_click root node:table content
  234. console.log('right_click root table of content');
  235. }
  236. }
  237. }
  238. }
  239. };
  240. })(jQuery);