Code from bookmarklet works in console but not in my Tampermonkey script?

馋奶兔 提交于 2019-12-11 05:03:12

问题


tl;dr

Don't use exotic dynamic injection of external libraries in Userscript. @require them instead.


Original Question

I am trying to modify this page with the following script:

console.log("run");
!function(){var e=document.createElement("SCRIPT")
e.src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js",e.type="text/javascript",document.getElementsByTagName("head")[0].appendChild(e)
var t=function(e){window.jQuery?e(jQuery):window.setTimeout(function(){t(e)},100)}
t(function(e){e(".title").children().each(function(){this.href="/"+this.href.split("'")[1]})})}()

The script works fine from the console (try it), transforming window-open links to URL hrefs. However, the same script in Tampermonkey does not work (and the debug line shows in the console, indicating that the script is indeed running):

These are the settings for the particular script:

What am I doing wrong? How can I make the script work from Tampermonkey?


After checking syntax (see comments):


Changing some commas to semicolons --- this is a mess.


回答1:


That script relies on a very short timer for jQuery to load. That is very bad form; it sets up a race condition which might be okay in one circumstance but fail in others.

It might (usually) work from the console because most of the code operates synchronously and it's all in the same scope.

But that code from a Tampermonkey script switches scopes and injects some but not all of the needed code.

Don't use jQuery from a userscript that way! Keep the script sandboxed and use @require for better performance.

In this case, your entire script would become:

// ==UserScript==
// @name     OpenHymnal fix
// @match    http://openhymnal.org/genindex.html
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/

console.log ("run");

$(".title").children ().each (function () {
    this.href = "/" + this.href.split("'")[1]
} );


来源:https://stackoverflow.com/questions/23923992/code-from-bookmarklet-works-in-console-but-not-in-my-tampermonkey-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!