faqts : Computers : Programming : Languages : JavaScript : DHTML

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

177 of 211 people (84%) answered Yes
Recently 8 of 10 people (80%) answered Yes

Entry

How to have a floating link (that is repositioned when scrolling)?

Jan 30th, 2001 06:21
Martin Honnen,


Use css absolute positioning to get a positionable page element, then 
use setInterval for NN4+ and Opera 5 and onscroll for IE 
to reposition the element to float at a fixed position in the viewport. 
The following positions a link in the top right corner of the window:
<HTML>
<HEAD>
<TITLE>
fix element in viewport
</TITLE>
<STYLE>
#fixed {
  position: absolute;
  visibility: hidden;
  z-index: 10;
}
</STYLE>
<SCRIPT>
var delay = 25;
var Opera = window.opera ? true : false;
var fixedElement, elWidth, elHeight, tid;
function initFixing (id) {
  if (document.layers) {
    fixedElement = document[id];
    elWidth = fixedElement.document.width;
    elHeight = fixedElement.document.height;
  }
  else if (document.getElementById && !Opera) {
    fixedElement = document.getElementById(id);
    elWidth = fixedElement.offsetWidth;
    elHeight = fixedElement.offsetHeight;
  }
  else if (document.all && !Opera) {
    fixedElement = document.all[id];
    elWidth = fixedElement.offsetWidth;
    elHeight = fixedElement.offsetHeight;
  }
  else if (Opera) {
    fixedElement = document.getElementById(id);
    elWidth = fixedElement.style.pixelWidth;
    elHeight = fixedElement.style.pixelHeight;
  }
  fixPosition();
  if (document.layers)
    fixedElement.visibility = 'show';
  else
    fixedElement.style.visibility = 'visible';
  if (document.all && !Opera)
    window.onscroll = fixPosition;
  else
    tid = setInterval('fixPosition()', delay);
}
function fixPosition () {
  if (document.layers) {
    fixedElement.left = 
      window.pageXOffset + window.innerWidth - elWidth - 15;
    fixedElement.top =
      window.pageYOffset;
  }
  else if (document.all && !Opera) {
    fixedElement.style.pixelLeft =
      document.body.scrollLeft + document.body.clientWidth - elWidth;
    fixedElement.style.pixelTop =
      document.body.scrollTop;
  }
  else if (document.getElementById && !Opera) {
    if (elWidth == 0)  // workaround for bug of NN6 to compute width
      elWidth = fixedElement.offsetWidth;
    fixedElement.style.left =
      (window.pageXOffset + window.innerWidth - elWidth - 30) + 'px';
    fixedElement.style.top =
      (window.pageYOffset) + 'px';
  }
  else if (Opera) {
    fixedElement.style.pixelLeft =
      window.pageXOffset + window.innerWidth - elWidth;
    fixedElement.style.pixelTop =
      window.pageYOffset;
  }
}
</SCRIPT>
</HEAD>
<BODY>
<SPAN ID="fixed">
<A HREF="javascript: void 0"
   ONCLICK="window.scrollTo(0, 0); return false"
   ONMOUSEOVER="window.status = 'top'; return true;"
   ONMOUSEOUT="window.status = ''; return true;"
>
top
</A>
</SPAN>
<SCRIPT>
initFixing('fixed');
</SCRIPT>
What follows here is just example page content to fill the page so that 
scrollbars appear.
<SCRIPT>
for (var i = 0; i < 100; i++)
  document.write(i + ' Kibology<BR>');
