开发者

Need to calculate offsetRight in javascript

开发者 https://www.devze.com 2023-01-03 06:08 出处:网络
I need to calculate the offsetRight of a DOM object. I already have some rather simple code for getting the offsetLeft, but there is no javascript offsetRight property. If I add the offsetLeft and off

I need to calculate the offsetRight of a DOM object. I already have some rather simple code for getting the offsetLeft, but there is no javascript offsetRight property. If I add the offsetLeft and offsetWidth, will that work? Or is there a better way?

function getOffsetLeft(obj)
{
    if(obj == null)
        return 0;
    var offsetLeft = 0;
    var开发者_运维百科 tmp = obj;
    while(tmp != null)
    {
        offsetLeft += tmp.offsetLeft;
        tmp = tmp.offsetParent;
    }
    return offsetLeft;
}

function getOffsetRight(obj)
{
    if (obj == null)
        return 0;
    var offsetRight = 0;
    var tmp = obj;
    while (tmp != null)
    {
        offsetRight += tmp.offsetLeft + tmp.offsetWidth;
        tmp = tmp.offsetParent;
    }
    return offsetRight;    
}


Cannot be more simpler than this:

let offsetright = window.innerWidth - obj.offsetLeft - obj.offsetWidth


UPDATED POST TO CLARIFY SOME GOTCHAS:

// Assuming these variables:
const elem = document.querySelector('div'),
      body = document.body,
      html = document.documentElement;

Here are several approaches:

/* Leveraging the viewport AND accounting for possible overflow to the right */
const offsetRight = body.clientWidth - elem.getBoundingClientRect().right
// OR
const offsetRight = body.scrollWidth - elem.getBoundingClientRect().right
// OR
const offsetRight = html.scrollWidth - elem.getBoundingClientRect().right

OR

/*
*  Likely the safest option:
*  Doesn't depend on the viewport
*  Accounts for overflow to the right
*  Works even if the user is scrolled to the right some
*  NOTE: This ends at the <html> element,
*  but you may want to modify the code to end at the <body>
*/
const getOffsetRight = e => {
    let left = e.offsetWidth + e.offsetLeft;
    const traverse = eRef => {
        eRef = eRef.offsetParent; // `.offsetParent` is faster than `.parentElement`
        if (eRef) {
            left += eRef.offsetLeft;
            traverse(eRef);
        }
    };
    traverse(e);
    return html.scrollWidth - left;
};
const offsetRight = getOffsetRight(elem);

Import considerations:

  • Are you using box-sizing: border-box; for all your elements?
  • Is there margin-left set on the <body> or <html> elements you need to account for?
  • Does the <body> have a fixed width but centered such as with margin: 0 auto;

Those things will help determine which method to use, and if you want to modify the CSS and/or the JavaScript to account for those use cases.

ORIGINAL POST:

A few choices:

  • If you want "offsetRight" relative to the viewport, use element.getBoundingClientRect().right;

  • Your example is good simply subracting the parent width from the element's width + offsetLeft.

  • Lastly, to be relative to the document, and to speed up traversing (offsetParent):

In this example, I'm positioning a pseudo dropdown element below the referenced element, but because I'm avoiding some tricky z-index issues and want to have the element be referenced from the right and expand out left, I had to append it to the body element, and the get the "offsetRight" from the original parent.

...

// Set helper defaults
dropdownElem.style.left = 'auto';
dropdownElem.style.zIndex = '10';

// Get the elem and its offsetParent
let elem = dropdownElemContainer;
let elemOffsetParent = elem.offsetParent;

// Cache widths
let elemWidth = elem.offsetWidth;
let elemOffsetParentWidth = 0;

// Set the initial offsets
let top = elem.offsetHeight; // Because I want to visually append the elem at the bottom of the referenced bottom
let right = 0;

// Loop up the DOM getting the offsetParent elements so you don't have to traverse the entire ancestor tree
while (elemOffsetParent) {
  top += elem.offsetTop;
  elemOffsetParentWidth = elemOffsetParent.offsetWidth;
  right += elemOffsetParentWidth - (elem.offsetLeft + elemWidth); // Most important line like your own example
  // Move up the DOM
  elem = elemOffsetParent;
  elemOffsetParent = elemOffsetParent.offsetParent;
  elemWidth = elemOffsetParentWidth;
}

// Set the position and show the elem
dropdownElem.style.top = top + 'px';
dropdownElem.style.right = right + 'px';
dropdownElem.style.display = 'block';


//Object references
function getObject(id) {
   var object = null;
   if (document.layers) {
    object = document.layers[id];
   } else if (document.all) {
    object = document.all[id];
   } else if (document.getElementById) {
    object = document.getElementById(id);
   }
   return object;
}
//Get pixel dimensions of screen
function getDimensions(){
    var winW = 630, winH = 460;
    if (document.body && document.body.offsetWidth) {
     winW = document.body.offsetWidth;
     winH = document.body.offsetHeight;
    }
    if (document.compatMode=='CSS1Compat' && document.documentElement && document.documentElement.offsetWidth ) {
     winW = document.documentElement.offsetWidth;
     winH = document.documentElement.offsetHeight;
    }
    if (window.innerWidth && window.innerHeight) {
     winW = window.innerWidth;
     winH = window.innerHeight;
    }
    return{"width":winW, "height":winH}
}
//Get the location of element
function getOffsetRight(elem){
    element=getObject(elem)
    var width = element.offsetWidth
    var right = 0;
    while (element.offsetParent) { 
        right += element.offsetLeft; 
        element = element.offsetParent;
    }
    right += element.offsetLeft;
    right = getDimensions()["width"]-right
    right -= width
    return right
}

This is not bullet-proof but you can usually get the "offsetRight" by calling: getOffsetRight("[object.id]")


If you are interested in using some Js library then try the following functionality of prototype js http://api.prototypejs.org/dom/element/offset/

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号