drag_.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146
  1. /**
  2. * option:handleClick,handledbclick,dragend,itemClick,dragListClick,onSelectedClick,onItemSelect,ondblclick
  3. */
  4. var sc = document.createElement("script");
  5. sc.src = '/ss/js/wdDrag.js'; // = '/wd/js/wdDrag.js'。Lin
  6. document.head.appendChild(sc);
  7. $(function () {
  8. if (wd.configurableTab) {
  9. console.warn("这一段引入自动引入wdDrag只是应急处理,说不定哪一天就干掉了,看到这段信息,就表示你要引用新的wdDrag(tab需要重新发布)(重要的话要说三遍)");
  10. console.warn("这一段引入自动引入wdDrag只是应急处理,说不定哪一天就干掉了,看到这段信息,就表示你要引用新的wdDrag(tab需要重新发布)(重要的话要说三遍)");
  11. console.warn("这一段引入自动引入wdDrag只是应急处理,说不定哪一天就干掉了,看到这段信息,就表示你要引用新的wdDrag(tab需要重新发布)(重要的话要说三遍)");
  12. }
  13. })
  14. // console.log("旧的drag");
  15. // throw "这个脚本已经废除,现在帮你引入新的脚本";
  16. var drager = dragStartPoint = dragNowPoint = options = null;
  17. var justDragEnd = itemDraging = dragItemDown = dragListDown = dashedDrawing =
  18. dashedDrawEnd = draginited = false;
  19. var clickedField, startScrollPoint, dashedStartPoint, dashedEndPoint, doc,
  20. wdw, currentMouseDownItem;
  21. var prepareDrag = [];
  22. // http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js
  23. /*
  24. * var dragcss = "<link id='dragcss' rel='stylesheet'
  25. * href='/wd/js/drag/drag.css' /><link id='dragcss' rel='stylesheet'
  26. * href='drag.css' />";
  27. */
  28. var dragcss = "<link id='dragcss' rel='stylesheet' href='/ss/js/drag.css'/>"; // ='/wd/js/drag.css'。Lin
  29. var yx = '.dragList',
  30. bx = '.content-right';
  31. $(document).ready(function () {
  32. for (var name in prepareDrag) {
  33. var drager = DragManager.getInstance(name);
  34. }
  35. });
  36. // function initTagDrag(opt, _window) {
  37. // options = {
  38. // dashedField: " ",
  39. // alignMode: 'vertical'
  40. // };
  41. // for (var k in opt) {
  42. // options[k.toString()] = opt[k];
  43. // }
  44. // initDrag(options, _window);
  45. // }
  46. function prepareDrag(name, opt, _window) {
  47. prepareDrag[name] = {};
  48. prepareDrag[name].options = opt || {};
  49. };
  50. function initDrag(name, opt, _window) {
  51. // if (typeof (isWriteOut) == "undefined") {
  52. // alert("注意下,这是旧的写法,以后不会再有自动初始化拖拽了,\n记得新的拖拽需要通过commonwrite输出^_^");
  53. // return;
  54. // }
  55. options = opt || {};
  56. options.dragListSelector = options.dragListSelector || ".dragList"
  57. options.dashedField = options.dashedField || ".dragList"
  58. options.alignMode = options.alignMode || 'vertical';
  59. console.log(options);
  60. drager = {};
  61. distnic();
  62. _window = _window || window;
  63. wdw = $(_window);
  64. doc = $(_window.document);
  65. // //初始化iframe的drag
  66. // if ($("iframe", _window.document).length > 0) {
  67. // $.each($("iframe", _window.document), function(index) {
  68. // this.onload = function() {
  69. // initDrag(options, this.contentWindow)
  70. // }
  71. // });
  72. // }
  73. var dragList_ = $(".dragList", doc);
  74. var item_ = $(".dragList>.item", doc);
  75. /*
  76. * 初始化item.dragList的三角
  77. */
  78. $(".dragList.item", doc).each(function () {
  79. if (!$(this).children(".triangle").length > 0) {
  80. $(this).prepend(setUpTriangle(this));
  81. }
  82. });
  83. var handle_ = $(".dragList>.item>.handle", doc);
  84. doc.off("selectstart").on('selectstart', function () {
  85. return false;
  86. });
  87. doc.off("keydown").on("keydown", function (event) {
  88. functionKeyDown = event.ctrlKey || event.altKey || event.shiftKey;
  89. if (event.ctrlKey && event.keyCode === 65) { // 全选
  90. if ($(".dragList.focused").length < 1 && $(".L").length > 0) {}
  91. $(".dragList.focused .item").addClass("selected");
  92. doc.trigger("mouseup");
  93. }
  94. });
  95. doc.off("keyup").on("keyup", function (event) {});
  96. doc.off("mousedown").on("mousedown", function (event) {});
  97. doc.off("mouseup").on("mouseup", function (event) {
  98. currentMouseDownItem = null;
  99. _dragEnd(event, options.dragend);
  100. });
  101. doc.off("click").on("click", function (event) {});
  102. doc.mousemove(function (event) { // 模拟mouseentermouseout
  103. $("body").find(".mousedata").html(
  104. "left:" + event.clientX + ",top:" + event.clientY);
  105. if (!drager.list && dragItemDown) { // 将item拖拽出来
  106. itemToList(event);
  107. }
  108. if (drager.list && dragItemDown) { // 移动List
  109. moveList(event);
  110. }
  111. });
  112. // dragList_.off("scroll").on("scroll", function() {
  113. // doc.trigger("mousemove");
  114. // });
  115. $(".dragList,.item").off("mousedown mouseup click dblclick");
  116. dragList_.off("scroll").on("scroll", function () {
  117. doc.mousemove();
  118. });
  119. dragList_.on("click", function (event) {
  120. // 列表的点击事件
  121. if (options.dragListClick) {
  122. options.dragListClick(this, event);
  123. }
  124. if ($(this).is(".item")) {
  125. event.stopPropagation();
  126. doc.click();
  127. }
  128. });
  129. dragList_.on("mousedown", function (event) {
  130. // 列表的点击事件
  131. focusList(this);
  132. if ($(this).is(".item")) {
  133. event.stopPropagation();
  134. doc.mousedown();
  135. }
  136. });
  137. dragList_.on("mouseup", function (event) {
  138. // 列表的点击事件
  139. if ($(this).is(".item")) {
  140. event.stopPropagation();
  141. doc.mouseup();
  142. }
  143. });
  144. dragList_.off("selectAll").on("selectAll", function () {});
  145. item_.on("dblclick", function () {});
  146. item_.on("click", function (event) {
  147. if (options.itemClick) {
  148. console.log("itemclick_id:" + this.id);
  149. options.itemClick(this, event);
  150. }
  151. });
  152. item_.on("mousedown", function (event) {
  153. currentMouseDownItem = this;
  154. $(".L", doc).removeClass("L");
  155. $(this).addClass("ready").addClass("L");
  156. if (event.shiftKey) {
  157. if ($(".F").length > 0) {
  158. if ($(this).isChildOf($(".F").eq(0).parent())) {
  159. shiftSelect();
  160. } else {
  161. $(this).removeClass("L");
  162. return false;
  163. }
  164. }
  165. } else if (event.ctrlKey) { // 按下ctrl多选
  166. } else {} {
  167. if ($(this).is(".selected")) { // 第二次或以上选中
  168. if (options.onSelectedClick) {
  169. options.onSelectedClick(this);
  170. }
  171. } else { // 第一次选中
  172. if (options.onItemSelect) {
  173. options.onItemSelect(this);
  174. }
  175. }
  176. }
  177. if ($(this).is(".dragList.expand")) {
  178. focusList(this);
  179. } else {
  180. focusList($(this).parents(".dragList").eq(0));
  181. }
  182. dragItemDown = true;
  183. if (drager.list != null) {
  184. return false;
  185. }
  186. dragStartPoint = {
  187. x: event.clientX,
  188. y: event.clientY
  189. };
  190. event.stopPropagation();
  191. return false;
  192. });
  193. item_.on("mouseup", function (event) {
  194. if (event.shiftKey) {
  195. if ($(".F").length > 0) {
  196. if ($(this).isChildOf($(".F").eq(0).parent())) {} else {
  197. return false;
  198. }
  199. }
  200. }
  201. dragItemDown = false;
  202. $(".F").removeClass("F");
  203. $(this).removeClass("L").addClass("F");
  204. if (dashedDrawing) {
  205. return;
  206. }
  207. // 鼠标弹起,主要是标记跟取消标记
  208. if ($(".focused .selected").length < 2 && !event.shiftKey &&
  209. !event.ctrlKey) {
  210. $(".selected", doc).not(".L").removeClass("selected");
  211. }
  212. if (event.shiftKey || event.ctrlKey) {
  213. if (!event.shiftKey) {
  214. $(".L", doc).toggleClass("selected dselected");
  215. }
  216. } else {
  217. $(".dragList>.item", doc).not(".ready").removeClass("selected");
  218. }
  219. $(".ready", doc).addClass("selected").removeClass("ready");
  220. event.stopPropagation();
  221. return false;
  222. });
  223. item_.on("click", function () {});
  224. item_.off("itemOut").on("itemOut", function (event) {
  225. if ($(this).is(".dragList")) {
  226. if (this.intervalID)
  227. clearInterval(this.intervalID);
  228. }
  229. });
  230. item_.off("itemEnter").on(
  231. "itemEnter",
  232. function (event) {
  233. if ($(this).is(".dragList")) {
  234. var this_ = $(this);
  235. var id = setInterval(function () {
  236. if (dragItemDown &&
  237. !this_.is(".dragList .dragList .dragList")) {
  238. this_.trigger("showT");
  239. }
  240. clearInterval(id);
  241. this_[0].intervalID == null;
  242. }, 1000);
  243. this.intervalID = id;
  244. }
  245. });
  246. handle_.off("click").on("click", function (event) {
  247. if (options.handleClick && !justDragEnd) {
  248. try {
  249. console.log("handle_click_id:" + this.id);
  250. options.handleClick(event, this);
  251. } catch (e) {
  252. console.error(e.message);
  253. }
  254. }
  255. if (justDragEnd) {
  256. justDragEnd = false;
  257. }
  258. });
  259. handle_.off("dblclick").on("dblclick", function (event) {
  260. if (options.handledbclick) {
  261. options.handledbclick(event, this);
  262. }
  263. });
  264. handle_.off("mouseup").on("mouseup", function (event) {
  265. if (options.handleMouseUp) {
  266. try {
  267. options.handleMouseUp(event, this);
  268. } catch (e) {
  269. console.error(e.message);
  270. }
  271. }
  272. });
  273. handle_.hover(function (event) {
  274. $(this).css("cursor", 'move');
  275. if (event.shiftKey) {
  276. if ($(".F").length > 0) {
  277. if ($(this).parents(".item").eq(0).isChildOf(
  278. $(".F").eq(0).parent())) {} else {
  279. $(this).css("cursor", 'not-allowed');
  280. }
  281. }
  282. }
  283. }, function (event) {
  284. $(this).css("cursor", 'move');
  285. });
  286. handle_.off("mousedown").on("mousedown", function (event) {
  287. if (options.handleMouseDown) {
  288. try {
  289. options.handleMouseDown(event, this);
  290. } catch (e) {
  291. console.error(e.message)
  292. }
  293. }
  294. });
  295. $("form", doc).on("keydown", function (event) {
  296. if (event.keyCode === 13) { // 回车提交表单
  297. return false;
  298. }
  299. });
  300. window.options = options;
  301. // 其他初始化
  302. if ($("#dragcss").length < 1) {
  303. $("head", doc).append(dragcss);
  304. } { // 设置拖选虚线框
  305. if (options.dashedField && $(options.dashedField).length > 0) {
  306. // setDashedField(options.dashedField);
  307. }
  308. }
  309. // { //设置handle前面的checkbox
  310. // if (options.selectBox) {
  311. // $(".dCheck").remove();
  312. // $.each($(".dragList .item"), function (index) {
  313. // var firstHandle = $(this).children(".handle").eq(0);
  314. // var itemid = firstHandle.parent().attr("id");
  315. // var dcheck = $("<input type='" + options.checkbox.type + "' name='" +
  316. // options.checkbox.name.replace("{#index}", index).replace("{#itemid}",
  317. // "item" + itemid) + "' class='dCheck' />");
  318. // firstHandle.prepend(dcheck);
  319. // });
  320. // }
  321. // //绑定checkbox的事件
  322. // $(".dCheck").off("mousedown click mouseup").on("mousedown click mouseup",
  323. // function (event) {
  324. // var handle = $(this).parents(".handle").eq(0);
  325. // var item =$(this).parents(".item").eq(0);// findClosestObj(this,
  326. // ".item");
  327. // //focusList(handle);
  328. // if (this.checked) {
  329. // item.addClass("selected dselected");
  330. // } else {
  331. // item.removeClass("selected dselected");
  332. // }
  333. // doc.mouseup();
  334. // event.stopPropagation();
  335. // });
  336. // }
  337. clearSlct();
  338. draginited = true;
  339. };
  340. /**
  341. *
  342. * shift选择
  343. */
  344. function shiftSelect() {
  345. var f = $(".F", doc);
  346. if (f.length <= 0 || $(".L", doc).length <= 0) {
  347. return;
  348. }
  349. $(".selected", doc).removeClass("selected");
  350. $(".F", doc).nextAll(".item").addClass("selected");
  351. $(".L", doc).nextAll(".item").toggleClass("selected");
  352. $(".F", doc).addClass("selected");
  353. $(".L", doc).addClass("selected");
  354. };
  355. /**
  356. * 根据ID查找targetList里面跟item重复的内容
  357. *
  358. */
  359. function distnic() {
  360. $.each($(".dragList", doc), function (index) {
  361. result = true;
  362. var par = $(this);
  363. $.each($(this).find(".item"), function (index) {
  364. var id = $(this).attr("id");
  365. if (id && par.find(" [id=" + id + "]").length > 1) {
  366. result = false;
  367. if (id && par.find(" [id=" + id + "]").length > 1) {
  368. par.find(" [id=" + id + "]").not(":first").remove();
  369. }
  370. }
  371. });
  372. })
  373. };
  374. /**
  375. * 查看鼠标是否在目标上方
  376. *
  377. * @param {目标}
  378. * target
  379. * @param {MouseEvent}
  380. * event
  381. */
  382. jQuery.fn.isMouseOver = function (event) {
  383. var target = this;
  384. if ($(target).length < 1 || $(target).is(".ghost"))
  385. return;
  386. // console.log("判断鼠标是不是在目标上方");
  387. var xy = $(target).getSize();
  388. // console.log("---------------------------");
  389. // console.log(getSize($(".item.dragList")));
  390. // console.log($(".item.dragList"));
  391. // console.log("===========================");
  392. var result = 1;
  393. // var tx = "";
  394. try {
  395. if ((event.clientX >= xy.left) &&
  396. (event.clientX <= (xy.left + xy.width + xy.margin)) &&
  397. (event.clientY >= xy.top) &&
  398. (event.clientY <= (xy.top + xy.height + xy.margin))) {
  399. if (event.clientX >= (xy.left - xy.margin) &&
  400. event.clientX <= (xy.left + (xy.width + xy.margin) / 2)) {
  401. result *= 1; // 左边
  402. } else if (event.clientX >= (xy.left + (xy.margin + xy.width) / 2) &&
  403. event.clientX <= (xy.left + xy.width + xy.margin)) {
  404. result *= 2; // 右边
  405. } else {
  406. result *= 0; // 不在上面
  407. }
  408. if (event.clientY >= (xy.top - xy.margin) &&
  409. event.clientY <= (xy.top + xy.height / 3)) {
  410. result *= 3; // 上半部分
  411. } else if (event.clientY > (xy.top + xy.height / 3) &&
  412. event.clientY <= (xy.top + xy.height + xy.margin)) {
  413. result *= 4; // 下半部分
  414. } else {
  415. result *= 0; // 不在上面
  416. }
  417. } else {
  418. result = 0
  419. }
  420. } catch (e) {
  421. console.log(e)
  422. }
  423. // console.group();
  424. // console.log(xy);
  425. // console.log(event.clientX+":"+(event.clientX>=xy.left &&
  426. // event.clientX<=(xy.left + xy.width + xy.margin)) + "-" + event.clientY + ":" + (event.clientY >= xy.top && event.clientY <= (xy.top + xy.height + xy.margin)));
  427. // console.log((xy.left)+":"+(xy.left + xy.width +
  428. // xy.margin)+"-"+xy.top+":"+(xy.top+xy.height+xy.margin));
  429. // console.groupEnd();
  430. // 左上1*3=3,右上2*3=6,左下1*4=4,右下2*4=8,不在0*0
  431. return result;
  432. };
  433. /**
  434. * 产生一个空白div
  435. */
  436. function generateGhost() {
  437. var firstItemSize = $(".selected", doc).eq(0).getSize();
  438. var ghost = $(".selected", doc).eq(0).clone();
  439. ghost.attr('id', 'ghost');
  440. if (ghost.is("tr")) {
  441. ghost
  442. .html('<td colspan="' + ghost.find("td").length +
  443. '">&nbsp;</td>');
  444. } else {
  445. ghost.html('');
  446. }
  447. ghost.dashMode = function () {
  448. ghost.css({
  449. "width": firstItemSize.width,
  450. "height": firstItemSize.height,
  451. "border": "1px dashed red",
  452. "border-radius": "5px",
  453. "margin": firstItemSize.margin,
  454. "background": "white"
  455. });
  456. }
  457. ghost.lineMode = function () {
  458. if (options.alignMode == 'vertical') {
  459. ghost.css({
  460. "width": "auto",
  461. "height": "2px",
  462. "border-width": "2px",
  463. "border-style": "solid",
  464. "border-color": "transparent red",
  465. "margin": 0,
  466. "background": "padding-box red"
  467. });
  468. } else {
  469. ghost.css({
  470. "width": "2px",
  471. "height": "auto",
  472. "border-width": "2px",
  473. "border-style": "solid",
  474. "border-color": "red transparent",
  475. "margin": 0,
  476. "background": "padding-box red"
  477. });
  478. }
  479. }
  480. ghost.removeClass("selected").removeClass("dragList");
  481. return ghost;
  482. };
  483. function setDashedField(item) {
  484. $(item) /* .off("mousedown") */ .on("mousedown",
  485. function (event) {
  486. $(this).data("position", $(this).css("position"));
  487. $(this).css({
  488. "position": "relative"
  489. });
  490. dashedStartPoint = getMouseCoordinateOf(this, event);
  491. startScrollPoint = {
  492. top: $(this)[0].scrollTop +
  493. findObjScrollParent(this)[0].scrollTop,
  494. left: $(this)[0].scrollLeft +
  495. findObjScrollParent(this)[0].scrollLeft
  496. };
  497. dashedEndPoint = dashedStartPoint = {
  498. x: dashedStartPoint.x + startScrollPoint.left,
  499. y: dashedStartPoint.y + startScrollPoint.top
  500. }
  501. if ($(".dasheddiv").length < 1) {
  502. $(this).append("<div class = 'dasheddiv' nowrap > <!--拖选正在测试中……<br/>有问题就反馈下<br/>目前遇到的问题是:滚动条--></div>")
  503. }
  504. var fieldSize = $(this).getSize();
  505. clickedField = $(this);
  506. dragListDown = true;
  507. });
  508. $(doc).on("mousemove", function () {
  509. if (dragListDown) {
  510. drawDashed(event);
  511. }
  512. });
  513. $(item) /* .off("mouseup") */ .on("mouseup", function (event) {
  514. $(this).css("position", $(this).data("position"));
  515. $(".dasheddiv").remove();
  516. dragListDown = false;
  517. startScrollPoint = dashedEndPoint = dashedStartPoint = {};
  518. });
  519. };
  520. function updateDashed(s, e) {
  521. e = e || s;
  522. if (!s.x || !s.y)
  523. return;
  524. var div = $(".dasheddiv");
  525. if (s.x > e.x) { // 交换x坐标
  526. s.x = [e.x, e.x = s.x][0];
  527. // s.x ^= e.x;
  528. // e.x ^= s.x;
  529. // s.x ^= e.x;
  530. }
  531. if (s.y > e.y) { // 交换y坐标
  532. s.y = [e.y, e.y = s.y][0];
  533. // s.y ^= e.y;
  534. // e.y ^= s.y;
  535. // s.y ^= e.y;
  536. }
  537. div.css({
  538. display: "block",
  539. left: s.x,
  540. top: s.y,
  541. width: Math.abs(e.x - s.x - 5),
  542. height: Math.abs(e.y - s.y - 5)
  543. });
  544. }
  545. function itemToList(event) {
  546. dragNowPoint = {
  547. x: event.clientX,
  548. y: event.clientY
  549. };
  550. var xdiff = dragStartPoint.x - dragNowPoint.x; // 计算两个点的横坐标之差
  551. var ydiff = dragStartPoint.y - dragNowPoint.y; // 计算两个点的纵坐标之差
  552. if (Math.pow((xdiff * xdiff + ydiff * ydiff), 0.5) < 10) {
  553. return false;
  554. }
  555. // console.log("将ITEM复制到LIST")
  556. drager.xy = $(".item.L", doc).eq(0).getSize();
  557. drager.left = event.clientX - drager.xy.left;
  558. drager.top = event.clientY - drager.xy.top;
  559. if ($(".selected").length < 2) {
  560. $(".selected").removeClass("selected");
  561. }
  562. if ($(currentMouseDownItem).is(".dragList")) {
  563. focusList($(currentMouseDownItem).parents(".dragList").eq(0));
  564. }
  565. $(".ready", doc).removeClass("ready").addClass("selected");
  566. // 取消父节点下子节点的选中状态,父节点移动就不会把子节点放出来
  567. $(".selected.item.dragList").find(".item").removeClass("selected");
  568. var items = $(".focused.dragList .selected,.focused.dragList .dselected",
  569. doc);
  570. if (items.length < 1) {
  571. drager = {};
  572. return;
  573. }
  574. $(".dragList:not(.focused)").children(".item").removeClass("selected");
  575. if (!drager.ghost) {
  576. drager.ghost = generateGhost();
  577. }
  578. // createshadows
  579. $.each(items, function () {
  580. var clone_ = $(this).clone();
  581. clone_.css("opacity", "0.5");
  582. // clone_.attr("class", "item shadow");
  583. clone_.addClass("shadow");
  584. clone_.removeClass("expand selected");
  585. // clone_.attr("id", "");
  586. $(this).after(clone_)
  587. this.shadow = clone_;
  588. if ($(this).hasClass("dragList")) {
  589. $(this).addClass("dragList_");
  590. $(this).removeClass("dragList");
  591. }
  592. });
  593. drager.items = items;
  594. drager.startpoint = $("<div style='display:none' id='startpoint'/>");
  595. items.eq(0).before(drager.ghost).before(drager.startpoint);
  596. drager.list = items.eq(0).parents(".dragList").eq(0).clone().html("")
  597. .removeClass("dragList");
  598. drager.list.append($("style", doc).clone());
  599. drager.list.css({
  600. "z-index": "99999",
  601. "background": "white ",
  602. "border": "1px dashed black ",
  603. "border-radius": ".3em ",
  604. 'position': "fixed",
  605. "padding": ".3em",
  606. "height": "auto"
  607. });
  608. drager.list.addClass("itemList");
  609. drager.list.width(drager.ghost.width())
  610. drager.list
  611. .append("<div style = 'clear:both;position:absolute;top:0;left:0;right:0;bottom:0;z-index:100000' class = 'panel' / > "); // 遮罩层
  612. drager.list.on("mousewheel DOMMouseScroll", function (e) { // 拖拽的时候滚动div
  613. var delta = (e.originalEvent.wheelDelta && (e.originalEvent.wheelDelta > 0 ? 1 : -1)) || // chrome & ie
  614. (e.originalEvent.detail && (e.originalEvent.detail > 0 ? -1 : 1)); // firefox
  615. findObjScrollParent(drager.ghost)[0].scrollTop -= delta * parseInt(drager.items.css("height").replace("px", ""));
  616. });
  617. if (items.eq(0).is('tr')) {
  618. var tb = $("<table class='list'></table>");
  619. tb.append(items);
  620. drager.list.append(tb);
  621. } else {
  622. drager.list.append(items);
  623. }
  624. $("body", doc).append(drager.list);
  625. };
  626. /**
  627. *
  628. * @param {MouseEvent}
  629. * event
  630. */
  631. function moveList(event) {
  632. justDragEnd = false;
  633. itemDraging = true;
  634. drager.list.css('left', (event.clientX - drager.left) + "px");
  635. drager.list.css('top', (event.clientY - drager.top) + "px");
  636. clearSlct();
  637. setGhost(event);
  638. };
  639. function setGhost(event, element) {
  640. var items = new Array();
  641. if (element) {
  642. if ($(element).is(".dragList")) {
  643. items = [element];
  644. } else {
  645. items = $(element).find(".dragList:not('.item')");
  646. }
  647. } else {
  648. items = $(".dragList:not('.item')", doc);
  649. }
  650. $.each(items, function () {
  651. var result = true;
  652. var theList = ($(this).children('tbody').length > 0) ? $(
  653. this).children('tbody') :
  654. $(this);
  655. if (theList.isMouseOver(event) > 0) {
  656. drager.list.children(".panel")
  657. .css("cursor", "move");
  658. if (theList.children('#ghost').length < 1) {
  659. theList.append(drager.ghost);
  660. }
  661. if (theList.is(yx)) {
  662. drager.ghost.slideDown();
  663. } else {
  664. drager.ghost.slideUp();
  665. }
  666. $.each(theList.children('.item'),
  667. function () {
  668. // drager.ghost.lineMode();
  669. var flag = true;
  670. var item = $(this);
  671. if ($(this).isMouseOver(event) > 0) { // 这里触发item的鼠标进出事件, 以后可能会调整, 同时这里的逻辑有点问题但是能用, 以后处理
  672. if (!this.isEnter) { // 从未进来过,这次进来了
  673. $(this).trigger(
  674. "itemEnter");
  675. this.isEnter = true; // 进来了
  676. }
  677. } else {
  678. if (this.isEnter) { // 曾经是进来过的
  679. $(this).trigger("itemOut");
  680. this.isEnter = false; // 出去了
  681. }
  682. }
  683. if (window.options &&
  684. window.options.alignMode != 'horizontal' || window.options && window.options.alignMode != 'hor') { // 如果不是水平分布,就上下拖动排序
  685. switch ($(this).isMouseOver(event)) {
  686. case 3: // 左上
  687. case 6: // 右上
  688. if (!item.prev().is(
  689. "#ghost")) {
  690. item
  691. .before(drager.ghost);
  692. }
  693. console.log("上半部分")
  694. flag = false;
  695. break;
  696. case 4:
  697. case 8:
  698. if (!item.next().is(
  699. "#ghost")) {
  700. item
  701. .after(drager.ghost);
  702. }
  703. console.log("下半部分")
  704. flag = false;
  705. break;
  706. }
  707. } else { // 不然就左右分布
  708. switch ($(this).isMouseOver(event)) {
  709. case 3: // 左上
  710. case 4: // 左下
  711. if (!item.prev().is("#ghost")) {
  712. item.before(drager.ghost);
  713. }
  714. console.log("左半部分")
  715. flag = false;
  716. break;
  717. case 6: // 右上
  718. case 8: // 右下
  719. if (!item.next().is("#ghost")) {
  720. item.after(drager.ghost);
  721. }
  722. console.log("半部分")
  723. flag = false;
  724. break;
  725. }
  726. result = false;
  727. }
  728. if (item.is(".dragList") && item.is(".expand")) {
  729. if (drager.list.children(".item").find(".item").length < 1) {
  730. setGhost(event, this);
  731. drager.list.children(".panel").css("cursor", "move");
  732. drager.list.children(".panel").attr("title", "");
  733. drager.ghost.dashMode();
  734. } else {
  735. drager.list.children(".panel").css("cursor", "not-allowed");
  736. drager.list.children(".panel").attr("title", "选中项存在子元素,不得放入该列表");
  737. drager.ghost.lineMode();
  738. }
  739. } else {
  740. drager.list.children(".panel").css("cursor", "move");
  741. drager.list.children(".panel").attr("title", "");
  742. drager.ghost.lineMode();
  743. }
  744. return flag
  745. });
  746. } else {}
  747. return result; // return true = continue;return false = break;
  748. });
  749. focusList(drager.ghost);
  750. }
  751. function drawDashed(event) {
  752. // 画虚线框
  753. dashedDrawing = true;
  754. if ($(".focused").length < 1) {
  755. return;
  756. }
  757. var nowScrollPoint = {
  758. top: $(".focused")[0].scrollTop +
  759. findObjScrollParent(".focused")[0].scrollTop,
  760. left: $(".focused")[0].scrollLeft +
  761. findObjScrollParent(".focused")[0].scrollLeft
  762. };
  763. dashedEndPoint = getMouseCoordinateOf('.focused', event);
  764. dashedEndPoint.x += nowScrollPoint.left;
  765. dashedEndPoint.y += nowScrollPoint.top;
  766. var xdiff = dashedStartPoint.x - dashedEndPoint.x; // 计算两个点的横坐标之差
  767. var ydiff = dashedStartPoint.y - dashedEndPoint.y; // 计算两个点的纵坐标之差
  768. if (Math.pow((xdiff * xdiff + ydiff * ydiff), 0.5) < 8) {
  769. return false;
  770. }
  771. // 重新定义起点终点坐标
  772. var fieldSize = $(".focused").getSize();
  773. start = {
  774. x: dashedStartPoint.x,
  775. y: dashedStartPoint.y
  776. };
  777. var end = {
  778. x: dashedEndPoint.x,
  779. y: dashedEndPoint.y
  780. };
  781. var scrollwidth = $(".focused")[0].scrollWidth;
  782. var scrollheight = $(".focused")[0].scrollHeight;
  783. // 让虚线框保持在draglist里面
  784. start.x = start.x < 0 ? 0 : ((start.x > scrollwidth) ? scrollwidth :
  785. start.x);
  786. start.y = start.y < 0 ? 0 : ((start.y > scrollheight) ? scrollheight :
  787. start.y);
  788. end.x = end.x < 0 ? 0 : ((end.x > scrollwidth) ? scrollwidth : end.x);
  789. end.y = end.y < 0 ? 0 : ((end.y > scrollheight) ? scrollheight : end.y);
  790. updateDashed(start, end);
  791. var ds = $(".dasheddiv").getSize();
  792. $(".selected", doc).removeClass("selected");
  793. $.each($(".focused").find(".item"), function (index) {
  794. var is = $(this).getSize();
  795. // 判断是否重叠
  796. if ((is.top >= ds.top && (is.top) <= (ds.top + ds.height)) ||
  797. (is.top + is.height) >= ds.top &&
  798. (is.top + is.height) <= (ds.top + ds.height)) { // item的y在拖选匡的y里面
  799. if ((is.left >= ds.left && is.left <= (ds.left + ds.width)) ||
  800. ((is.left + is.width) >= ds.left && is.left < ds.left))
  801. $(this).addClass("selected");
  802. } else if (is.top <= ds.top &&
  803. (is.top + is.height) >= (ds.top) ||
  804. is.top <= (ds.top + ds.height) &&
  805. (is.top + is.height) >= (ds.top + ds.height)) {
  806. if ((is.left >= ds.left && is.left <= (ds.left + ds.width)) ||
  807. ((is.left + is.width) >= ds.left && (is.left + is.width) <= (ds.left +
  808. ds.width))) {
  809. $(this).addClass("selected");
  810. }
  811. }
  812. });
  813. clearSlct();
  814. };
  815. /**
  816. *
  817. * @param {MouseEvent}
  818. * event
  819. * @param {拖拽结束的回调}
  820. * callback
  821. */
  822. function _dragEnd(event, callback) {
  823. if (drager && drager.list) { // 清除拖拽列
  824. $(".F,.L,.N").removeClass("F L N");
  825. drager.ghost.parent().find(".shadow").each(function () {
  826. var shadow = this;
  827. drager.items.each(function () {
  828. if (shadow == this.shadow[0]) {
  829. $(shadow).slideUp();
  830. }
  831. });
  832. });
  833. drager.ghost.before(drager.items);
  834. $('.dragList', doc).css('background', "");
  835. $('.dragList tbody', doc).css('background', "");
  836. $.each(drager.items, function () {
  837. if ($(this).hasClass("dragList_")) {
  838. $(this).addClass("dragList");
  839. $(this).removeClass("dragList_");
  840. }
  841. });
  842. var result = true;
  843. if (itemDraging) { // 回调
  844. justDragEnd = true;
  845. itemDraging = false;
  846. if (callback) {
  847. try {
  848. result = callback(event);
  849. } catch (e) {
  850. console.err(e.message);
  851. }
  852. }
  853. }
  854. if (result == false || !drager.ghost.is(":visible")) { // 取消移动
  855. $.each(drager.items, function () {
  856. $(this.shadow).before(this);
  857. this.shadow == null;
  858. });
  859. }
  860. drager.list.remove();
  861. drager.ghost.remove();
  862. drager.startpoint.remove();
  863. drager = {};
  864. distnic();
  865. $(".shadow").slideUp('fast', function () {
  866. $(".shadow").remove();
  867. });
  868. }
  869. if (dashedDrawing) {
  870. dashedDrawing = false;
  871. dashedDrawEnd = true;
  872. }
  873. $(".dasheddiv").remove();
  874. handleDown = false;
  875. itemDraging = false;
  876. dragItemDown = dragListDown = false;
  877. dashedEndPoint = dashedStartPoint = null;
  878. }
  879. /**
  880. * 获取最靠近的带滚动条的父级
  881. *
  882. * @param {Object}
  883. * obj
  884. * @param {Object}
  885. * i
  886. */
  887. function findObjScrollParent(obj, i) {
  888. i = i || 0;
  889. i++;
  890. // console.log($(obj)[0].tagName + ":" + ($(obj)[0].tagName != "HTML"))
  891. var par = $(obj).parent();
  892. if ($(obj)[0].tagName == "HTML") {
  893. return $(obj).find("body");
  894. }
  895. if (isCanScroll(par)) {
  896. return $(par);
  897. } else {
  898. return findObjScrollParent(par, i);
  899. }
  900. }
  901. /**
  902. * 判断是否带滚动条
  903. *
  904. * @param {Object}
  905. * obj
  906. */
  907. function isCanScroll(obj) {
  908. if (obj) {
  909. // console.log(obj)
  910. var of = $(obj).css("overflow-y");
  911. return ("scroll|auto".indexOf( of ) > -1) && (obj[0].scrollHeight > 0);
  912. } else {
  913. console.groupEnd()
  914. return false
  915. }
  916. }
  917. /**
  918. * 查找最近的.dragList
  919. *
  920. * @param {Object}
  921. * obj
  922. */
  923. function findClosestDragList(obj) {
  924. var o = $(obj);
  925. if (o.is("td")) {
  926. // -td tr tbody table
  927. return o.parent().parent().parent();
  928. } else if (o.is("tr")) {
  929. return o.parent().parent();
  930. } else if (o.is("body")) {
  931. return o.parent();
  932. } else if (o.is(".dragList")) {
  933. return o;
  934. // } else if (o.is(".item") || o.is("#ghost")) {
  935. // return o.parent();
  936. // } else if (o.is(".handle")) {
  937. // return o.parent().parent();
  938. } else {
  939. return o.parents(".dragList").eq(0);
  940. }
  941. }
  942. /**
  943. * 查找最近的父级的selector 元素
  944. *
  945. * @param {Object}
  946. * obj
  947. * @param {Object}
  948. * selector
  949. */
  950. function findClosestObj(obj, selector) {
  951. // try {
  952. // console.log(obj);
  953. // var par = $(obj).parent();
  954. // if (par.is(selector)) {
  955. // return par;
  956. // } else {
  957. // return findClosestObj(par, selector);
  958. // }
  959. // } catch (e) {
  960. // console.log(e.message)
  961. // return {
  962. // length: 0
  963. // }
  964. // }
  965. return $(obj).parents(selector).eq(0);
  966. }
  967. /**
  968. * 获取鼠标在selector的相对位置
  969. *
  970. * @param {Object}
  971. * selector
  972. * @param {Object}
  973. * event
  974. */
  975. function getMouseCoordinateOf(selector, event) {
  976. var top, left, oDiv;
  977. if ($(selector).length < 1)
  978. return;
  979. oDiv = $(selector)[0];
  980. top = getY(oDiv);
  981. left = getX(oDiv);
  982. function getX(obj) {
  983. var parObj = obj;
  984. var left = obj.offsetLeft;
  985. while (parObj = parObj.offsetParent) {
  986. left += parObj.offsetLeft;
  987. }
  988. return left;
  989. }
  990. function getY(obj) {
  991. var parObj = obj;
  992. var top = obj.offsetTop;
  993. while (parObj = parObj.offsetParent) {
  994. top += parObj.offsetTop;
  995. }
  996. return top;
  997. }
  998. var result = {
  999. x: (event.clientX - left + document.body.scrollLeft) - 2,
  1000. y: (event.clientY - top + document.body.scrollTop) - 2
  1001. }
  1002. return result;
  1003. }
  1004. /**
  1005. * 设置list的焦点样式
  1006. *
  1007. * @param {Object}
  1008. * obj
  1009. */
  1010. function focusList(obj) {
  1011. $(".focused").removeClass("focused");
  1012. findClosestDragList(obj).addClass("focused");
  1013. };
  1014. /**
  1015. * 注销掉拖拽
  1016. */
  1017. function destroyDrag() {
  1018. _dragEnd(event);
  1019. $.each($(".dragList", doc), function () {
  1020. $(this).before($(this).clone())
  1021. $(this).remove();
  1022. })
  1023. doc.off("selectstart keydown keyup mousedown mouseup mousemove click");
  1024. $("#dragcss").remove();
  1025. $(".dCheck").remove();
  1026. $("#dragcss").remove();
  1027. }
  1028. /**
  1029. * 清除选中的文字
  1030. */
  1031. var clearSlct = "getSelection" in window ? function () {
  1032. window.getSelection().removeAllRanges();
  1033. } : function () {
  1034. document.selection.empty();
  1035. };
  1036. function setUpTriangle(dragList) {
  1037. var span = $("<span/>");
  1038. var list = $(dragList);
  1039. span.isShow = false;
  1040. span.addClass("triangle");
  1041. var defaulthigh = list.height();
  1042. list.on("hideT", function () {
  1043. if (!span.isShow)
  1044. return;
  1045. span.isShow = false;
  1046. $(this).css("overflow", "hidden");
  1047. $(this).animate({
  1048. height: defaulthigh
  1049. }, "fast");
  1050. $(this).removeClass("expand");
  1051. focusList($(this).parents(".dragList").eq(0));
  1052. });
  1053. list.on("showT", function () {
  1054. if (span.isShow)
  1055. return;
  1056. span.isShow = true;
  1057. $(this).addClass("expand");
  1058. if ($(this).children(".item").length == 0) {
  1059. $(this).animate({
  1060. height: $(this).height() * 2,
  1061. "overflow": "visible"
  1062. }, "fast");
  1063. } else {
  1064. $(this).css({
  1065. "overflow": "visible"
  1066. });
  1067. $(this).autoHeightAnimate("fast", function () {
  1068. $(this).height("auto");
  1069. });
  1070. }
  1071. focusList(this);
  1072. });
  1073. span.click(function (event) {
  1074. if (span.isShow) {
  1075. list.trigger("hideT");
  1076. } else {
  1077. list.trigger("showT");
  1078. }
  1079. event.stopPropagation();
  1080. return false;
  1081. });
  1082. list.prepend(span);
  1083. list.css("overflow", "hidden");
  1084. list.css("height", list.children(".item").eq(0).height());
  1085. var n = span.next();
  1086. n.css("display", "inline-block");
  1087. n.css("padding-left", 15);
  1088. span.animate({
  1089. "top": (n.height() - 10) / 2 + "px"
  1090. }, "fast");
  1091. dragList.triangle = span[0];
  1092. }
  1093. jQuery.fn.autoHeightAnimate = function (time, callback) {
  1094. var element = this;
  1095. this.curHeight = element.height(); // Get Default Height
  1096. element.height('auto'); // Get Auto Height
  1097. this.autoHeight = element.height()
  1098. element.height(this.curHeight); // Reset to Default Height
  1099. if (this.autoHeight)
  1100. element.stop().animate({
  1101. height: this.autoHeight
  1102. }, time, null, callback); // Animate to Auto Height
  1103. }
  1104. jQuery.fn.isChildOf = function (b) {
  1105. return this.parent()[0] == $(b)[0];
  1106. };
  1107. jQuery.fn.getSize = function () {
  1108. var obj = $(this);
  1109. var xy = {};
  1110. if (!isDom(obj)) {
  1111. console.group("------------------------");
  1112. console.log(obj);
  1113. console.error(obj + "不是DOM对象");
  1114. console.groupEnd("------------------------");
  1115. return xy;
  1116. }
  1117. var offset = obj.offset();
  1118. if (offset) {
  1119. xy.top = offset.top - $("body", doc)[0].scrollTop; // 距离浏览器上边距的高 top
  1120. xy.left = offset.left; // 左
  1121. xy.width = obj.outerWidth(); // 宽
  1122. xy.height = obj.outerHeight(); // 高
  1123. xy.margin = parseInt(obj.css('margin').replace("px", "")) || 0;
  1124. xy.margin = isNaN(xy.margin) ? 0 : xy.margin;
  1125. }
  1126. function isDom(obj) {
  1127. obj = obj[0] || obj;
  1128. if (typeof HTMLElement === 'object')
  1129. return obj instanceof HTMLElement;
  1130. else
  1131. return obj && typeof obj === 'object' && obj.nodeType === 1 &&
  1132. typeof obj.nodeName === 'string';
  1133. }
  1134. return xy;
  1135. };