简体   繁体   English

我的Greasemonkey脚本找不到页面上的元素(链接)吗?

[英]My Greasemonkey script is not finding the elements (links) on the page?

The website is: lexin.nada.kth.se/lexin/#searchinfo=both,swe_gre,hej; 该网站是: lexin.nada.kth.se/lexin/#searchinfo=both,swe_gre,hej;

My script is: 我的脚本是:

function main(){
  var links=document.getElementsByTagName("a");
  alert("There are " + links.length + "links.");
}

main();

Running the script gives me two alert messages saying 运行脚本会给我两条警告消息,提示

There are 0 links. 有0个链接。

Any ideas why I can't get the right amount of links from the document? 为什么我无法从文档中获得正确数量的链接? And why do I get the alert twice? 为什么我会两次收到警报?

  1. The alert fires more than once because that page contains iFrames (with, de facto, the same URL as the main page). 警报触发不止一次,因为该页面包含iFrame(事实上,该URL与主页相同)。 Greasemonkey treats iFrames as if they were standalone web pages. Greasemonkey将iFrame视为独立的网页。 Use @noframes to stop that. 使用@noframes停止该操作。

  2. The script is not finding the links because they are added, by javascript, long after the page loads and the GM script fires. 该脚本未找到链接,因为在页面加载和GM脚本启动后很长一段时间内,它们是通过javascript添加的。 This is a common problem with scripts and AJAX. 这是脚本和AJAX的常见问题。 A simple, robust solution is use waitForKeyElements() (and jQuery). 一个简单,可靠的解决方案是使用waitForKeyElements() (和jQuery)。

Here is a complete sample script that avoids the iFrames and shows how to get dynamic links: 以下是一个完整的示例脚本 ,该脚本避免使用iFrame,并显示了如何获取动态链接:

// ==UserScript==
// @name     _Find elements added by AJAX
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @match    http://stackoverflow.com/questions/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @noframes
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/
var totalUsrLinks   = 0;

waitForKeyElements ("a[href*='/users/']", listLinks);

function listLinks (jNode) {
    var usrMtch     = jNode.attr ("href").match (/^.*\/users\/(\d+)\/.*$/);
    if (usrMtch  &&  usrMtch.length > 1) {
        totalUsrLinks++;
        var usrId   = usrMtch[1];
        console.log ("Found link for user: ", usrId, "Total links = ", totalUsrLinks);
    }
}

It's returning an HTMLcollection because of .getElementsByTagName and because of that, you will have to state the HTMLcollection with .getElementsByTagName and then find the length, and alert it. 由于.getElementsByTagName而返回HTMLcollection,因此,您必须使用.getElementsByTagName声明HTMLcollection,然后找到长度并发出警报。 It will look like this... 看起来像这样...

  (function main(){ var links = document.getElementsByTagName("a").length alert("There are "+ links + " links."); })() 

I added an IIFE or an Immediately-Invoked-Function-Expression more on IIFEs here , so you don't have to call the function, and so the code is small and able to be "swallowed". 在这里在IIFE上添加了IIFE或立即调用函数表达式,因此您不必调用该函数,因此代码很小,可以被“吞噬”。 lastly, it's alerting 2 alert boxes, because there's one[alert box] in the function and you're calling that function so it's going to do the same thing. 最后,它正在警告2个警告框,因为该函数中有一个[alert box],而您正在调用该函数,因此它将执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM