JSFiddle - React, Tailwind, and code Playground
by ChangJoo Park
HTML
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/axios-mock-adapter/dist/axios-mock-adapter.js"></script>
<div id="app">
<message-wrapper :messages="messages"></message-wrapper>
</div>
<template id="message-wrapper">
<div id="message-wrapper">
<message-item v-for="message in messages" :message="message"></message-item>
</div>
</template>
<template id="message-item">
<div class="message">
{{message}}
</div>
</template>
CSS
#message-wrapper {
width: 400px;
height: 400px;
background-color: tomato;
overflow-y: auto;
overflow-x: hidden;
}
JavaScript
var SCROLL_STATE = {
BOTTOM: 'BOTTOM',
MIDDLE: 'MIDDLE',
TOP: 'TOP'
};
Vue.component('message-wrapper', {
template: '#message-wrapper',
props: ['messages'],
data: function() {
return {
scrollState: '',
offset: 50,
}
},
mounted: function() {
console.log('[#message-wrapper] - mounted');
this.$el.addEventListener('scroll', this.updateScrollState)
this.scrollToBottom();
},
updated: function() {
this.updateScrollState();
},
watch: {
scrollState: function (newState, oldState) {
console.log(newState);
}
},
methods: {
updateScrollState: function () {
var scrollHeight = this.$el.scrollHeight;
var boxHeight = this.$el.clientHeight;
var currentTop = this.$el.scrollTop;
var isInTop = currentTop < this.offset;
var isInBottom = currentTop + boxHeight >= scrollHeight - this.offset;
if (isInTop) {
this.scrollState = SCROLL_STATE.TOP;
} else if (isInBottom) {
this.scrollState = SCROLL_STATE.BOTTOM;
} else {
this.scrollState = SCROLL_STATE.MIDDLE;
}
console.log('#updateScrollState : ', this.scrollState)
},
scrollToBottom: function() {
console.log('[#message-wrapper] - scroll to bottom');
this.$el.scrollTop = this.$el.scrollHeight;
}
}
});
Vue.component('message-item', {
template: '#message-item',
props: ['message'],
mounted: function() {
console.log('[#message-item] - mounted');
}
});
var dummyMessages = [];
for (var i = 0; i < 100; i++) {
dummyMessages.push('hello')
}
var vm = new Vue({
el: '#app',
data: function() {
return {
messages: dummyMessages
}
}
})
/*
setInterval(function () {
vm.$data.messages.push('new Hello :) ');
}, 1000);
*/