[英]HTML frame's onload is called before the content is loaded
我正在為Java SE API參考文檔[ http://docs.oracle.com/javase/8/docs/api/ ]編寫一個簡單的Greasemonkey腳本。 它是這樣的:
// ==UserScript==
// @id Test
// @grant none
// @include http://docs.oracle.com/javase/8/docs/api/*
// @version 1
// @run-at docuitment-end
// ==UserScript==
var classNamesFrame = null;
var classNamesDoc = null;
var classNamesATags = null;
var classNames = null;
function printClassNames()
{
classNamesATags = classNamesDoc.getElementsByTagName('a');
classNames = new Array();
var i;
for (i = 0; i < classNamesATags.length; i++) {
classNames.push(classNamesATags[i].textContent);
}
console.log(classNames);
console.log(classNamesDoc.URL);
console.log('Total number of classes: ' + classNamesATags.length);
alert("printClassNames called");
}
classNamesFrame = document.getElementsByName('packageFrame') [0];
classNamesDoc = classNamesFrame.contentDocument;
classNamesFrame.onload = printClassNames;
//classNamesFrame.addEventListener("DOMContentLoaded", printClassNames, false);
函數printClassNames()
打印在列出所有類的框架中找到的所有類的名稱。 框架完成加載后,我應該這樣做。 但是在加載框架的HTML文檔之前,甚至調用了onload
。
我曾嘗試使用DOMContentLoaded
事件,但尚未調用它。
我該怎么做,以便在框架完全加載完畢后調用printClassNames
?
該腳本有多種錯誤(在下面列出),但是主要的是它捕獲了錯誤的contentDocument
。
這是因為Firefox返回框架內容的<about:blank>
,直到它被實際的頁面內容替換為止。 classNamesDoc
變量仍指向空白值。 (請注意,Chrome處理框架的方式略有不同,並會為您更新classNamesDoc
。)
因此,移動classNamesDoc = classNamesFrame.contentDocument;
到printClassNames()
內部,解決了最明顯的問題。
其他問題,“最差”:
格式錯誤的元數據塊。 // ==/UserScript==
行不正確。 這會導致腳本針對您瀏覽的每個頁面和(i)框架運行(並崩潰)!
對於每個頁面/框架,只有一個很小的子集, 腳本會無提示地崩潰 (在Firefox中,Chrome報告這些錯誤)。 使用前,需要檢查classNamesFrame
的值。
例如,在docs.oracle.com/javase/8/docs/api/
頁面上,此腳本運行4次,其中三個靜默崩潰。
缺少@name
指令。 這可能會導致范圍,更新和維護方面的問題-以及妨礙上載和共享腳本。
語法錯誤。 它應該是: @run-at document-end
,除了在這種情況下可能根本不需要此指令之外。
放在一起,您的腳本將是:
// ==UserScript==
// @name Test
// @grant none
// @include http://docs.oracle.com/javase/8/docs/api/*
// @version 1
// ==/UserScript==
var classNamesFrame = null;
var classNamesDoc = null;
var classNamesATags = null;
var classNames = null;
function printClassNames()
{
classNamesDoc = classNamesFrame.contentDocument;
classNamesATags = classNamesDoc.getElementsByTagName('a');
classNames = new Array();
var i;
for (i = 0; i < classNamesATags.length; i++) {
classNames.push(classNamesATags[i].textContent);
}
console.log(classNames);
console.log(classNamesDoc.URL);
console.log('Total number of classes: ' + classNamesATags.length);
console.log("printClassNames called");
}
classNamesFrame = document.getElementsByName('packageFrame') [0];
if (classNamesFrame) {
classNamesFrame.onload = printClassNames;
}
-在Firefox和Chrome(以及其他)上均可使用。
// ==UserScript==
// @name Test
// @version 1
// @include http://docs.oracle.com/javase/8/docs/api/allclasses-frame.html
// @grant none
// ==/UserScript==
var classNamesATags = document.getElementsByTagName('a');
var classNames = [].map.call(classNamesATags, function(e) {
return e.textContent;
});
console.log(classNames);
console.log(document.URL);
console.log('Total number of classes: ' + classNamesATags.length);
alert('printClassNames called');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.