Creating an IntersectionObserver with the Composition API: A Step-by-Step Guide

I am currently in the process of incorporating an IntersectionOberver that will update the url once the viewport transitions into a new section. I came across This thread and now endeavoring to apply it in vue 3 compositon api.

The script is being integrated into my index.vue file, which serves as the parent for all other vue components:

<template>
  <div class="container">
    <navbar></navbar>
    <social-media-bar></social-media-bar>
    <main>
      <home></home>
      <news></news>
      <vision></vision>
      <event-section></event-section>
      <artwork></artwork>
      <about></about>
      <donate></donate>
      <contact></contact>
      <partners></partners>
    </main>
    <footer-component></footer-component>
  </div>
</template>


<script setup>
import ... // component imports
import {onMounted, reactive} from "vue";
import router from "../js/router";

const state = reactive({
    sectionObserver: null
})

const sectionObserveHandler = (entries) => {
    for (const entry of entries) {
        if (entry.isIntersecting) {
            router.push({name: 'news', hash: '#news'})
        }
    }
}
  
const observeSections = () => {
    const options = {
        rootMargin: '0px 0px',
        threshold: 0
    }
    state.sectionObserver = new IntersectionObserver(sectionObserveHandler, options)
    const sections = document.querySelectorAll('.section')
    sections.forEach(section =>{
        state.sectionObserver.observe(section)
    })
}

onMounted(() => {
    observeSections()
})
</script>

Essentially, my current goal is to modify the url to .../#news when the viewport is scrolled to the next section.

Upon launching the web app, there are no error messages, but the url change does not take place when scrolling down to sections.

What could be causing this issue?

An observation at this point is that Phpstorm indicates at this line:

state.sectionObserver = new IntersectionObserver(sectionObserveHandler, options)

that:

Assigned expression type IntersectionObserver is not assignable to type UnwrapRef<null> ...   Type IntersectionObserver is not assignable to type null extends ShallowRef<infer V> ? V : (null extends Ref<infer V> ? UnwrapRefSimple<V> : UnwrapRefSimple<null>)     Type IntersectionObserver is not assignable to type null extends Ref<infer V> ? UnwrapRefSimple<V> : UnwrapRefSimple<null>

I have attempted changing state.sectionObserver to string, integer, or array, yet the error persists. However, it seems like the browser disregards these changes. Unsure whether this impacts the functionality.

Answer №1

After watching a fantastic tutorial by Kevin Powell on YouTube, I finally figured out the solution.

I had to insert this code snippet into the script setup section of my index.vue file:

onMounted(() => {
    const sections = document.querySelectorAll('section')
    const options = {
        threshold: 0.5
    }
    const observer = new IntersectionObserver(function(entries, observer) {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                console.log(entry.target)
            }
        })
    }, options)
    sections.forEach(section => {
        observer.observe(section)
    })
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Coordinating multiple API requests for optimal performance

I have a task where I need to retrieve data from two different API endpoints. Once both sets of data are fetched, I need to compare the information obtained from each source. I am familiar with fetching data from a single API endpoint and using a callback ...

Looking to adjust the title font size when exporting DataTable to Excel?

