Reputation: 75
We are using frames in our application. In one frame the scrolling is set to "auto"
. I'm trying to change that frame attribute based on a small condition. Here is the HTML and JavaScript:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=5">
</head>
<frameset>
<frame src="#" name="contentFR" id="contentFR" scrolling="Auto" noresize marginwidth="0" marginheight="0">
</frameset>
<script language="javascript">
var iFrm = document.getElementById("contentFR");
iFrm.setAttribute('scrolling', 'no');
</script>
</html>
I'm using IE 11, But my application can only run in IE 5 compatibility mode.
Upvotes: 3
Views: 1402
Reputation: 268414
Updated Approach: Simply clone the node.
// Proceed when the document has loaded
var timer = setInterval(function () {
// The document has loaded
if ( document.readyState === "complete" ) {
// Stop checking document load-state
clearInterval( timer );
// Get our frame, and create a clone of it
var frame = document.getElementById("contentFR");
var clone = frame.cloneNode(true);
// Update the scrolling on the clone
clone.setAttribute("scrolling", "no");
// Replace original frame with clone frame
frame.parentElement.replaceChild(clone, frame);
}
}, 10);
See below for deeper explanation of why this route was chosen.
I am baffled that changing the property, and/or the attribute, doesn't work. Granted, I can only check from Internet Explorer 11 on Windows 10 so I don't know that the same issue would repro in earlier builds of Internet Explorer. Since you said your users will be in Internet Explorer 11, we can safely assume that if we run into the issue, so too will they.
I also found that placing the <script>
below the frameset wouldn't work either, so I had to place it in the <head>
(Scripts can only be placed within a <body>
or a <head>
, and since there is no <body>
in this document, we can only place them in the <head>
). Because the head is parsed/created first, our frame element won't exist in time to change it from the head. Additionally, since we're working with the IE 5 Document Mode, we can't merely listen on the document
for the DOMContentLoaded event. Instead, I chose to check the document.readyState
value every 10ms until it registered as complete.
Lastly, as you have found, simply updating the attribute doesn't appear to work. Setting the property also doesn't appear to work. Oddly enough, both of these actually change the value from Auto to No if you inspect the element after performing the operation, but the change isn't reflected in the document. For this reason, I decided to create a brand new frame, replacing the other.
This code feels really, really misguided. Hopefully somebody will come along and share an approach that doesn't require going through such extremes as fundamentally duplicating an element, and applying the attributes of one to the other. Until then, this solution appears to work.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=5">
<script type="text/javascript">
// Proceed when the document has loaded
var timer = setInterval(function () {
if ( document.readyState === "complete" ) {
// Stop checking document load-state
clearInterval( timer );
// Get our frame, and create a replacement
var frame = document.getElementById("contentFR");
var newFrame = document.createElement( "frame" );
// Copy all attributes over
var i = 0, attr;
for ( ; i < frame.attributes.length; i++ ) {
attr = frame.attributes[i];
// If we found a scrolling attribute, set it to 'no'
if ( attr.name === "scrolling" ) attr.value = "no";
// Apply old attribute to new frame
newFrame.setAttribute( attr.name, attr.value );
}
// Replace old frame with new frame
frame.parentElement.replaceChild( newFrame, frame );
// Null-out our variables
frame = i = attr = timer = null;
}
}, 10);
</script>
</head>
<frameset cols="50%, *">
<frame src="side.html">
<frame src="page.html" id="contentFR" scrolling="Auto" noresize marginWidth="0" marginHeight="0">
</frameset>
</html>
Upvotes: 3