index.vue 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <template>
  2. <div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll">
  3. <div class="scroll-wrapper" ref="scrollWrapper" :style="{left: left + 'px'}">
  4. <slot></slot>
  5. </div>
  6. </div>
  7. </template>
  8. <script>
  9. const padding = 15 // tag's padding
  10. export default {
  11. name: 'scrollPane',
  12. data () {
  13. return {
  14. left: 0
  15. }
  16. },
  17. methods: {
  18. handleScroll (e) {
  19. const eventDelta = e.wheelDelta || -e.deltaY * 3
  20. const $container = this.$refs.scrollContainer
  21. const $containerWidth = $container.offsetWidth
  22. const $wrapper = this.$refs.scrollWrapper
  23. const $wrapperWidth = $wrapper.offsetWidth
  24. if (eventDelta > 0) {
  25. this.left = Math.min(0, this.left + eventDelta)
  26. } else {
  27. if ($containerWidth - padding < $wrapperWidth) {
  28. if (this.left < -($wrapperWidth - $containerWidth + padding)) {
  29. this.left = this.left
  30. } else {
  31. this.left = Math.max(this.left + eventDelta, $containerWidth - $wrapperWidth - padding)
  32. }
  33. } else {
  34. this.left = 0
  35. }
  36. }
  37. },
  38. moveToTarget ($target) {
  39. const $container = this.$refs.scrollContainer
  40. const $containerWidth = $container.offsetWidth
  41. const $targetLeft = $target.offsetLeft
  42. const $targetWidth = $target.offsetWidth
  43. if ($targetLeft < -this.left) {
  44. // tag in the left
  45. this.left = -$targetLeft + padding
  46. } else if ($targetLeft + padding > -this.left && $targetLeft + $targetWidth < -this.left + $containerWidth - padding) {
  47. // tag in the current view
  48. // eslint-disable-line
  49. } else {
  50. // tag in the right
  51. this.left = -($targetLeft - ($containerWidth - $targetWidth) + padding)
  52. }
  53. }
  54. }
  55. }
  56. </script>
  57. <style lang="less" scoped>
  58. .scroll-container {
  59. white-space: nowrap;
  60. position: relative;
  61. overflow: hidden;
  62. width: 100%;
  63. .scroll-wrapper {
  64. position: absolute;
  65. }
  66. }
  67. </style>