Fixed Position in any browser

Gabarieko 0 Tallied Votes 363 Views Share

This is a javascript code to fix any element in any browser.
Simply add "fixed" to the classes of the desired element.

Examples:

<div class="fixed">FIXED</div>
<div class="someClass fixed">FIXED</div>

Though it's a little rough when scrolling I hope it will do the job.

The way it works:
- By using an event listener ("onscroll") the script calls the function which aligns the elements absolutely but relative to the window borders

Some of the functions are copied from the Internet simply to avoid the annoying writing.

// Function to get the amount of pixels scrolled
//    Copied from the Internet
function getScrollXY() {
   var scrOfX = 0, scrOfY = 0;
   if( typeof( window.pageYOffset ) == 'number' ) {
     //Netscape compliant
     scrOfY = window.pageYOffset;
     scrOfX = window.pageXOffset;
   } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
     //DOM compliant
     scrOfY = document.body.scrollTop;
     scrOfX = document.body.scrollLeft;
   } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
     //IE6 standards compliant mode
     scrOfY = document.documentElement.scrollTop;
     scrOfX = document.documentElement.scrollLeft;
   }
   return [ scrOfX, scrOfY ];
}

// Function to get the Elements with class "fixed"
//    It is the same as most function "getElementsByClass" found on the net
//    The only difference is that it does not accept parameters,
//    they are hard-coded instead

function getFixedElements(){
   var classElements = new Array();
   var node = document;
   var els = node.getElementsByTagName('*');
   var pattern = new RegExp("(^|\\s)"+"fixed"+"(\\s|$)");
   for (i = 0, j = 0; i < els.length; i++) {
     if (pattern.test(els[i].className) ) {
       classElements[j] = els[i];
       j++;
     }
   }
   return classElements;
}

// The function which scrolls the elements
// to their initial position (relative to the window borders)
// after the page has been scrolled

function maintainFixing(){
   var Elements = getFixedElements();
   var Scrolling= getScrollXY();

   for(ei=0;ei<Elements.length;ei++){
      // Fix the Elements to the y axis
      Elements[ei].style.top = Elements[ei].initialPositionTop + Scrolling[1];
      // Use if you want to fix the elements to the x axis as well
      //Elements[ei].style.left= Elements[ei].initialPositionLeft+ Scrolling[0];
   }
}

// The function to get the absolute position of an element
// Styling the elements with position:... wont interfere

function getElementPosition(obj){
	var curleft = curtop = 0;

   if (obj.offsetParent) {
      do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
      }while(obj = obj.offsetParent);
   }
   return [curleft,curtop];
}

// Get the elements and store their initial position

var Elements = getFixedElements();
for(ei=0;ei<Elements.length;ei++){
   var initPos = getElementPosition(Elements[ei]);
   Elements[ei].initialPositionTop = initPos[1];
   Elements[ei].initialPositionLeft= initPos[0];
}


// Add the event handler to the 'onscroll' event
//    This can be avoided by adding onscroll="maintainFixing()"
//    to the body tag in your HTML

if(typeof window.attachEvent != 'undefined')
   window.attachEvent("onscroll", maintainFixing);
else if(typeof document.addEventListener != 'undefined')
   document.addEventListener('scroll', maintainFixing, false);
else
   window.onscroll = maintainFixing();

Dani AI

Generated

Nice vintage trick from — that kind of JavaScript shim was a common workaround back when reliable viewport-fixed positioning was inconsistent. For modern pages it's far simpler and faster to use native CSS position: fixed (or position: sticky when you want an element to become fixed only after scrolling). (mdn2.netlify.app)

Practical CSS examples (use these instead of per-scroll JS when possible):

/* always fixed to the viewport */
.fixed-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9999;
}

/* stays in flow until it reaches viewport top, then becomes fixed */
.header-sticky {
  position: sticky;
  top: 0;
}

position: sticky is a different, often better fit for in-flow headers/sidebars. (devdoc.net)

If you must update element coordinates in JavaScript (for legacy support or special effects), avoid doing heavy layout writes on every scroll event. Throttle work with requestAnimationFrame and add touch/wheel listeners as passive so the browser can optimise scrolling. A common pattern is to capture scrollY, schedule a single rAF callback, then update using transforms (not top/left) for smoother compositing. (mdn2.netlify.app)

Troubleshooting notes:

  • A fixed element can behave like it’s positioned relative to an ancestor when that ancestor has transform, perspective, filter, contain, or certain will-change values — move fixed elements out of transformed containers if you want them pinned to the viewport. (developer.mozilla.org)
  • Use will-change or GPU-friendly transforms sparingly to improve animation smoothness; overuse can hurt memory and performance. (developer.mozilla.org)

Summary: prefer CSS-first (fixed/sticky), and if JS is necessary use rAF + passive listeners + transform-based updates to avoid the “rough” scrolling you noted.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.