javascripthtmlgetboundingclientrect

Why is getBoundingClientRect() returning all values as zero?


I am making a popup function which creates a popup on the user's screen. Here is the code:

function popup(o){
    if(typeof o==="undefined")o={"width":"75%","height":"75%","html":""};
    if(!o.width)o.width="75%";
    if(!o.height)o.height="75%";
    if(!o.html)o.html="";
    var p=document.createElement("span");
    var c=document.createElement("span");
    c.setAttribute("style","z-index:1;position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.5)");
    p.setAttribute("style","width:"+o.width+";height:"+o.height+";background-color:#444444;position:absolute;z-index:2;border-radius:25px;padding:20px;border:10px solid white;color:white;font-size:60px");
    p.innerHTML=o.html;
    document.body.appendChild(c);
    document.body.appendChild(p);
}

popup({"html":"<i>Test popup</i>", "width": "50%", "height": "50%"});
<!DOCTYPE html>
<html>
    <head>
        <title>Popup test</title>
        <meta charset="UTF-8"/>
    </head>
    <body>
        <h1>Popup Testing Page</h1>
        <span>other text</span>
    </body>
</html>

The getBoundingClientRect() is returning an object with all properties as an integer with the value 0.

function popup(o){
    if(typeof o==="undefined")o={"width":"75%","height":"75%","html":""};
    if(!o.width)o.width="75%";
    if(!o.height)o.height="75%";
    if(!o.html)o.html="";
    var p=document.createElement("span");
    var c=document.createElement("span");
    c.setAttribute("style","z-index:1;position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.5)");
    p.setAttribute("style","width:"+o.width+";height:"+o.height+";background-color:#444444;position:absolute;z-index:2;border-radius:25px;padding:20px;border:10px solid white;color:white;font-size:60px");
  
  var bcr=p.getBoundingClientRect();
  alert(bcr.width);
  alert(bcr.height);
  alert(bcr.top);
  alert(bcr.bottom);
  alert(bcr.x);
  alert(bcr.y);
  alert(bcr.left);
  alert(bcr.right);
  
    p.innerHTML=o.html;
    document.body.appendChild(c);
    document.body.appendChild(p);
}

popup({"html":"<i>Test popup</i>", "width": "50%", "height": "50%"});
<!DOCTYPE html>
<html>
    <head>
        <title>Popup test</title>
        <meta charset="UTF-8"/>
    </head>
    <body>
        <h1>Popup Testing Page</h1>
        <span>other text</span>
    </body>
</html>

Run the stack snippet and you will get alerted all of the values of the getBoundingClientRect() (which are all 0). Can anyone explain why?


Solution

  • Short anwswer: You should call getBoundingClientRect after you've added the element to the document, as demonstrated below

    function popup(o){
        if(typeof o==="undefined")o={"width":"75%","height":"75%","html":""};
        if(!o.width)o.width="75%";
        if(!o.height)o.height="75%";
        if(!o.html)o.html="";
        var p=document.createElement("span");
        var c=document.createElement("span");
        c.setAttribute("style","z-index:1;position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.5)");
        p.setAttribute("style","width:"+o.width+";height:"+o.height+";background-color:#444444;position:absolute;z-index:2;border-radius:25px;padding:20px;border:10px solid white;color:white;font-size:60px");
              p.innerHTML=o.html;
        document.body.appendChild(c);
        document.body.appendChild(p);
    
      var bcr=p.getBoundingClientRect();
      alert(JSON.stringify(bcr, null, 3));
      
    
    }
    
    popup({"html":"<i>Test popup</i>", "width": "50%", "height": "50%"});
    <!DOCTYPE html>
    <html>
        <head>
            <title>Popup test</title>
            <meta charset="UTF-8"/>
        </head>
        <body>
            <h1>Popup Testing Page</h1>
            <span>other text</span>
        </body>
    </html>