JS supported in chrome, but only working in FF.

Associate
Joined
11 Oct 2008
Posts
268
Hey guys. I am not very experienced with JS, so please bear with me.
I read about the battery api, and according to caniuse.com it should be supported by firefox and chrome. However my code does not work in chrome.

this is the code I came up with:

Code:
 <script>
        var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery || navigator.msBattery;
        if (battery) {
            // Battery API supported
            var displayBattery = Math.floor(battery.level * 100);

        }
        console.log("Battery level: ", Math.floor(battery.level * 100) + "%");
        console.log("Device is ", (battery.charging ? "charging" : "discharging"));
        console.log(Math.floor(battery.level * 100));

        document.addEventListener('DOMContentLoaded', function() {
            var infoStatus = document.getElementsByClassName('infoStatus')[0];
            var batt = document.getElementsByClassName('batteryInner')[0];
            batt.style.width = displayBattery + "%";
            if (battery.charging) {
                document.getElementById('status').innerHTML = "Charging";
                infoStatus.style.color = "#006400";
            } else {
                document.getElementById('status').innerHTML = "Discharging";
                infoStatus.style.color = "#FF0000";
            }
        })
    </script>

Can anyone see what I have done wrong. Constructive criticism is welcomed as I would love to improve my JS skills.

Here is the full code with css in case anyone wants to see the whole thing working.

Thanks for any tips

Code:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Battery API Test</title>

    <script>
        var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery || navigator.msBattery;
        if (battery) {
            // Battery API supported
            var displayBattery = Math.floor(battery.level * 100);

        }
        console.log("Battery level: ", Math.floor(battery.level * 100) + "%");
        console.log("Device is ", (battery.charging ? "charging" : "discharging"));
        console.log(Math.floor(battery.level * 100));

        document.addEventListener('DOMContentLoaded', function() {
            var infoStatus = document.getElementsByClassName('infoStatus')[0];
            var batt = document.getElementsByClassName('batteryInner')[0];
            batt.style.width = displayBattery + "%";
            if (battery.charging) {
                document.getElementById('status').innerHTML = "Charging";
                infoStatus.style.color = "#006400";
            } else {
                document.getElementById('status').innerHTML = "Discharging";
                infoStatus.style.color = "#FF0000";
            }
        })
    </script>

    <style>
        body {
            font-family: Arial, Helvetica, sans-serif;
            letter-spacing: 6px;
            font-size: 0.8rem;
        }
        
        p {
            display: inline;
        }
        
        .batteryWrapper {
            position: fixed;
            top: 36px;
            left: 20px;
            width: 100px;
            height: 10px;
            background: #696969;
            border-radius: 6px;
            overflow: hidden;
        }
        
        .batteryInner {
            position: relative;
            height: 100%;
            width: 0%;
            background: #98FB98;
        }
        
        .infoTop {
            position: absolute;
            top: 10px;
            left: 20px;
        }
        
        .infoBottom {
            position: absolute;
            top: 60px;
            left: 20px;
        }
        
        .infoStatus {
            color: #000000;
        }
    </style>

</head>

<body>

    <div class="infoTop">
        Battery level:
    </div>

    <div class="batteryWrapper">
        <div class="batteryInner">
        </div>
    </div>

    <div class="infoBottom">
        Battery status:
        <span class="infoStatus"><p id="status"></p></span>
    </div>

</body>

</html>
 
There's been a recent overhaul to the Battery API so that it now runs asynchronously and uses promises to return information, so you'll need to re-structure your logic to work on the callback of the 'navigator.getBattery()` method. Also your 'displayBattery' variable is out of scope of the DOMContentLoaded handler, and you use 'battery' outside of the availability check. Here's a re-jigged version which should happily work cross-browser:

Code:
document.addEventListener('DOMContentLoaded', function() {
    if (typeof navigator.getBattery === "function") { 
        navigator.getBattery().then(function(battery) {
            var displayBattery = Math.floor(battery.level * 100);
            var infoStatus = document.getElementsByClassName('infoStatus')[0];
            var batt = document.getElementsByClassName('batteryInner')[0];
            batt.style.width = displayBattery + "%";            

            if (battery.charging) {
                document.getElementById('status').innerHTML = "Charging";
                infoStatus.style.color = "#006400";
            } else {
                document.getElementById('status').innerHTML = "Discharging";
                infoStatus.style.color = "#FF0000";
            }
        })
    }
})

Working example: https://jsfiddle.net/RoryMcCrossan/ktfo18o5/. I checked this works in Chrome on both my desktop and phone. I don't have FF to hand, but I don't see why it wouldn't work there too.

You can move the logic which gets the battery state out of the DOM ready handler if you prefer, I just put it all in there to keep it simple.

Also, here's an up to date reference for the Battery API: https://developer.mozilla.org/en/docs/Web/API/Battery_Status_API
 
Last edited:
Back
Top Bottom