javascript 为什么document.addEventListener('load', function) 在greasemonkey 脚本中不起作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16404380/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 04:31:34  来源:igfitidea点击:

Why doesn't document.addEventListener('load', function) work in a greasemonkey script?

javascriptgreasemonkeyaddeventlistener

提问by Yet Another User

It doesn't give an error, and I put a console.log('loaded userscript wifi-autologin'), the console.logworks, but the intended effect of the document.addEventListener doesn't happen. After doing a bit more debugging, making it print that the addEventListener was called, I discovered that it wasn't being called.

它没有给出错误,我放了一个console.log('loaded userscript wifi-autologin')console.log工作,但 document.addEventListener 的预期效果不会发生。在进行了更多的调试后,让它打印出 addEventListener 被调用了,我发现它没有被调用。

Source of script:

脚本来源:

// ==UserScript==
// @name        wifi-autologin
// @namespace   lf-ns
// @description Hopefully autologins to a captive portal
// @include     *://1.1.1.1/*
// @version     1
// @run-at document-end
// ==/UserScript==

document.addEventListener('load', submitAction);

回答by Yet Another User

Apparently, document.addEventListener()is unreliable, and hence, my error. Use window.addEventListener()with the same parameters, instead.

显然,document.addEventListener()是不可靠的,因此,我的错误。window.addEventListener()改为使用相同的参数。

回答by ekim

The problem is WHENthe event is added andEXECUTEDvia triggering (the documentonloadproperty modification can be verified by examining the properties list).

问题是WHEN添加事件EXECUTED通过触发(在documentonload属性修改可以通过检查属性列表来验证)。

When does this execute and modify onloadrelative to the onloadevent trigger:

什么时候执行和修改onload相对于onload事件触发器:

document.addEventListener('load', ... );

before, during or after the load and/or render of the page's HTML?
This simple scURIple (cut & paste to URL) "works" w/o alerting as naively expected:

在加载和/或呈现页面的 HTML 之前、期间或之后?
这个简单的 scURIple(剪切并粘贴到 URL)alert按天真的预期“有效” :

data:text/html;charset=utf-8,
    <html content editable><head>
          <script>
                document.addEventListener('load', function(){ alert(42) } );
          </script>
          </head><body>goodbye universe - hello muiltiverse</body>
    </html>

Does loading imply script contents have been executed?

加载是否意味着脚本内容已被执行?

A little out of this world expansion ...
Consider a slight modification:

有点超出这个世界的扩展......
考虑一个小的修改:

data:text/html;charset=utf-8,
    <html content editable><head>
          <script>
              if(confirm("expand mind?"))document.addEventListener('load', function(){ alert(42) } );
          </script>
        </head><body>goodbye universe - hello muiltiverse</body>
    </html>

and whether the HTML has been loaded or not.

以及 HTML 是否已加载。

Rendering is certainly pending since goodbye universe - hello muiltiverseis not seen on screen but, does not the confirm( ... )have to be alreadyloaded to be executed? ... and so document.addEventListener('load', ... )... ?

渲染肯定是挂起的,因为goodbye universe - hello muiltiverse在屏幕上看不到,但是,不是confirm( ... )必须已经加载才能执行吗?……所以document.addEventListener('load', ... )……?

In other words, can you execute code to check for self-loading when the code itself is not yet loaded?

换句话说,当代码本身尚未加载时,您是否可以执行代码来检查自加载?

Or, another way of looking at the situation, if the code is executable and executed then it has ALREADYbeen loaded as a done deal and to retroactively check when the transition occurred between not yet loaded and loaded is a priori fait accompli.

或者,看着的情况下,如果代码是可执行文件,然后执行它的另一种方式ALREADY被加载木已成舟,并追溯检查时的过渡尚未加载,加载之间发生的是一个先验的既成事实

So which comes first: loading and executing the code or using the code's functionality though not loaded?

那么哪个先出现:加载和执行代码还是使用代码的功能虽然没有加载?

onloadas a windowproperty works because it is subordinate to the object and not self-referential as in the documentcase, ie. it's the window's contents, via document, that determine the loaded question err situation.

onload作为window属性起作用,因为它从属于对象,而不是像这种document情况下的自我参照,即。它的window内容,通过document,确定加载的问题错误情况。

