Skip to content

Commit 2416bad

Browse files
authored
fix(b-img-lazy): better initial inView check + new show prop (fixes #1755) (#2382)
1 parent 503ac8b commit 2416bad

File tree

2 files changed

+53
-12
lines changed

2 files changed

+53
-12
lines changed

src/components/image/fixtures/image.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@
2222
<b-img ref="right" right src="https://picsum.photos/200/200/?image=58"></b-img>
2323
<br>
2424
<b-img-lazy ref="lazy" blank blank-color="#f00" width="200" height="200" src="https://picsum.photos/200/200/?image=58"></b-img-lazy>
25+
<br>
26+
<b-img-lazy ref="lazy-show" show blank blank-color="#f00" width="200" height="200" src="https://picsum.photos/200/200/?image=58"></b-img-lazy>
2527
</div>

src/components/image/img-lazy.js

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import BImg from './img'
2-
import { isVisible, getBCR, eventOn, eventOff } from '../../utils/dom'
2+
import { getBCR, eventOn, eventOff } from '../../utils/dom'
33
const THROTTLE = 100
44

55
// @vue/component
@@ -41,6 +41,10 @@ export default {
4141
type: [Number, String],
4242
default: null
4343
},
44+
show: {
45+
type: Boolean,
46+
default: false
47+
},
4448
fluid: {
4549
type: Boolean,
4650
default: false
@@ -93,7 +97,7 @@ export default {
9397
return (!this.blankSrc || this.isShown) ? this.src : this.blankSrc
9498
},
9599
computedBlank () {
96-
return !((this.isShown || this.blankSrc))
100+
return !(this.isShown || this.blankSrc)
97101
},
98102
computedWidth () {
99103
return this.isShown ? this.width : (this.blankWidth || this.width)
@@ -102,15 +106,47 @@ export default {
102106
return this.isShown ? this.height : (this.blankHeight || this.height)
103107
}
104108
},
109+
watch: {
110+
show (newVal, oldVal) {
111+
if (newVal !== oldVal) {
112+
this.isShown = newVal
113+
if (!newVal) {
114+
// Make sure listeners are re-enabled if img is force set to blank
115+
this.setListeners(true)
116+
}
117+
}
118+
},
119+
isShown (newVal, oldVal) {
120+
if (newVal !== oldVal) {
121+
// Update synched show prop
122+
this.$emit('update:show', newVal)
123+
}
124+
}
125+
},
126+
created () {
127+
this.isShown = this.show
128+
},
105129
mounted () {
106-
this.setListeners(true)
107-
this.checkView()
130+
if (this.isShown) {
131+
this.setListeners(false)
132+
} else {
133+
this.setListeners(true)
134+
this.$nextTick(this.checkView)
135+
}
108136
},
109137
activated () {
110-
this.setListeners(true)
111-
this.checkView()
138+
/* istanbul ignore if */
139+
if (!this.isShown) {
140+
this.setListeners(true)
141+
this.$nextTick(this.checkView)
142+
}
112143
},
113144
deactivated () {
145+
/* istanbul ignore next */
146+
this.setListeners(false)
147+
},
148+
beforeDestroy () {
149+
/* istanbul ignore next */
114150
this.setListeners(false)
115151
},
116152
methods: {
@@ -119,19 +155,23 @@ export default {
119155
this.scrollTimeout = null
120156
const root = window
121157
if (on) {
158+
eventOn(this.$el, 'load', this.checkView)
122159
eventOn(root, 'scroll', this.onScroll)
123160
eventOn(root, 'resize', this.onScroll)
124161
eventOn(root, 'orientationchange', this.onScroll)
162+
eventOn(document, 'transitionend', this.onScroll)
125163
} else {
164+
eventOff(this.$el, 'load', this.checkView)
126165
eventOff(root, 'scroll', this.onScroll)
127166
eventOff(root, 'resize', this.onScroll)
128167
eventOff(root, 'orientationchange', this.onScroll)
168+
eventOff(document, 'transitionend', this.onScroll)
129169
}
130170
},
131-
checkView () {
171+
checkView () /* istanbul ignore next: can't test getBoundingClientRect in JSDOM */ {
132172
// check bounding box + offset to see if we should show
133-
if (!isVisible(this.$el)) {
134-
// Element is hidden, so skip for now
173+
if (this.isShown) {
174+
this.setListeners(false)
135175
return
136176
}
137177
const offset = parseInt(this.offset, 10) || 0
@@ -142,7 +182,9 @@ export default {
142182
b: docElement.clientHeight + offset,
143183
r: docElement.clientWidth + offset
144184
}
185+
/* istanbul ignore next */
145186
const box = getBCR(this.$el)
187+
/* istanbul ignore if */
146188
if (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b) {
147189
// image is in view (or about to be in view)
148190
this.isShown = true
@@ -180,8 +222,5 @@ export default {
180222
}
181223
}
182224
)
183-
},
184-
beforeDdestroy () {
185-
this.setListeners(false)
186225
}
187226
}

0 commit comments

Comments
 (0)