Pure JavaScript function similar to jQuery.offset(

2020-03-02 05:15发布

问题:

In a small iframe-application at the Russian social network Ok.ru I use the following call to resize the iframe:

<div id="fb-root"></div> 
<script src="http://api.odnoklassniki.ru/js/fapi.js" 
type="text/javascript"></script> 
<script type="text/javascript"> 
FAPI.init("http://api.odnoklassniki.ru/", "XXX_YYY",
function() {
        alert("clientHeight " + document.getElementById("fb-root").clientHeight);
        alert("offsetHeight " + document.getElementById("fb-root").offsetHeight);
        FAPI.UI.setWindowSize(720, 1200);
}, function(error){
        alert("API initialization failed");
});
</script> 
</body> 
</html>

i.e. the iframe-height is currently hardcoded to 1200.

It works okay, but I'd like to use the height/position of #fb-root element instead.

Does anybody please have an idea, which JavaScript or CSS function could be used here - if I don't want to include jQuery just for one $(#fb-root).offset() call?

I've also looked at their library http://api.odnoklassniki.ru//js/fapi.js but it doesn't include such function.

UPDATE

I've added two alert-calls to my source code above, but they only print

clientHeight 0
offsetHeight 0

UPDATE

The following code seem to work well for my iframe-app now in Google Chrome and Mozilla Firefox, regardless of how many
s do I add for testing it. But with Internet Explorer it fails to resize the window and alert shows top=1107 instead of top=1157 in Google Chrome, thus the html table at the bottom is cut off:

... here my flash game + html table with players ...
<br>
<br>
<br>
<br>
<br>
<br>
<div id="fb-root"></div>
<script src="http://api.odnoklassniki.ru/js/fapi.js" type="text/javascript"></script>
<script type="text/javascript">
FAPI.init("http://api.odnoklassniki.ru/", "XXX_YYY",
function() {
        var top = findTop(document.getElementById("fb-root"));
        FAPI.UI.setWindowSize(720, Math.max(top, 1200));
}, function(error){
        alert("API initialization failed");
});
function findTop(obj) {
        if(!obj) return 0;
        return obj.offsetTop + findTop(obj.offsetParent);
}
</script>

</body>
</html>

回答1:

Quirksmode has a JavaScript tutorial/function that shows how to find the coordinates of an element here

Once you have its coordinates, you can use the offsetHeight property of the iframe to read its height.



回答2:

If document.getElementById("fb-root").clientHeight returns 0, it certainly means that your "fb-root" div is either not displayed or still empty.

I have had a look at fapi.js, and it seems that calling the FAPI.init function creates a span which id is "FAPI_Flash_wrap", appends it to the body of the document, then embeds a flash object with id "FAPI_Flash" in this span.

So I would try retrieving an element with id "FAPI_Flash_wrap" or "FAPI_Flash" instead of "fb-root":

<script type="text/javascript">
FAPI.init("http://api.odnoklassniki.ru/", "XXX_YYY",
function() {
    alert("Height = " + document.getElementById("FAPI_Flash_wrap").offsetHeight);
    alert("Width = " + document.getElementById("FAPI_Flash_wrap").offsetWidth);
    FAPI.UI.setWindowSize(720, 1200);
}, function(error){alert("API initialization failed");}
);
</script>
I hope this works!

If it's the case, then just use

<script type="text/javascript">
FAPI.init("http://api.odnoklassniki.ru/", "XXX_YYY",
function() {
    var height = document.getElementById("FAPI_Flash_wrap").offsetHeight;
    var width = document.getElementById("FAPI_Flash_wrap").offsetWidth;
    FAPI.UI.setWindowSize(width, height);
}, function(error){alert("API initialization failed");}
);
</script>


回答3:

Looking at the code in jquery, the offset is calculated like this:

function getOffset(element)
{
    if (!element.getClientRects().length)
    {
      return { top: 0, left: 0 };
    }

    let rect = element.getBoundingClientRect();
    let win = element.ownerDocument.defaultView;
    return (
    {
      top: rect.top + win.pageYOffset,
      left: rect.left + win.pageXOffset
    });   
}



回答4:

Use offsetHeight or clientHeight to get div's height:

document.getElementById("fb-root").offsetHeight // including border
document.getElementById("fb-root").clientHeight // excluding border 

Use offsetLeft and offsetTop to get div's position relative to its offsetParent. offsetParent is its first parent box which position style is fixed, relative or absolute.