The problem: Older knowledgebase software that, for whatever reason, has links that are broken. It is a series of nested frames. Some point to the correct target, some do not, and many are just broken. It makes using the knowledgebase cumbersome when it doesn't work smoothly
What I'm trying to acomplish: I want to determine when the specific frame has loaded and then parse the frame's document replacing the anchor tags with correct hrefs and targets.
Resources and limitations: I have access to some of the .aspx pages. The one I'm targeting now contains a framset which loads the knowledgebase document. The src of this frame however does not appear to be an actual .aspx page (physical file) - unsure how it is generated and unsure how the documents are stored. I see the src listed but can't find it on the webserver to which I have access.
Basic info: Pages are loaded using .aspx (I don't understand parts of this well and don't have access to anything much deeper). The .aspx page has a frameset that gets built when the page is loaded.
Sample Framset code from the .aspx file:
<FRAMESET id="FrameSetMainView" runat="server" border="0" framespacing="0" frameborder="0">
<!-- This frame set is defined and generated in the code -->
</FRAMESET>
I've tried adding onload in the FRAMESET
tag (this causes the page to error when trying to load). The frameset takes over the body so I can't add inline script to the bottom of the page to make it run after loading either.
Additionally, b/c of the age of the product - it is forced into compatibility mode. So IE7 equivalent support has to be used. (no addeventlistener
option)
Current Strategy: What I think I can get working, but feels gimicky as all be - adding script into the <head>
. Something along the lines of:
<SCRIPT>
function load(){
var frameset = window.frames;
if(frameset.length > 0){ // frames have loaded - commence replacement
}else{ // frames not loaded
setTimeout(load,1000); // wait 1 sec, try again
}
}
load();
</SCRIPT>
Other solutions?
Yes, there is reliable way to solve this problem without resorting to timers or other ticks. When the page loads assign a handler to each frame "onreadystatechange" event. And you must also call it once to ensure that it is applied to frames which have already loaded. The code below was tested in IE compatibility modes 5,7,8,9,10 and worked as expected (fails in IE11). It was also tested with slow loading frames without problem.
References:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<title>Demo</title>
<script type="text/javascript">
window.onload = function() {
for (var i = 0; i < window.frames.length; i++) {
(function(frame) {
// called whenever a frame is loaded or reloaded
frame.onreadystatechange = function() {
if (frame.readyState === 'complete') {
updateLinks(frame);
}
}
// call once to apply to already loaded frames
frame.onreadystatechange();
})(window.frames[i].frameElement);
}
}
// modify the links within the frame
function updateLinks(frame) {
var i, links, doc;
doc = frame.contentDocument || frame.contentWindow.document;
links = doc.getElementsByTagName('A');
for (i = 0; i < links.length; i++) {
// modify the links here
links[i].href += '?time=' + (new Date()).getTime();
}
console.info('modified ' + links.length + ' links in frame ' + frame.src);
}
</script>
</head>
<frameset cols="*,*">
<frame src="frameLeft.html">
<frame src="frameRight.html">
</frameset>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With