I am working on creating an overflow effect with tagging that fades out at the beginning to provide a subtle hint to users that there is more content. Here is what it currently looks like:
https://i.stack.imgur.com/fXGBR.png
To achieve this, I added a fading gradient as a :after
element in the CSS and "activated" it using Vue's style binding when scrollWidth > offsetWidth
(indicating overflow bigger than the box itself).
However, I have encountered a problem where the calculation sometimes lags and does not accurately determine the scrollWidth, especially when entering a long word and then deleting it. In such cases, even though there is no tag remaining in the box, the overflow status is still falsely indicated. This behavior can be seen here: https://i.stack.imgur.com/yVhhd.png
I attempted to address this issue by placing the calculation inside a $nextTick()
, but it did not resolve the problem. Additionally, I tried implementing Vue's keyDown
, keyUp
, and keyPress
listeners, all to no avail.
A demonstration of this issue can also be viewed on CodePen.
Here is the code snippet showcasing the problem:
new Vue({
el: '#tagsinput',
data: {
input_value: "",
tags: []
},
methods: {
addTag: function() {
if (this.input_value > "") {
this.tags.push(this.input_value)
this.input_value = "";
// Refocus the text input, so it stays at the end
this.$refs.input.blur();
this.$nextTick(function() {
this.$refs.input.focus();
})
}
},
deleteTag: function() {
if (this.input_value == "") {
this.tags.pop()
}
}
}
})
.outter {
border: 1px solid red;
width: 250px;
overflow: hidden;
display: flex;
}
.inner {
border: 1px solid blue;
margin: 2px;
display: flex;
}
.tag {
border: 1px solid black;
margin: 2px;
}
input {
min-width: 80px;
width: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.2/vue.min.js"></script>
<div id="tagsinput">
<div class="outter" ref="outter">
<div class="inner" ref="inner">
<div class="tag" v-for="tag in tags">{{tag}}</div><input type="text" v-model="input_value" @keydown.enter="addTag" @keydown.delete="deleteTag">
</div>
</div>
Outter div scrollwidth: {{ $refs.outter ? $refs.outter.scrollWidth : null }}<br> Outter div offsetWidth: {{ $refs.outter ? $refs.outter.offsetWidth : null }}<br>
<br> Is overflowing: {{ ($refs.outter ? $refs.outter.scrollWidth : null) > ($refs.outter ?$refs.outter.offsetWidth : null) }}
</div>
<br><br> Type a really long word in, add and then delete it. "Is overflowing" will be the inverse, until you press Backspace <b>again</b>.
Any assistance with resolving this issue would be highly appreciated.