Я пытаюсь переместить 3 полосы прокрутки из 3 <div class = "container"> по имени класса с одним и тем же событием за один раз. Это мой подход:
В первую очередь делюсь обработчиком событий из скрипта
function handleScroll(event: any) {
let position: number = event._vts
let scrollOptions = {
left: position,
top: 0,
behavior: undefined
}
if (event._vts) {
if (graficas.length !== 0) {
console.info('muevo el array')
console.info('asi tengo el array -> ' + graficas)
const el0 = document.getElementsByClassName('container').item(0)
el0?.scroll(scrollOptions)
const el1 = document.getElementsByClassName('container').item(1)
el1?.scroll(scrollOptions)
const el2 = document.getElementsByClassName('container').item(2)
el2?.scroll(scrollOptions)
} else {
console.info('lleno el array')
for (let index = 0; index < document.getElementsByClassName('container').length; index++) {
graficas.push(document.getElementsByClassName('container')[index])
document.getElementsByClassName('container')[index].scrollBy(event._vts, 0)
console.info(document.getElementsByClassName('container')[index])
}
graficas.shift()
console.info('asi queda el array -> ' + graficas)
}
}
}
затем я разделяю часть шаблона, которая отображает диаграмму с полосами прокрутки, которые я хочу переместить:
<h2>CPU</h2>
<div class = "container" @scroll = "handleScroll">
<div class = "containerBody">
<Bar :data = "cpu" :options = "options" />
</div>
</div>
<h2>IO</h2>
<div class = "container" @scroll = "handleScroll">
<div class = "containerBody">
<Bar :data = "io" :options = "options" />
</div>
</div>
<h2>SEC</h2>
<div class = "container" @scroll = "handleScroll">
<div class = "containerBody">
<Bar :data = "sec" :options = "options" />
</div>
</div>
Любая идея, как я могу приблизиться к достижению этого?
@Mayank Есть ли конкретная причина, по которой вы добавили тег [node.js] к этому вопросу? Я не вижу смысла добавлять его, так как JavaScript работает в браузере...
Верно, но почти всегда разработка ведется с использованием node.js. Затем он упаковывается и отправляется для запуска в браузере.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Подход 1: вместо событий прокрутки слушайте событие колеса.
В основном пользователи прокручивают страницы жестами или колесиком мыши. При этом вы можете легко избежать бесконечного цикла (один свиток запускает другой и наоборот). Это не будет работать, когда пользователь прокручивает, перетаскивая маркер прокрутки.
Подход 2: прислушивайтесь к наведению курсора мыши, чтобы узнать, какой элемент находится непосредственно под курсором, и используйте только событие прокрутки этого элемента для синхронизации прокрутки.
Следующий фрагмент представляет собой модифицированную/упрощенную версию исходного кода для Vue Scroll Sync. В зависимости от сложности ваших потребностей (и вашей способности использовать сторонние зависимости в вашей кодовой базе), вы можете захотеть получить эту библиотеку напрямую, а не жестко программировать компонент.
Несколько уточнений:
uuid для обозначения различных регионов, положение прокрутки которых должно быть синхронизировано. Это предотвращает «двойной учет» данного события прокрутки при обновлении позиций прокрутки в других регионах.onScroll временно удаляется из div при изменении положения прокрутки. Опять же, это предотвращает поведение «двойного счета», которое может повлиять на плавную прокрутку.scroll-sync для достижения того же эффекта. Глубокая вложенность элементов DOM по-прежнему должна работать, потому что topNode компонента вычисляется при монтировании, а события отправляются/захватываются на этом узле.let uuid = 0;
Vue.component('scroll-sync', {
name: 'ScrollSync',
template: document.querySelector("#scroll-sync-template").innerHTML,
data() {
return {
topNode: null
}
},
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
mounted() {
let parent = this.$parent
while (parent) {
this.topNode = parent
parent = this.topNode.$parent
}
const vue = this;
this.topNode.$on('scroll-sync', function(data) {
if (data.emitter === vue.uuid) {
return
}
const {
scrollTop,
scrollHeight,
clientHeight,
barHeight
} = data
const scrollTopOffset = scrollHeight - clientHeight
vue.$el.onscroll = null
if (scrollTopOffset > barHeight) {
vue.$el.scrollTop = scrollTop;
}
window.requestAnimationFrame(() => {
vue.$el.onscroll = vue.handleScroll
})
})
this.$el.onscroll = this.handleScroll
},
methods: {
handleScroll: function(e) {
const vue = this
window.requestAnimationFrame(() => {
const {
scrollTop,
scrollHeight,
clientHeight,
offsetHeight
} = e.target
this.topNode.$emit('scroll-sync', {
scrollTop,
scrollHeight,
clientHeight,
barHeight: offsetHeight - clientHeight,
emitter: vue.uuid
})
})
}
}
});
Vue.config.productionTip = false;
new Vue({
el: '#app'
});.scroll-sync-container {
height: 100%;
width: 100%;
position: relative;
overflow: auto;
}<script src = "https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id = "app">
<div style = "display:flex;">
<scroll-sync vertical style = "height:500px;width:100px;margin-right:50px;">
<div style = "width:100px;height:1000px;background:linear-gradient(red, green, blue);"></div>
</scroll-sync>
<scroll-sync vertical style = "height:500px;width:100px;">
<div style = "width:100px;height:2000px;background:linear-gradient(red, green, blue);"></div>
</scroll-sync>
</div>
</div>
<div id = "scroll-sync-template">
<div class = "scroll-sync-container">
<slot></slot>
</div>
</div>
Можно ли использовать сторонние библиотеки для этой задачи? Существует плагин Vue, vue-scroll-sync, который может помочь. npmjs.com/package/vue-scroll-sync Даже если вы не можете использовать саму библиотеку, возможно, вы сможете вдохновиться реализацией.