在加载内容之前调用HTML框架的onload

时间:2014-07-02 13:52:02

标签: javascript dom greasemonkey dom-events html-frames

我正在为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

2 个答案:

答案 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');
相关问题