The Javascript, SetInterval, and SetTimeOut functions cause jump-like scrolling.

I am using a Squarespace site with a specific template that uses the index page and sub pages as the contents of the index page. (Pages scroll one by one). I assume that the bindings are used by Squarespace to go to the corresponding page from the index page.

I added javascript to show the current time and update it every second (moment.js and moment-timezone). I update the time every second with SetInterval (function_name, 1000);

Time is updated correctly every second. However, this brings up a specific page, on which I am updating the time to keep focusing while trying to scroll up or down (this happens every second). So if I try to scroll up or down from that particular page where the time is being updated, it will automatically scroll to that page every second!

It seems that every second an event occurs that causes this. The actual function that I call every second is as follows:

function showLocalTime() { var momentLondon = moment().tz("Europe/London").format('HH:mm:ss z'); // The location label HTML var locationHTML = '<strong>Location</strong><br>'; // The HTML string for london, England var londonHTML = 'London, England'; $( "p:contains('London, England')" ).html(locationHTML + londonHTML + ' (' + momentLondon + ')'); } 

Therefore, all I do is change the innerHTML of a specific HTML element to show the current time.

I call the above function as follows:

 <script> $(function() { document.addEventListener("DOMSubtreeModified", function(){ return;}); window.setInterval(showLocalTime, 1000); // update it periodically }); </script> 

However, as I said, calling the above function again through SetInterval forces the web page to automatically track this section of the web site (the "Contact Us" page) every second !!.

I see that the DOMSubtreeModified event is triggered, which is fired every time I call the function above. I added a custom listener to the DOMSubtreeModified event, but still, I still get the same problem.

Maybe this is due to some kind of redrawing event? Anyway, I cannot find the problem, and I cannot solve this problem.

Any help would be appreciated!

thanks

+7
javascript jquery settimeout setinterval squarespace
source share
2 answers

Problem

You remove and add two DOM nodes ( <strong> and <br> ) every second using $.html() . And this action triggers the mentioned DOMSubtreeModified event, check the test below:

 go.onclick = function() { document.addEventListener('DOMSubtreeModified', function() { alert('Modified'); }); test.innerHTML = '<strong>Location</strong><br>'; }; 
 <button id=go>Test</button> <p id=test></p> 

Decision

Instead of installing html and concatenating strings with:

 .html(locationHTML + londonHTML + ' (' + momentLondon + ')'); 

You need to create an example DOM node ( <span> ) to change only the necessary things using the textContent attribute:

 go.onclick = function() { wrapper.removeChild(go); document.addEventListener('DOMSubtreeModified', function() { alert('Modified'); }); setInterval(function() { test.textContent = new Date; }, 1000); }; 
 <p id=wrapper> <button id=go>Test</button> <span id=test></span> </p> 

In your case, this will be the value of momentLondon . (Final example at the end)

Performance

Since your function will run every second, you should keep the maximum execution time as you can.

1 . You can declare constant variables outside the scope of a function, for example:

 var locationHTML = '<strong>Location</strong><br>'; var londonHTML = 'London, England'; function showLocalTime() { // locationHTML ... // londonHTML ... // ... } 

2 . Also, if the function will always give the same expected result:

  $("p:contains('London, England')") 

You can run it only once outside the scope and save the result in a variable:

 var $p = $("p:contains('London, England')"); function showLocalTime() { // $p ... // ... } 

Final result

With this in mind, your code will look like this:

 <script> $(function() { // constants var locationHTML = '<strong>Location</strong><br>'; var londonHTML = 'London, England'; var $p = $("p:contains('London, England')"); // prepare your DOM outside showLocalTime $p.html(locationHTML + londonHTML + ' (<span></span>)'); var span = $p.find('span')[0]; // do only necessary things within setInterval setInterval(function showLocalTime() { span.textContent = moment().tz('Europe/London').format('HH:mm:ss z'); }, 1000); }); </script> 

Hope this helps.

+9
source share

I would move the showLocalTime function to a immediately called anonymous function and call it before calling setTimeOut in such a way that it displays the time at startup, and also after 1 second.

I made this script of my code to see if I can reproduce your problem with automatic scrolling, this code does not call this in JSFiddle.

Here is the JSFiddle: https://jsfiddle.net/workingClassHacker/xhrfoznj/10/

Here is the code:

 $(function() { var londonP = $("p:contains('London, England')"); var showLocalTime = function() { timeDisplay.textContent = moment().tz("Europe/London").format('HH:mm:ss z'); } londonP.html('<strong>Location</strong><br/>London, England (<span></span>)'); var timeDisplay = londonP.find('span')[0]; showLocalTime(); setInterval(showLocalTime, 1000); }); 
0
source share

All Articles