Reputation: 73938
I need to programmatically set focus for a "parent" frame from an iframe .
Please try out the following example.
01 show panel
, and a div with an iframe will show up02 click me
, the div with an iframe will be hiddenOn step 02 I need to set the focus from the iframe to the "parent" frame.
I am doing this using window.focus()
which works well on Chrome.
My problem is on Firefox, the script keeps the focus on the iframe (see the result in div resultFocus
) and does not focus on "parent"frame
I need a work around for FireFox, any idea how to fix it?
test.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<style>
#panel {
position: absolute;
top: 50px;
left: 250px;
width: 250px;
height: 150px;
}
#resultFocus {
position:absolute;
left: 650px;
}
.btn {
width: 150px;
height: 30px;
margin: 5px;
background-color: lightblue;
}
</style>
<script>
(function (window) {
var _hidePanel = function () {
var panel = document.getElementById('panel');
panel.style.display = 'none';
};
var _showPanel = function () {
var panel = document.getElementById('panel');
panel.style.display = '';
};
var _addListeners = function () {
var btnHide = document.getElementById('btnHide');
btnHide.addEventListener('click', function (event) {
_hidePanel();
_setFocusMainWindow();
_showActiveFocus();
});
var btnShow = document.getElementById('btnShow');
btnShow.addEventListener('click', function (event) {
_showPanel();
});
var btnInner = document.getElementById('iframe').contentWindow.document.getElementById('btnInner');
btnInner.addEventListener('click', function (event) {
_hidePanel();
_setFocusMainWindow();
_showActiveFocus();
});
var btnShowActiveFocus = document.getElementById('btnShowActiveFocus');
btnShowActiveFocus.addEventListener('click', function (event) {
_showActiveFocus();
});
};
var _showActiveFocus = function () {
var resultFocus = document.getElementById('resultFocus');
resultFocus.innerHTML = '';
resultFocus.innerHTML = document.activeElement;
};
var _setFocusMainWindow = function () {
window.focus();
};
window.start = function () {
_addListeners();
_hidePanel();
_showActiveFocus();
}
})(window);
</script>
</head>
<body onload="start();">
<div id="btnShow" type="button" class="btn">01 show panel</div>
<div id="btnHide" type="button" class="btn" style="display:none;">03 hide panel</div>
<div id="btnShowActiveFocus" type="button" class="btn" style="display:none;">show active focus</div>
<div id="panel">
<iframe id="iframe" src="include.html"></iframe>
</div>
<div id="resultFocus" rows="2" cols="20"></div>
</body>
</html>
include.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<style>
body {
background-color:orange;
}
</style>
<script>
</script>
</head>
<body>
<h1>I am an iframe!</h1>
<button id="btnInner" type="button">02 - click me</button>
</body>
</html>
Possibly related: How to get window.focus() to work in firefox
Upvotes: 4
Views: 2591
Reputation: 2344
You can solve this issue by adding an invisible fake focus target and focusing in and out of that target programmatically before focusing on the window itself. Here is how to do it:
Add the fake focus element in the DOM right at the beginning of start()
:
window.start = function () {
var input = document.createElement('INPUT');
input.id = 'fakefocus';
input.type = 'checkbox';
input.style.position = 'absolute';
input.style.left = '-999em';
document.body.appendChild(input);
_addListeners();
_hidePanel();
_showActiveFocus();
};
Focus in and out of the fake focus element right before _setFocusMainWindow();
in click
event listener of the btnInner
:
btnInner.addEventListener('click', function (event) {
_hidePanel();
var ff = document.getElementById('fakefocus');
ff.focus();
ff.blur();
_setFocusMainWindow();
_showActiveFocus();
});
And actually, after doing that, you might not even need window.focus();
anymore.
Upvotes: 2