Menu

#1768 Running window.getComputedStyle() and element.getBoundingClientRect in different orders yields different results

Latest SVN
closed
1
2016-04-07
2016-04-07
No

Hi,

seems that running <element>.getBoundingClientRect() will make later queries to window.getComputedStyle() fail. Otherwise, when calling .getComputedStyle() before .getBoundingClientRect(), the state is cached and things work ok later on.

Here's a sample page demonstrating it (you'll need to change the order of the method calls in 'body' manually)

<html>
<head>
    <style type="text/css">
        div {
            padding: 15px;
        }
        #MyElement {
            background: lightblue;
        }
        #MyElement:before {
            content: "0.33";
        }
        #JSOutput {
            background: green;
        }
    </style>
</head>
<body onload="styleFirst(); rectFirst();">

<div id="MyElement">
</div>
<div id="JSOutput">
</div>
<script type="text/javascript">

    function append(text, value) {
        var p = document.createElement('p');
        p.appendChild(document.createTextNode(text + ': ' + value));
        document.getElementById('JSOutput').appendChild(p);
    }

    function styleFirst() {
        append('mode', 'First content then width');

        var elem = document.getElementById('MyElement');

        var computedStyle = window.getComputedStyle(elem, ':before');
        var property = computedStyle.getPropertyValue("content");
        append('property', property);

        var widthOfTopHatShelve = elem.getBoundingClientRect().width;
        append(
            'width',
            widthOfTopHatShelve
        );
    }

    function rectFirst() {
        append('mode', 'First width then content');

        var elem = document.getElementById('MyElement');

        var widthOfTopHatShelve = elem.getBoundingClientRect().width;
        append(
            'width',
            widthOfTopHatShelve
        );

        var computedStyle = window.getComputedStyle(elem, ':before');
        var property = computedStyle.getPropertyValue("content");
        append('property', property);
        var scaling = property.slice(1,-1);
    }

</script>
</body>
</html>

If you change

<body onload="styleFirst(); rectFirst();">

to

<body onload="rectFirst(); styleFirst();">

then .getComputedStyle() is empty.

Simply printing out the page shows the expected content isn't there.

public class Test {

    public void test() throws FailingHttpStatusCodeException, IOException
             {
        WebClient client = new WebClient(BrowserVersion.CHROME);
        client.getOptions().setCssEnabled(true);
        client.getOptions().setJavaScriptEnabled(true);
        client.getOptions().setThrowExceptionOnScriptError(true);
        WebRequest request = new WebRequest(
                new URL("file:///.....rect_style_test.html"));

        Page page = client.getPage(request);
        client.waitForBackgroundJavaScript(1000);
        System.out.println(((HtmlPage) page).asXml());

    }
}

Discussion

  • Ahmed Ashour

    Ahmed Ashour - 2016-04-07
    • status: open --> pending
    • assigned_to: Ahmed Ashour
     
  • Ahmed Ashour

    Ahmed Ashour - 2016-04-07
    • status: pending --> accepted
     
  • Ahmed Ashour

    Ahmed Ashour - 2016-04-07
    • status: accepted --> closed
     
  • Ahmed Ashour

    Ahmed Ashour - 2016-04-07

    Thanks for reporting, fixed in SVN.

     

Log in to post a comment.