У меня проблемы с наблюдателем на пересечении в Гэтсби js.
Существует фиксированный заголовок, который должен изменить цвет, когда какой-то раздел входит в 90% области просмотра.
Я создал компонент с именем IntersectionObserverComponent , который отображает div с абсолютной позицией и высотой 100vh. Идея состоит в том, чтобы включить этот компонент в раздел, который я хочу отслеживать с помощью Intersection Observer.
Вот мой компонент
class IntersectionObserverComponent extends React.PureComponent {
constructor(props) {
super(props)
//
this.observer = null
this.ref = React.createRef()
}
componentDidMount() {
const { root, threshold, callback } = this.props
('IntersectionObserver' in window
? Promise.resolve()
: import('intersection-observer')
).then(() => {
this.observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
callback(entry)
})
},
{ threshold, root }
)
if (this.ref.current) {
this.observer.POLL_INTERVAL = 100
this.observer.observe(this.ref.current)
}
})
}
componentWillUnmount() {
if (this.ref.current && this.observer) {
this.observer.unobserve(this.ref.current)
}
}
render() {
return (
<div
ref={this.ref}
style={{
height: '100vh',
position: 'absolute',
top: 0,
left: 0,
right: 0,
}}
></div>
)
}
}
export default IntersectionObserverComponent
А вот использование
import { handleHeaderStyle } from '../../utils/intersectionObserver'
const About = ({ isTrackable = false, handleChangeHeader = () => {} }) => {
// previousValues object is directly mutated in a handleHeaderStyle fn
const previousValues = { previousY: 0, previousRatio: 0 }
const colors = { prevColor: 'white', currColor: 'secondary' }
const handleIOCallback = entry => {
console.log(entry)
handleHeaderStyle(entry, colors, previousValues, handleChangeHeader)
}
return (
<section className="padding-top-m padding-bottom-tablet-portrait-96 header-behind background-gray-small-only">
{isTrackable ? <IO callback={handleIOCallback} /> : null}
<Container>
<Grid className="grid-padding-x">
<Cell small={12} large={8}>
<p className="margin-bottom-small-20 margin-bottom-tablet-portrait-32">
We are a brand and product development consultancy, that believes
in that design is essentially a problem-solving exercise that we
can apply to any sector, discipline or media.
</p>
<p className="margin-bottom-small-32">
We are founded on and by people who are driven by:
</p>
<ul className="arrow-bullets">
<li>
Crafting simple and notable components that build up your
brand’s value
</li>
<li>Discovery and research aimed at thoughtful practices</li>
<li>Attention to detail</li>
<li>Independence and creative freedom</li>
<li>Thinking that goes deeper</li>
</ul>
</Cell>
<Cell className="padding-top-m">
<Projects />
</Cell>
</Grid>
</Container>
</section>
)
}
export default About
А вот функция, которая обрабатывает logi c для обновления заголовка
export const handleHeaderStyle = (
IOEntry,
colors,
previousValues,
callback
) => {
if (!IOEntry || !colors || !previousValues || typeof callback !== 'function')
return
//
const { prevColor, currColor } = colors
const currentY = IOEntry.boundingClientRect.y
const currentRatio = IOEntry.intersectionRatio
const isIntersecting = IOEntry.isIntersecting
// going up
if (currentY > previousValues.previousY) {
if (currentRatio < previousValues.previousRatio && !isIntersecting) {
callback(prevColor)
}
}
// going down
else if (currentY < previousValues.previousY && isIntersecting) {
if (currentRatio > previousValues.previousRatio) {
callback(currColor)
}
}
previousValues.previousY = currentY
previousValues.previousRatio = currentRatio
}
Это работает очень хорошо на всех размерах экрана, когда я тестирую его в браузере настольного компьютера, но проблема возникает, когда я тестирую его на реальном мобильное устройство.
- Устройство: Iphone 7+, IOS 13.3.1
- Браузеры: Safari 12.1.1, Chrome 80
It отлично работает, если я не отпускаю палец во время прокрутки, но если я это сделаю, обратный вызов не срабатывает постоянно. Я также попытался установить POLL_INTERVAL на 100 мс, но это не помогло.
Я подозреваю, что это как-то связано с тем, как iOS Safari обрабатывает событие прокрутки (https://github.com/martinlaxenaire/curtainsjs/issues/18)
Вот тестовая ссылка на Netlify - https://nifty-einstein-c4cf08.netlify.com/
Я пытаюсь выяснить это уже несколько дней, заранее спасибо