MenuContainer.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <template>
  2. <div ref="whole">
  3. <div class="topbar" ref="topbar">
  4. <slot class="top-link"></slot>
  5. </div>
  6. <span class="arrow">
  7. <span class="top-link" ref="dropdownbutton">vv</span>
  8. <div class="dropdown" ref="dropdown" />
  9. </span>
  10. </div>
  11. </template>
  12. <script>
  13. export default {
  14. methods: {
  15. onResize() {
  16. this.update()
  17. },
  18. update() {
  19. let topbar = this.$refs.topbar
  20. let dropdown = this.$refs.dropdown
  21. let dropDownButton = this.$refs.dropdownbutton
  22. dropDownButton.classList.remove('alone', 'full')
  23. let dropdownWidth = dropDownButton.offsetWidth
  24. let topbarElements = Array.from(topbar.childNodes)
  25. let dropboxElements = Array.from(dropdown.childNodes)
  26. for(let el of dropboxElements) {
  27. dropdown.removeChild(el)
  28. topbar.appendChild(el)
  29. }
  30. let childAndSize = []
  31. for(let child of topbarElements.concat(dropboxElements)) {
  32. childAndSize.push([child.offsetWidth, child])
  33. }
  34. topbar.innerHTML = ''
  35. let width = this.$refs.whole.clientWidth - dropdownWidth - 50
  36. let tmp = 0
  37. for(let child of childAndSize) {
  38. tmp += child[0]
  39. if(width > tmp) {
  40. topbar.appendChild(child[1])
  41. } else {
  42. dropdown.appendChild(child[1])
  43. }
  44. }
  45. if(dropdown.childNodes.length === 0) {
  46. dropDownButton.classList.add('full')
  47. } else if(topbar.childNodes.length === 0) {
  48. dropDownButton.classList.add('alone')
  49. }
  50. }
  51. },
  52. mounted() {
  53. window.addEventListener('resize', this.onResize)
  54. //Initial menu sorting
  55. this.update()
  56. },
  57. beforeDestroy() {
  58. //TBI never will be closed...!
  59. window.removeEventListener('resize', this.onResize)
  60. }
  61. }
  62. </script>
  63. <style scoped>
  64. .whole {
  65. box-sizing: border-box;
  66. }
  67. .topbar > .top-link:first-child {
  68. border: none;
  69. }
  70. .top-link {
  71. box-sizing: border-box;
  72. white-space: nowrap;
  73. display: inline-block;
  74. padding: 0.2em 0.3em 0.2em 0.3em;
  75. border-left: solid 1px #aaa;
  76. color: #aaa;
  77. text-decoration: none;
  78. }
  79. .alone {
  80. border-left: none;
  81. }
  82. .full {
  83. display: none;
  84. }
  85. .topbar {
  86. box-sizing: border-box;
  87. display: inline-block;
  88. }
  89. .arrow {
  90. position: relative;
  91. }
  92. .dropdown {
  93. display: none;
  94. position: absolute;
  95. z-index: 1;
  96. min-width: 100%;
  97. top: 1.3em;
  98. left: 50%;
  99. transform: translateX(-50%);
  100. }
  101. .dropdown .top-link {
  102. border: none;
  103. border-top: 1px solid #aaa;
  104. display: block;
  105. position: relative;
  106. background-color: #222;
  107. }
  108. .arrow:hover .dropdown {
  109. display: inline-block;
  110. }
  111. .top-link:hover {
  112. background-color: #333;
  113. color: #ddd;
  114. }
  115. </style>