我正在为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
?
答案 0 :(得分:1)
该脚本有各种各样的错误(下面列出),但主要的是它抓错了contentDocument
。
这是因为Firefox返回<about:blank>
表示帧内容,直到它被实际的页面内容替换。 classNamesDoc
变量仍然指向空白值。 (请注意,Chrome处理框架的方式略有不同,并为您更新classNamesDoc
。)
所以,将classNamesDoc = classNamesFrame.contentDocument;
移到printClassNames()
内,最明显的问题就解决了。
其他问题,&#34;最恶劣的第一次&#34;:
格式错误的元数据块。 // ==/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(可能还有其他)。
答案 1 :(得分:0)
// ==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');