document.hidden is incorrectly false when used in a WebBrowser control

986 Views Asked by At

I want to detect when a window is minimized in JavaScript, so I am using document.hidden. In the below snippet, click "Start" and minimize the window by clicking the minimize button, toggling the application icon in the taskbar, using Win + Down Arrow, using Win + D, etc.

When the window is minimized, you will see "hidden" appear in the textarea.

var startButton = document.getElementById("start");
var stopButton = document.getElementById("stop");
var ta = document.getElementById("ta");

var id;
startButton.onclick = function() {
 id = setInterval(function() {
  ta.value += document.hidden ? "hidden\n" : "visible\n";
 }, 1000);
};

stopButton.onclick = function() {
 if (id) clearInterval(id);
};
<button id="start">Start</button>
<button id="stop">Stop</button>
<br />
<textarea id="ta" cols="50" rows="20"></textarea>

No issues there.

However, I am hosting this JS code in VB6.

I have created a simple project with a form with a WebBrowser control and a CommandButton. My only code is this:

Private Sub Command1_Click()
    WebBrowser1.Navigate "http://localhost:1234/mypage.html"
End Sub

Clicking the command button takes me to the same page:

enter image description here

In VB6, "hidden" is displayed for these three cases:

  • clicking the minimize button
  • Win + Down Arrow
  • Win + D

But not, in this case:

  • toggling the application icon in the taskbar

I've also noticed that "hidden" is only displayed the first time the window is minimized. If you minimize it again, it will display "visible".

I'm guessing this is a bug with how WebBrowser controls integrate with JS? Does anyone have any workarounds for this?


I may soon repurpose this question into a broader one, since this has less to do with document.hidden being wrong and more to do with WebBrowser not integrating nicely with JS's Page Visibility.

A more general problem that I have discovered is that the visibilitychange handler does not fire when run in a page hosted by a WebBrowser control in VB6, but works totally fine in the browser:

var ta = document.getElementById("ta");
document.addEventListener("visibilitychange", function ()
{
 ta.value += document.visibilityState + "\n";
});
<textarea id="ta" cols="50" rows="20"></textarea>

1

There are 1 best solutions below

0
On BEST ANSWER

I worked around it by listening to the Resize event, and whenever the WindowState changed, I'd set a property in my JS code indicating the state:

Private Sub Form_Resize()
    Static lWindowState As Long
    Dim lNewWindowState As Long
    Dim lOldWindowState As Long

    lNewWindowState = m_DesktopForm.WindowState
    lOldWindowState = lWindowState

    If lWindowState <> lNewWindowState Then  
        lWindowState = lNewWindowState

        Dim bHidden As Boolean
        bHidden = (lWindowState = vbMinimized)          
        Call CallByName(MyJSObj, "windowIsHidden", VbLet, bHidden)
    End If
End Sub

My JS has an object (that VB can reference) like this:

MyJSObj = {
    windowIsHidden: false
}

Then I added a method to wrap document.hidden:

function isDocumentHidden() {
    // if document.hidden is true, trust that. If it's not true, then fall back on what VB says
    return document.hidden || MyJSObj.windowIsHidden;
}

I use that method in my code instead of document.hidden.