</SCRIPT>
<IMG SRC="kiboInside.gif" WIDTH="1000">
</BODY>
</HTML>
Here is more generalized code that allows to specify the corner to 
which you want to fix the element or link to. It works with NN4, Opera 
5 and IE4+ for all four corners of the window, and due to bugs in 
NN6/Mozilla only for the top left and the bottom left corner while 
positioning to the right corners is not working as intended.
<HTML>
<HEAD>
<TITLE>
fixed positioning
</TITLE>
<STYLE>
.fixedLink {
  background-color: blue;
  color: white;
}
</STYLE>
<STYLE>
.toBeFixed {
  position: absolute;
  visibility: hidden;
  z-index: 10;
}
</STYLE>
<SCRIPT>
FixElement.interval = 25;
var Opera = window.opera ? true : false;
function FixElement (id, vertical, horizontal) {
  this.elementId = id;
  this.vertical = vertical ? vertical : 'top';
  this.horizontal = horizontal ? horizontal : 'left';
  this.id = FixElement.elements.length;
  FixElement.elements[this.id] = this;
  this.init();
}
function FixElement_init () {
  if (document.layers) {
    this.element = document[this.elementId];
    this.width = this.element.document.width;
    this.height = this.element.document.height;
  }
  else if (Opera) {
    this.element = document.getElementById(this.elementId);
    this.width = this.element.style.pixelWidth;
    this.height = this.element.style.pixelHeight;
  }
  else if (document.all) {
    this.element = document.all[this.elementId];
    this.width = this.element.offsetWidth;
    this.height = this.element.offsetHeight;
  }
  else if (document.getElementById) {
    this.element = document.getElementById(this.elementId);
    this.width = this.element.offsetWidth;
    this.height = this.element.offsetHeight;
  }
  this.fixPosition();
  this.makeVisible();
  /* want here
     if (!Opera && document.all)
       window.onscroll = fixElements;
     else if (this.id == 0)
       FixElement.tid = setInterval('fixElements()', 
FixElement.interval);
     but due to a initial positioning problem with IE we don't use 
onscroll
  */
  if (this.id == 0)
    FixElement.tid = setInterval('fixElements()', FixElement.interval)
}
FixElement.prototype.init = FixElement_init;
function FixElement_fixPosition () {
  if (document.layers) {
    if (this.horizontal == 'left')
      this.element.left = window.pageXOffset;
    else
      this.element.left = 
        window.pageXOffset + window.innerWidth - this.width - 15;
    if (this.vertical == 'top')
      this.element.top = window.pageYOffset;
    else
      this.element.top =
        window.pageYOffset + window.innerHeight - this.height - 15
  }
  else if (Opera) {
    if (this.horizontal == 'left')
      this.element.style.pixelLeft = window.pageXOffset;
    else 
      this.element.style.pixelLeft = 
        window.pageXOffset + window.innerWidth - this.width;
    if (this.vertical == 'top')
      this.element.style.pixelTop = window.pageYOffset;
    else
      this.element.style.pixelTop =
        window.pageYOffset + window.innerHeight - this.height;
  }
  else if (document.all) {
    if (this.horizontal == 'left')
      this.element.style.pixelLeft = document.body.scrollLeft;
    else 
      this.element.style.pixelLeft = 
        document.body.scrollLeft + document.body.clientWidth - 
this.width;
    if (this.vertical == 'top')
      this.element.style.pixelTop = document.body.scrollTop;
    else
      this.element.style.pixelTop =
        document.body.scrollTop + document.body.clientHeight - 
this.height;
  }
  else if (document.getElementById) {
    if (this.horizontal == 'left')
      this.element.style.left = window.pageXOffset + 'px';
    else
      this.element.style.left =
        (window.pageYOffset + window.innerWidth - this.width - 60) 
+ 'px';
    if (this.vertical == 'top')
      this.element.style.top = window.pageYOffset + 'px';
    else
      this.element.style.top =
        (window.pageYOffset + window.innerHeight - this.height - 40) 
+ 'px';
  }
}
FixElement.prototype.fixPosition = FixElement_fixPosition;
function FixElement_makeVisible () {
  if (document.layers)
    this.element.visibility = 'show';
  else
    this.element.style.visibility = 'visible';
}
FixElement.prototype.makeVisible = FixElement_makeVisible;
function fixElements () {
  for (var e = 0; e < FixElement.elements.length; e++)
    FixElement.elements[e].fixPosition();
}
FixElement.elements = new Array();
</SCRIPT>
</HEAD>
<BODY>
<SPAN ID="topLink" CLASS="toBeFixed">
<A HREF="javascript: void 0"
   CLASS="fixedLink"
   ONMOUSEOVER="window.status = 'scroll to top';
                return true;"
   ONMOUSEOUT="window.status = '';
               return true;"
   ONCLICK="window.scrollTo(0, 0);
            return false;"
>
top
</A>
</SPAN>
<SCRIPT>
new FixElement('topLink', 'top', 'right');
</SCRIPT>
<SPAN ID="bottomLink" CLASS="toBeFixed">
<A HREF="javascript: void 0"
   CLASS="fixedLink"
   ONMOUSEOVER="window.status = 'scroll to bottom';
                return true;"
   ONMOUSEOUT="window.status = '';
               return true;"
   ONCLICK="if (document.layers)
              var bottom = window.document.height;
            else if (Opera)
              var bottom = 1000;
            else if (document.all)
              var bottom = document.body.scrollHeight;
            else if (document.getElementById)
              var bottom = window.document.height;
            window.scrollTo(0, bottom);
            return false;"
>
bottom
</A>
</SPAN>
<SCRIPT>
new FixElement('bottomLink', 'bottom', 'right');
</SCRIPT>
Here follows content to fill the page so that scrollbars appear.
<BR>
<SCRIPT>
for (var i = 0; i < 50; i++)
  document.write(i + ' Kibology<BR>');
if (document.all && !Opera)
  var width = document.body.offsetWidth;
else
  var width = window.innerWidth;
document.write('<IMG SRC="kiboInside.gif" WIDTH="' + (width + 100) 
+ '">');
</SCRIPT>
</BODY>
</HTML>