There is a recent requirement in a project that a paragraph of content that is more than 3 lines should be followed by ‘… More ‘buttons, click more buttons to display the complete content, after the content changes to’ fold ‘button, first take a look at the effect of my implementation, as shown below:



The following will tell about my practice, what is the optimization of the place or wrong place also please advise more ~

1, the first is to compare the height to determine whether overflow

Get ‘… ‘offsetHeight More ‘the height of the Dom node is moreDom, using it as the standard, and then getting the height of the component itself ‘this’ offsetHeight, such as limiting the display to 3 rows (maxRow=3), then comparing the height to determine whether to display ‘… $this.$el.offsetheight > maxRow* moredom. offsetHeight

2. The dichotomy method is adopted to intercept the content

Cyclic judgment to obtain the maximum number of contents that can be displayed, using the dichotomy method to intercept the maximum number of contents that can be displayed, MaxHeight * (this.maxrow + 2)) to capture more content that can be displayed. Math.floor(text.length / 2) displays the maximum number of contents that can be displayed. Contentdom.innertext = text.subString (0, math.floor (text.length / 2))) to assign a value to your content’s Dom node.Here is the code for the parent component:

// testText: // isLimitHeight: whether to restrict the content display // isOver: whether to display the exceeded prompt // moreClick: Click to expand, <test-more :testText="testText" :maxRow="1" :isLimitHeight="isLimitHeight" :isOver. Sync ="isOver" @moreclick ="moreClick" > <span slot="before"> </span> <span slot="after" v-if="isOver" {{moreText}}</span> </test-more> // js moreClick() { this.isLimitHeight = ! this.isLimitHeight; this.moreText = this.isLimitHeight ? '... More ':' pack up '; },Copy the code

Here is the code for this component:

<template> <div class="overBox"> <slot name="before"></slot> <span class="contentText">{{testText}}</span> <! --<slot name="after" class="moreText" @click="handleMore"></slot>--> class="moreText" @click="handleMore"> <slot name="after"></slot> </span> </div> </template> <script> export default { name: 'testMore', props: { testText: { type: String, default: '', }, isLimitHeight: { type: Boolean, default: False,}, maxRow: {type: Number, default: 1,},}, data() {return {isHide: false, False, // default not to display 'more'}; }, mounted() { this.init(); }, methods: { handleMore() { this.$emit('moreClick'); }, init() {if (this.islimitheight) {this.handleheight (); } else { const contentDom = this.$el.querySelector('.contentText'); contentDom.innerText = this.testText; } }, handleHeight() { this.$nextTick(() => { const contentBox = this.$el; const contentDom = this.$el.querySelector('.contentText'); const moreDom = this.$el.querySelector('.moreText'); // Set the display to inline-block and get its own height moredom.style. display = 'inline-block'; Const maxHeight = this.maxRow * moredom.offsetheight; // let n = 999; if (contentBox.offsetHeight > maxHeight) { let text = this.testText; while (contentBox.offsetHeight > maxHeight && n > 0) { if (contentBox.offsetHeight > maxHeight * (this.maxRow + 2)) { contentDom.innerText = text = text.substring(0, Math.floor(text.length / 2)); } else { contentDom.innerText = text = text.substring(0, text.length - 1); } n--; } this.$emit('update:isOver', true); } else { this.$emit('update:isOver', false); } }) }, }, watch: { testText() { this.init(); }, maxHeight() { this.init(); }, isLimitHeight() { this.init(); }, maxRow() { this.init(); ,}}}; </script> <style scoped> .overBox { margin: 200px 400px; } .moreText { margin-left: 8px; cursor: pointer; color: #3199F5; } </style>Copy the code