`Monitoring and adjusting page view during window resizing in a dynamic website`

Situation:
Imagine we are reading content on a responsive page and decide to resize the browser window. As the window narrows, the content above extends down, making the entire page longer. This results in whatever content we were previously viewing being pushed further down the page as we continue to adjust the window size.

Example:
For example, let's say we were exploring the Helper classes section on this webpage. When we shrink or expand the window significantly, the section we were focused on moves up or down within our current view.

Prompt:
Is there a solution to this issue? Can we maintain our current view of the page regardless of changes to the content above when resizing the window?

Thoughts:
One suggestion is to use JavaScript to detect window resize events and automatically scroll the page to the topmost element that was visible before the resize. However, concerns arise about potential performance impacts, especially on larger pages. Additionally, determining the exact "top-most element" may be challenging, as overlapping elements can complicate this definition.

This seems more like a flaw in default browser scrolling behavior rather than an inherent problem with responsive design. It raises questions about whether the current behavior aligns with user expectations or if improvements are needed for a smoother browsing experience.


Edit 4

A revised demo has been created based on Rick Hitchcock's suggested solution.

Using jQuery:

//onresize:
var scrollAmount;

if (topNode.getBoundingClientRect().top >= 0) {
    scrollAmount = $(topNode).offset().top - topNode.getBoundingClientRect().top;
} else {
    scrollAmount = $(topNode.offset().bottom - topNode.getBoundingClientRect().bottom;
}
$(window).scrollTop(scrollAmount);

The demo may behave inconsistently across browsers, so I have also hosted it here. Additional fixes are required for IE, Opera, and Safari related to elementFromPoint.


Edit 3

Appreciation for your assistance, Rick Hitchcock. Your insights have been invaluable. As discussions veer towards cross-browser compatibility challenges, I've accepted your answer as it addresses the core question. Nonetheless, refinements are still needed regarding cross-browser considerations, topNode selection criteria, and handling cutoff elements.

An interesting scenario arises:

Upon further exploration, transitioning from a small viewport to a larger one can lead to unexpected behavior at the bottom of the page. If additional elements become visible due to the wider viewport, locking the topNode may not always work as intended. Resolving this anomaly requires careful consideration and testing, particularly concerning how Opera handles such scenarios.

These edge cases will be addressed systematically, starting with evaluating the impact of scroll bottoms and devising measures to ensure consistent behavior across different browsers.

Answer №1

Below is my latest creation:

(function(){
   var topNode;

   window.onscroll=function() {
     var timer;
     (function(){
        clearTimeout(timer);
        timer= setTimeout(
                 function() {
                   var testNode;
                   topNode= null;
                   for(var x = 0 ; x < document.body.offsetWidth ; x++) {
                     testNode= document.elementFromPoint(x,2);
                     if(!topNode || testNode.offsetTop>topNode.offsetTop) {
                       topNode = testNode;
                     }
                   }
                 },
                 100
               )
      }
     )();
   }

   window.onresize=function() {
     var timer;
     (function(){
        clearTimeout(timer);
        if(topNode) {
          timer= setTimeout(function(){topNode.scrollIntoView(true)},10);
        }
      }
     )();
   }
 }
)();

If there were a window.onbeforeresize() function, this would be more straightforward.

Please note that the script does not consider the scrolled position of the element's textNode. Handling this would require only resizing the height of the window. Resizing the width generally causes reformatting.

This code snippet has been tested and works seamlessly on Chrome, Firefox, IE, and Safari.

Edit

How it operates

The use of closures in the code keeps variables private, while timers prevent continuous execution during scrolling/resizing. To enhance understanding, here's another version that simplifies the code structure. It's worth mentioning that the timer within onscroll is necessary in IE due to an issue described here.

var topNode;

window.onscroll=function() {
  setTimeout(
    function() {
      var testNode;
      topNode= null;
      for(var x = 0 ; x < document.body.offsetWidth ; x++) {
        testNode= document.elementFromPoint(x,2);
        if(!topNode || testNode.offsetTop>topNode.offsetTop) {
          topNode = testNode;
        }
      }
    },
    100
  )
}

window.onresize=function() {
  if(topNode) {
    topNode.scrollIntoView(true)
  }
}

topNode tracks the element at the top of the screen as it scrolls.

The function scans from left to right along the 3rd row: document.elementFromPoint(x,2)*

It avoids scanning the 1st row because in IE, when scrollIntoView is used, the element shifts down slightly, making the previous element the new top-most one. This was discovered through trial and error.

Upon window resize, topNode is positioned at the top of the screen.

[*Initially, onscroll scanned left to right along the 11th row (in pixels) until finding an element with just one child. This child was often a textNode but not always. For example:

<div><ul><li>...<li>...<li>...</ul></div>

The div only had one child – the ul. If the scroll position was at the 50th li, scanning left to right incorrectly returned the div because of padding on lis.

The original code has since been updated. ]

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

What is the best way to retrieve a linked filter in Vue from another?

I have created a file to store filters linked to my Vue object, and it is being imported into my App.js. One of the filters I have needs to use another filter: Vue.filter('formatDateTime', value => { if (value) return moment(String(value ...

I'm not satisfied with the value of the ReactJs state after the change

I am working on creating a calendar app for practice purposes. Currently, I have a current_month state variable set to 1. Additionally, I have a function called IncreaseMonth() that is designed to increment the value of current_month. However, when the va ...

Updating a section of a component using another component

I need to update the Header.vue component from the ConfirmCode Component when the confirm method is called When a user logs in with axios ajax, I want to refresh the li element of the header component Appointment.vue: <send-sms-modal@clickClose="setS ...

The FormControlLabel radio button within the RadioGroup is experiencing difficulty in becoming selected

Utilizing a RadioGroup component to showcase a dynamic list of Radio options using FormControlLabel. The dynamic radio choices are appearing correctly on the screen and I can obtain the selected radio option through onChange in RadioGroup. However, after s ...

Organizing the dropdown menu in alphabetical order

I am facing an issue with the following element <li id="li_15" class="dropdown dropdown-alpha highlighted" style=""> <label class="description" for="element_15">Name <span id="required_15" class="required">*</span></labe ...

How can I resolve the issue of a lengthy link spanning two lines in Internet Explorer, while displaying correctly in other browsers on a Bootstrap navigation

Currently in the process of developing a responsive website with Bootstrap. The navigation buttons at the top are displaying correctly in Chrome, Safari, and Firefox, but in IE, the button labeled "Public Consultation" is wrapping onto two lines. I suspec ...

Modify the ColVis Appearance in Datatable Using JavaScript

Where can I modify the background color for the 'Hide/Show columns' label in the ColVis.js file? ...

Pass data from Wordpress plugin to JavaScript function

I recently developed a plugin for a WordPress website. Inside the plugin, I am trying to call a JavaScript function (passing a string as a parameter) from a file that I have just enqueued. However, nothing seems to be happening. Can anyone help me identify ...

Transform a React component from a regular function to an ES6 class

Recently delving into ES6 and React, I found myself navigating through various ways to write a React component. My journey began with "React.createClass," then transitioned to utilizing "extends React.Component" with ES6 classes syntax. While following a ...

Creating dynamic axes and series in Ext JS 4 on the fly

I am looking to dynamically generate the Y axis based on a JSON response. For example: { "totalCount":"4", "data":[ {"asOfDate":"12-JAN-14","eventA":"575","eventB":"16","eventC":"13",...}, {"asOfDate":"13-JAN-14","eventA":"234","eventB":"46","even ...

Struggling with the conundrum of aligning a constantly changing element amid the

I was optimistic about the code I wrote, hoping it would work out in the end. However, it seems that my expectations might not be met. Allow me to provide some context before I pose my question. The animation I have created involves an SVG element resembl ...

Execute the knockout function using jQuery

There's a scenario where I am trying to trigger a knockout method using jQuery. The Knockout viewModel has already been bound, but I'm unsure of how to call it using jQuery. Below is the snippet of my code: $(document).ready() { form_submit( ...

"Although disabled, input elements can still be focused on in Firefox browser

Illustrative example let userInput = document.createElement("input"); userInput.id = "user-input"; userInput.type = "number"; userInput.className = "user-number-input"; userInput.disabled = true; document.body.appendChild(userInput); .number-inp ...

An error of type 'TypeError' has occurred, where it is unable to access the property 'render' of an undefined element in

I'm using a function in my controller to render the "result" in my "home-page" view, which is calling my model to execute the query. exports.searchNoms = (req, res) => { getDatabaseModel.searchNoms(req).then(function(result) { console.l ...

Tips for ensuring an animation is triggered only after Angular has fully initialized

Within this demonstration, the use of the dashOffset property initiates the animation for the dash-offset. For instance, upon entering a new percentage in the input field, the animation is activated. The code responsible for updating the dashOffset state ...

Passing data from getServerSideProps to an external component in Next.js using typescript

In my Index.js page, I am using serverSideProps to fetch consumptions data from a mock JSON file and pass it to a component that utilizes DataGrid to display and allow users to modify the values. export const getServerSideProps: GetServerSideProps = async ...

Error Encountered: Unexpected Identifier in Angular 7 External jQuery Plugin

Struggling to convert a jQuery template to Angular7, I'm facing an issue with loading .js files from the assets folder in the original template to make it functional. Upon starting the application with: ng serve, I encounter the following error in th ...

Transfer only certain directories located within the primary directory

Imagine having a main-folder, which contains folders of type my-folder-x. Within these my-folder-x folders, there are subfolders and files. -main-folder -my-folder-a -build-folder -demo-folder dummy.js dummy.css my.json -dummy-folder - ...

When trying to bind an object that is constantly changing, one-way binding may not effectively capture those dynamic modifications

For a detailed review of the code, please check out the plnkr. I am quite new to AngularJS components. I have created two simple AngularJS components with the exact same bindings: bindings: { value:'@', field:'@', object: '<&a ...

Can Authorization be Combined with Filtering in a Node.js RESTful API?

In my current setup, I have a web application communicating with a RESTful API to interact with the database. The frontend of the web app uses Angular HTTP to post/get/put data to the backend, which then manages authentication, interacts with the API, and ...