Executing an if statement within a querySelectorAll NodeList

I have been working on structuring a blog post layout that involves having metadata fixed on one side while the content scrolls. I am utilizing position: sticky to achieve this effect.

The setup works well, but some types of content extend to 100% width, which causes them to overlap with the metadata as they scroll past. To address this issue, I am trying to implement an event listener that tracks the position of both elements and adds a class to the sticky element, setting its opacity to 0 when the other element passes over it.

The current solution functions properly when there is only one full-width (.fw) element on the page:

window.addEventListener('scroll', function() {
var a = document.querySelector('.postmeta-sticky').getBoundingClientRect(),
    b = document.querySelector('.fw').getBoundingClientRect();
    if((b.top <= (a.top + a.height)) && ((b.top + b.height) > a.top)) {
        $(".postmeta-wrap").addClass("overlap");
    } else {
        $(".postmeta-wrap").removeClass("overlap");
    }
});

However, because the post content gets generated dynamically, there could be multiple instances of .fw per page. Therefore, I am attempting to gather all instances using querySelectorAll for my second variable, but I seem to be running into issues making this work.

This is how far I've gotten:

window.addEventListener('scroll', function(){
  var a = document.querySelector(".postmeta-sticky").getBoundingClientRect(),
      objects = document.querySelectorAll(".fw");
  objects.forEach(function(object) {
    b = object.getBoundingClientRect();
    if ((b.top <= (a.top + a.height)) && ((b.top + b.height) > a.top)) {
      $(".postmeta-wrap").addClass("overlap");
    } else {
      $(".postmeta-wrap").removeClass("overlap");
    }
  });
});

Unfortunately, the code isn't functioning as expected. There must be some mistake or missing piece in my implementation.

Here are the links to see the issue in action and the simplified CodePen:

First instance only working in situ:

Simplified CodePen: https://codepen.io/MMS_/pen/VwQvvpm

Any assistance provided is highly appreciated.

jQuery(document).ready(function($) {
  window.addEventListener('scroll', function() {
    var a = document.querySelector(".sticky-content").getBoundingClientRect(),
      objects = document.querySelectorAll(".fw");
    objects.forEach(function(object) {
      b = object.getBoundingClientRect();
      if ((b.top <= (a.top + a.height)) && ((b.top + b.height) > a.top)) {
        $(".sticky-wrap").addClass("overlap");
      } else {
        $(".sticky-wrap").removeClass("overlap");
      }
    });
  });
});

Answer №1

To achieve the desired behavior, I made some adjustments to the code below. The issue was that the later elements with the class .fw were affecting the visibility of the meta element.

I modified the loop to use a for...of structure and included a break statement to end the loop when the element is hidden. Additionally, there was some refactoring done for better efficiency.

I hope these changes resolve the issue!

window.addEventListener('scroll', function(){
    var sticky = document.querySelector(".sticky-content");
    var a = sticky.getBoundingClientRect();
    var objects = document.querySelectorAll(".fw");
    for (object of objects) {
      b = object.getBoundingClientRect();
      if ((b.top <= (a.top + a.height)) && ((b.top + b.height) > a.top)) {
        sticky.parentNode.classList.add("overlap");
        break;
      } else {
        sticky.parentNode.classList.remove("overlap");
      }
    }
  });

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

Leverage and repurpose OOP objects

I am exploring how to inherit from Button using prototypes. Despite my efforts, the alerted name remains "Sarah" as it is the last Child created. I believe the Creator Class should be responsible for setting the name using a Method in Button. Check out m ...

Tips on Enhancing a Fetch Query in Laravel with the Help of Ajax

I am encountering difficulty fetching a list of cities with over 40,000 entries. The main issue is the lack of optimization as my browser becomes unresponsive while loading the city data. Within my Laravel Controller, the code snippet below showcases how I ...

carry out a task without changing direction

I have come across an interesting situation where one action response is displayed inside another action: {% extends '::layout.html.twig' %} {% block content %} <a class='btn $class' href='{{ path('esp_campaign_stop' ...

ASP.net Image slider using jQuery