PS.: When do the following fail to alert(...)? (personally experienced gotcha's):

PS.:以下什么时候失败alert(...)?(个人经历过的陷阱):

caveat: unless loading to the same window is really fast ... clobbering is the order of the day
so what is really needed below when using the same named window:

警告:除非加载到同一个窗口非常快...... clobbering 是一天的顺序,
所以当使用相同命名的窗口时,下面真正需要的是:

window.open(URIstr1,"w") .
   addEventListener('load', 
      function(){ alert(42); 
         window.open(URIstr2,"w") .
            addEventListener('load', 
               function(){ alert(43); 
                  window.open(URIstr3,"w") .
                     addEventListener('load', 
                        function(){ alert(44); 
                 /*  ...  */
                        } )
               } )
      } ) 

alternatively, proceed each successive window.openwith:
alert("press Ok either after # alert shows pending load is done or inspired via divine intervention" );

或者,依次window.open进行:
alert("press Ok either after # alert shows pending load is done or inspired via divine intervention" );

data:text/html;charset=utf-8,
    <html content editable><head><!-- tagging fluff --><script>

        window.open(
            "data:text/plain, has no DOM or" ,"Window"
         ) . addEventListener('load', function(){ alert(42) } )

        window.open(
            "data:text/plain, has no DOM but" ,"Window"
         ) . addEventListener('load', function(){ alert(4) } )

        window.open(
            "data:text/html,<html><body>has DOM and", "Window"
         ) . addEventListener('load', function(){ alert(2) } )

        window.open(
            "data:text/html,<html><body>has DOM and", "noWindow"
         ) . addEventListener('load', function(){ alert(1) } )

        /* etc. including where body has onload=... in each appropriate open */

    </script><!-- terminating fluff --></head></html>

which emphasize onloaddifferences as a documentor windowproperty.

强调onload作为documentwindow属性的差异。

Another caveat concerns preserving XSS, Cross Site Scripting, and SOP, Same Origin Policy rules which may allow loading an HTML URI but not modifying it's content to check for same. If a scURIple is run as a bookmarklet/scriplet from the same origin/site then there maybe success.

另一个警告涉及保留 XSS、跨站点脚本和 SOP、同源策略规则,这些规则可能允许加载 HTML URI 但不允许修改其内容以检查相同内容。如果 scURIple 作为来自同一来源/站点的书签/脚本运行,那么可能会成功。

ie. From an arbitrary page, this link will do the load but not likely do alert('done'):

IE。从任意页面,此链接将执行加载但不太可能执行alert('done')

    <a href="javascript:window.open('view-source:http://google.ca') . 
                   addEventListener( 'load',  function(){ alert('done') }  )"> src. vu </a>

but if the link is bookmarked and then clicked when viewing a google.capage, it does both.

但如果链接被添加书签,然后在查看google.ca页面时点击,它会同时执行这两项操作。

test environment:

测试环境:

 window.navigator.userAgent = 
   Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 (Splashtop-v1.2.17.0)

回答by Bruce Tong

To get the value of my drop down box on page load, I use

要在页面加载时获取下拉框的值,我使用

document.addEventListener('DOMContentLoaded',fnName);

Hope this helps some one.

希望这对某人有所帮助。

回答by bh_earth0

this happened again around last quarter of 2017 . greasemonkey firing too late . after domcontentloaded event already been fired.

这种情况在 2017 年最后一个季度左右再次发生。油猴开火为时已晚。在 domcontentloaded 事件已经被触发之后。

what to do:

该怎么办:

  • i used @run-at document-startinstead of document-end
  • updated firefox to 57.
  • 我用@run-at document-start而不是文档结束
  • 将 Firefox 更新为 57。

from : https://github.com/greasemonkey/greasemonkey/issues/2769

来自:https: //github.com/greasemonkey/greasemonkey/issues/2769

Even as a (private) script writer I'm confused why my script isn't working.

The most likely problem is that the 'DOMContentLoaded' event is fired before the script is run. Now before you come back and say @run-at document-start is set, that directive isn't fully supported at the moment. Due to the very asynchronous nature of WebExtensions there's little guarantee on when something will be executed. When FF59 rolls around we'll have #2663 which will help. It'll actually help a lot of things, debugging too.

即使作为(私人)脚本编写者,我也很困惑为什么我的脚本不起作用。

最可能的问题是在脚本运行之前触发了 'DOMContentLoaded' 事件。现在,在您返回并说已设置 @run-at document-start 之前,目前不完全支持该指令。由于 WebExtensions 非常异步的特性,几乎无法保证何时执行某些操作。当 FF59 推出时,我们将拥有 #2663,这将有所帮助。它实际上会帮助很多事情,调试也是如此。