Would like to customize the title of an excel file exported from Datatable. I attempted to implement a solution found on a stackoverflow post, but it ended up applying the customization to the entire sheet. $("#datatable").DataTable({ ...

Troubleshooting: Height setting issue with Kendo UI Grid during editing using Jquery

Issue: My Kendo UI JQuery Grid is fully functional except for a bug that occurs when adding a new record. When I add and save a new record, the grid's footer "floats" halfway up the grid and the scrollbar disappears, making it look distorted. Furth ...

Updating Django database records with ajax

I'm currently working on a feature that involves filtering table data and updating the table using ajax. Here's what I have so far: Filter Form: <form id="search" method="POST" action="{% url 'article-filter' %}"> <input ...

An issue has occurred: Cannot access the properties of an undefined object (specifically 'controls')

I encountered an error message stating "TypeError: Cannot read property 'controls' of undefined" in the code that I am not familiar with. My goal is to identify the source of this error. Below is the HTML code snippet from my webpage: <div ...

Validator alert for AMP scripts

I have implemented the amp version for my content management system. Since each article has a different body, some include amp-instagram while others include amp-facebook, and so on. In order to cover all bases, I have added both amp-facebook and amp-inst ...

Error message occurs during compilation of basic Vue file in Webpack

When I execute webpack watch in the VS2017 task runner, it displays the following error: ERROR in ./wwwroot/js/src/App.vue Module build failed: SyntaxError: Unexpected token { at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:373:25) ...

Conditional Matching with Javascript Regular Expressions

My strings are formatted like this: #WTK-56491650H #=> want to capture '56491650H' #M123456 #=> want to capture 'M123456' I am trying to extract everything after the # character, unless there is a dash. In that case, I onl ...

the reason behind the peculiar behavior of angularjs ng-include

I am attempting to utilize an ng-template to iterate through my args in order to create an indented menu content. Unfortunately, I have encountered issues with ng-include not working as expected. I have tried adding a quote but it still does not work. For ...

I need to inform users that this application is not accessible on devices with small screens

Showing this app on a small device is not supported, such as when the device width falls between 320px and 480px. ...

When using props.onChange(e.target.value) in a textField component in Material UI, it unexpectedly returns an object instead of a value

function FormInput(props) { const classes = formInputStyles(); return ( <div> <TextField onChange={(e) => props.onChange(e.target.value)} InputProps={{ classes, disableUnderline: true }} {...pro ...

Loading a local FBX file in Three.js without the need to upload it

When attempting to load files selected by users in an HTML input, I encountered a problem with the loader expecting a URL in Linux style. I have tried various methods such as using a blob as a URL object, providing raw data to the FBX loader, and even usin ...

The ajax keypress event is malfunctioning and the ActionResult parameter is failing to capture any data

I am facing an issue where I want to update the value of a textbox using AJAX on keypress event, but the controller is not receiving any value to perform the calculation (it's receiving null). <script> $('#TotDiscnt').keypress(fu ...

Guidance on invoking the navigate function from a component displayed at the highest level of rendering

Within the react-navigation documentation, it is explained that you can initiate navigation from the top-level component using the following method: import { NavigationActions } from 'react-navigation'; const AppNavigator = StackNavigator(SomeA ...

Tap on the child to reveal their parent

I am working with a family tree that includes dropdown menus containing the names of parents and children. Each child has a link, and when I click on a child's link, I want their father to be displayed in the dropdown menu as the selected option. Can ...

Unlocking the secrets of retrieving store values in Vue.js components

This is the code for my store.js file: import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { isLoggedIn: !!localStorage.getItem('token'), isLog : !!localSto ...

Optimal Placement for FB.Event.subscribe

Here is the code I have implemented on my website for the Facebook Like and Share buttons. The functionality works seamlessly. When I click the Like button, a notification is promptly displayed on my Facebook profile page. Additionally, Facebook automatic ...

How to utilize the reduce method with an array of objects in JavaScript

Every week, a number of objects are delivered to me. Each object contains information such as date, hours, and other fields. I need to arrange these objects in an array based on the total hours for each day. Here is an example of the objects: var anArray ...

Exploring and Presenting Arrays using React JS

Recently, I have started working with react js and I am trying to add a search functionality to filter an array in React. My goal is to allow the user to enter a character in the textbox and only see the names that contain that specific character. So far, ...

Manipulate JSON insertions and character replacements using JavaScript or Python

I have a JSON file that contains an array of 500 objects. The structure of each object is as follows: { "books":[ { "title":"Title 1", "year":"2012", "authors":"Jack ; George", }, { "title":"Title 2", "year":" ...