splitbox.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. (function () {
  2. function startDrag(node, splitter, event) {
  3. node.setAttribute('dragging', '');
  4. node.xtag.splitter = splitter;
  5. splitter.setAttribute('dragging', '');
  6. splitter.style.zIndex = node.xtag.splitZ = (node.xtag.splitZ || 0) + 1;
  7. var props = getProps(node);
  8. var lastCoord = event[props.page] - node[props.edge];
  9. var next = splitter.nextElementSibling, next = !next.hasAttribute('splitter') && next;
  10. var previous = splitter.previousElementSibling, previous = !previous.hasAttribute('splitter') && previous;
  11. var startingTotal = next[props.size] + previous[props.size];
  12. setPercents(node, props);
  13. node.xtag.drag = xtag.addEvent(node, 'move', function (e) {
  14. var delta = e[props.page] - node[props.edge] - lastCoord;
  15. var nextSize = next[props.size];
  16. var prevSize = previous[props.size];
  17. var nextMod = nextSize - delta;
  18. var prevMod = prevSize + delta;
  19. if (delta > 0) {
  20. if (nextSize > 0) {
  21. if (nextMod <= 0 || prevMod >= startingTotal || prevMod > startingTotal || nextMod > startingTotal) {
  22. prevMod = startingTotal;
  23. nextMod = 0;
  24. }
  25. setMinMax(next, props, nextMod);
  26. setMinMax(previous, props, prevMod);
  27. }
  28. }
  29. else if (delta < 0) {
  30. if (prevSize > 0) {
  31. if (prevMod <= 0 || nextMod >= startingTotal || prevMod > startingTotal || nextMod > startingTotal) {
  32. nextMod = startingTotal;
  33. prevMod = 0;
  34. }
  35. setMinMax(next, props, nextMod);
  36. setMinMax(previous, props, prevMod);
  37. }
  38. }
  39. lastCoord = e[props.page] - node[props.edge];
  40. });
  41. }
  42. function getProps(node) {
  43. return node.xtag.props = (node.direction == 'column') ? {
  44. page: 'pageY',
  45. size: 'clientHeight',
  46. edge: 'clientTop',
  47. parentSize: node.clientHeight
  48. } : {
  49. page: 'pageX',
  50. size: 'clientWidth',
  51. edge: 'clientLeft',
  52. parentSize: node.clientWidth
  53. };
  54. }
  55. function setPercents(node, props, setup) {
  56. node.xtag.panels = xtag.queryChildren(node, '*:not([splitter])').map(function (el) {
  57. setMinMax(el, props, el[props.size], setup);
  58. return el;
  59. });
  60. }
  61. function setMinMax(panel, props, value, setup) {
  62. panel.style.flex = panel.style[xtag.prefix.lowercase + 'Flex'] = (setup ? '0 0 ' : '1 1 ') + (value / props.parentSize) * 100 + '%';
  63. }
  64. function stopDrag(node) {
  65. if (node.xtag.drag) {
  66. xtag.removeEvent(node, node.xtag.drag);
  67. node.removeAttribute('dragging');
  68. node.xtag.splitter.removeAttribute('dragging');
  69. node.xtag.splitter = null;
  70. node.xtag.drag = null;
  71. }
  72. }
  73. xtag.addEvent(window, 'tapend', function (e) {
  74. xtag.query(document, 'x-splitbox[dragging]').forEach(stopDrag);
  75. })
  76. xtag.register('x-splitbox', {
  77. events: {
  78. 'tapstart:delegate(x-splitbox > [splitter])': function (e) {
  79. startDrag(e.currentTarget, this, e);
  80. },
  81. dragstart: function (e) {
  82. if (this.hasAttribute('dragging')) {
  83. e.preventDefault();
  84. return false;
  85. }
  86. },
  87. contextmemu: function (e) {
  88. e.preventDefault();
  89. }
  90. },
  91. accessors: {
  92. direction: {
  93. attribute: { def: 'row' },
  94. set: function (direction) {
  95. setPercents(this, getProps(this), true);
  96. }
  97. }
  98. }
  99. });
  100. })();