Skip to content

Commit 063fa98

Browse files
committed
fix(IntersectionObserver): use root opt to fix Preview bug in IntersectionObserver
1 parent df04713 commit 063fa98

File tree

4 files changed

+55
-31
lines changed

4 files changed

+55
-31
lines changed

src/lib/Image/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ export default class ReactImage extends React.PureComponent {
119119
this.setState({
120120
loadObserve: true
121121
})
122-
})
122+
}, this.props.observer)
123123
}
124124

125125
componentWillUnmount() {
126-
unobserve(this.refDom.current)
126+
unobserve(this.refDom.current, this.props.observer)
127127
}
128128

129129
render() {

src/lib/Image/observer.js

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,46 @@ export const CanUseIntersecion = 'IntersectionObserver' in window
88
// const targets = []
99
const targets = new Map()
1010
/* eslint-disable */
11-
const ins = CanUseIntersecion ? new IntersectionObserver(excute) : null
11+
export function createObserver(container) {
12+
if(!CanUseIntersecion) {
13+
return null
14+
}
15+
const opt = {}
16+
if(container) {
17+
opt.root = container
18+
}
19+
return new IntersectionObserver(excute, opt)
20+
}
21+
// const ins = CanUseIntersecion ? new IntersectionObserver(excute) : null
22+
const ins = createObserver()
1223
/* eslint-enable */
1324

14-
export function observe(element, cb) {
25+
export function observe(element, cb, observer = ins) {
1526
if(!CanUseIntersecion) {
1627
return
1728
}
18-
ins.observe(element)
19-
targets.set(element, cb)
29+
observer.observe(element)
30+
targets.set(element, {
31+
cb,
32+
observer
33+
})
2034
}
2135

22-
export function unobserve(element) {
36+
export function unobserve(element, observer = ins) {
2337
if(!CanUseIntersecion) {
2438
return
2539
}
2640
targets.delete(element)
27-
ins.unobserve(element)
41+
observer.unobserve(element)
2842
}
2943

3044
function excute(entries) {
3145
entries.forEach(each => {
3246
const { target, intersectionRatio } = each
3347
if(intersectionRatio > 0) {
34-
const cb = targets.get(target)
35-
cb(each)
36-
unobserve(target)
48+
const tar = targets.get(target)
49+
tar.cb(each)
50+
unobserve(target, tar.observer)
3751
}
3852
})
3953
}

src/lib/ImgPreview/ImgPreview.jsx

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import ReactDOM from 'react-dom'
44
import LoadingIcon from '../LoadingIcon'
55
import ErrorIcon from '../ErrorIcon'
66
import Image from '../Image'
7+
import {createObserver} from '../Image/observer'
78
// import Store from './imgViewStore'
89
function find(list, arg) {
910
return list.findIndex(each => each === arg)
1011
}
11-
12+
let observer = null
1213
export default class ImgPpreview extends React.PureComponent {
1314
state = {
1415
// mouse position
@@ -44,15 +45,15 @@ export default class ImgPpreview extends React.PureComponent {
4445
exportPreview = (current, list) => {
4546
let l = this.state.images
4647
let c = current
47-
if (list) {
48+
if(list) {
4849
l = list
4950
}
5051
// 如果为number型则直接设置
51-
if (typeof c !== 'number') {
52+
if(typeof c !== 'number') {
5253
// 否则调用find方法找下标
5354
// 如果不存在则设为images
5455
const idx = find(l, c)
55-
if (idx === -1) {
56+
if(idx === -1) {
5657
l = [c]
5758
c = 0
5859
} else {
@@ -76,11 +77,11 @@ export default class ImgPpreview extends React.PureComponent {
7677
e.stopPropagation()
7778
e.preventDefault()
7879
const { keyCode } = e
79-
if (keyCode === 27) {
80+
if(keyCode === 27) {
8081
this.hide()
81-
} else if (keyCode === 37) {
82+
} else if(keyCode === 37) {
8283
this.prev()
83-
} else if (keyCode === 39) {
84+
} else if(keyCode === 39) {
8485
this.next()
8586
}
8687
}
@@ -93,10 +94,10 @@ export default class ImgPpreview extends React.PureComponent {
9394
*/
9495
hideHandle = e => {
9596
const { target } = e
96-
if (
97-
target === this.$close ||
98-
target === this.$el ||
99-
target === this.$footer
97+
if(
98+
target === this.$close
99+
|| target === this.$el
100+
|| target === this.$footer
100101
) {
101102
this.hide()
102103
}
@@ -194,7 +195,7 @@ export default class ImgPpreview extends React.PureComponent {
194195
*/
195196
mouseDownHandle = e => {
196197
e.stopPropagation()
197-
if (e.button !== 0) {
198+
if(e.button !== 0) {
198199
return
199200
}
200201
const container = this.$el
@@ -243,7 +244,7 @@ export default class ImgPpreview extends React.PureComponent {
243244
// 放大缩小功能
244245
// const delta = e.wheelDelta ? e.wheelDelta : -(e.detail || 0)
245246
let { scale } = this.state
246-
if (-e.deltaY < 0) {
247+
if(-e.deltaY < 0) {
247248
// 放大
248249
scale *= 1.2
249250
} else {
@@ -266,7 +267,7 @@ export default class ImgPpreview extends React.PureComponent {
266267
const width = img.naturalWidth
267268
let scale = 1
268269
const windwoWidth = (window.innerWidth * 3) / 4
269-
if (width > windwoWidth) {
270+
if(width > windwoWidth) {
270271
scale = windwoWidth / width
271272
}
272273
this.setState(
@@ -284,8 +285,8 @@ export default class ImgPpreview extends React.PureComponent {
284285
)
285286
}
286287

287-
imgOnError = e => {
288-
console.log('onError');
288+
imgOnError = () => {
289+
console.log('onError')
289290
this.setState({
290291
loaded: true,
291292
error: true
@@ -334,6 +335,12 @@ export default class ImgPpreview extends React.PureComponent {
334335
}
335336
}
336337

338+
componentDidMount() {
339+
if(!observer) {
340+
observer = createObserver(document.querySelector('.img-viewer-list'))
341+
}
342+
}
343+
337344
render() {
338345
const {
339346
state,
@@ -348,6 +355,7 @@ export default class ImgPpreview extends React.PureComponent {
348355
next,
349356
rotateFnc
350357
} = this
358+
const { current, images } = state
351359
return (
352360
<div
353361
id="imgPreview"
@@ -422,16 +430,17 @@ export default class ImgPpreview extends React.PureComponent {
422430
<div className="img-viewer-list">
423431
<div className="img-viewer-list-inner">
424432
<div style={this.imgListStyle}>
425-
{state.images.map((src, idx) => (
433+
{images.map((src, idx) => (
426434
<div
427435
onClick={() => this.change(idx)}
428436
key={idx}
429437
className={[
430438
'img-viewer-list-item',
431-
state.current === idx ? 'active' : ''
439+
current === idx ? 'active' : ''
432440
].join(' ')}
433441
>
434442
<Image
443+
observer={observer}
435444
width="50"
436445
height="50"
437446
preview={false}
@@ -449,11 +458,11 @@ export default class ImgPpreview extends React.PureComponent {
449458
}
450459
}
451460

452-
ImgPpreview.newInstance = function newNotificationInstance(callback) {
461+
ImgPpreview.newInstance = function newPreviewInstance(callback) {
453462
const div = document.createElement('div')
454463
let called = false
455464
function ref(ins) {
456-
if (called) {
465+
if(called) {
457466
return
458467
}
459468
called = true

src/lib/ImgPreview/style.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
overflow: hidden;
8181
.img-viewer-list-item {
8282
opacity: .5;
83+
font-size: 0px;
8384
&:hover {
8485
opacity: 1;
8586
}

0 commit comments

Comments
 (0)