I am in search of an image slider that I can customize to fit my needs, similar to the one showcased in the link provided below. Although I have already tailored the script to suit my requirements, I am currently facing an issue with changing the image tr ...

Dealing with the name attribute in an array of ngModels in Angular 4

In this scenario, I have a class that defines hobbies and a user. Here is the structure: interface IHobby { name: string; type: string; } class User { constructor(public name: string, public hobbies: IHobby[]) { } } Now, when implementing a templa ...

Align two separate unordered lists together in the center

Would it be possible to align two separate UL elements next to each other horizontally? Here is the code that I am currently working with: <div id="container"> <ul id="list1"> <li></li> <li></li> ...

What is the method for creating an array of strings in VueJS?

In my VueJS and Vuetify project, I am working on creating a modal that allows users to input strings into a text field. What I aim to achieve is adding the inputted string to an array when the user clicks on create button. For example, if I enter 'inp ...

The function inside setTimeout lost its scope

I'm struggling to make the following function work correctly. All aspects seem fine except that I believe I am encountering scope issues within the setTimeout function. This is the JavaScript code: function galContent(){ var hovInt; $(".eleme ...

How can I get the class name of the drop destination with react-dnd?

Imagine having this component that serves as a drop target module. import { useDrop } from 'react-dnd'; import './css/DraggableGameSlot.css'; type DraggableGameSlotProps = { className: string, text: string } function Draggable ...

Steps to ensure a dropdown menu remains expanded when its nested menu is selected

Check out this dropdown list here, but the issue arises when clicking on a nested menu item such as "Books Registration". Once that page loads, the dropdown menu collapses like shown here. Here's a snippet of the dropdown code: <ul class="nav nav- ...

Searching for hidden elements within a div using a filter option

An accordion is located inside a div and a search box has been added to the div with the intention of serving as a search filter. Some accordion elements are visible within the div while others are hidden. The problem arises when trying to make the filter ...

React app experiencing issues with onClick button methods not functioning as expected

Here is the React code for a sample homepage. My intention was to have the function run and update the page when the buttons are clicked. However, instead of updating the page, it keeps showing alerts. I have confirmed that the fetch function is pulling da ...

What is the best way to manage data that arrives late from a service?

Within my Angular application, I have a requirement to store data in an array that is initially empty. For example: someFunction() { let array = []; console.log("step 1"); this.service.getRest(url).subscribe(result => { result.data.forEach( ...

Encountering a bug: Error message pops up while trying to create an action

I have implemented a Jquery Jtable with functions for displaying data (list action), deleting records, and creating actions. While using it in asp.net web forms, I encountered an issue where the create action is not functioning correctly. The list and del ...

Using vue.js to make an HTTP GET request to a web API URL and display

I am currently utilizing vue.js to make an http request to a web api in order to retrieve a list of projects and display them in a list. However, I am encountering an issue where only one item from the response array of eight items is being rendered. Any a ...

Locate HTML attribute values with the help of BeautifulSoup

Trying to extract data from HTML using BeautifulSoup has proven to be more challenging than expected. Specifically, I am struggling with utilizing the .find() function correctly in this scenario. Take a look at the HTML snippet below: <div class="a ...

Is it possible to set a unique identifier in Vue.js that persists even after the page is reloaded?

Currently, I'm working on a small project diving into Vue js - a Habittracker. Unfortunately, there is a bug in my code. When the page is reloaded and new habits are added, the function that should change the background doesn't work as expected. ...

Leveraging CSS Modules alongside external packages

Below is the important section from my webpack.config.js file: module: { loaders: [ { test: /\.css$/, exclude: /node_modules/, loaders: [ "style-loader?sourceMap", "css-l ...

`Multiple confirmation modals appearing from delete button in vue-bootstrap`

Trying to find a solution for the issue of having a unique reference to the modal within this loop. I attempted giving the ref a grade.id at the end, but it didn't work with String interpolation and the b-modal ref. I also tried using :ref. Below is ...

Populating a table with information retrieved from a file stored on the local server

Here is the specific table I am working with: <div class="chartHeader"><p>Performance statistics summary</p></div> <table id="tableSummary"> <tr> <th>Measurement name</th> <th>Resul ...