可能正在寻找一个古老问题的答案,但我想阻止脚本执行。在我的用例中,阻止浏览器是可以接受的。
此外,在我的用例中,我尝试从Firefox扩展程序执行此操作,这意味着我的代码是" Chrome代码",在浏览器环境中运行。
这可以通过使用模态窗口,然后以编程方式关闭窗口来轻松完成。所以这表明存在一种阻塞机制。
有没有办法在没有实际创建或打开模态窗口的情况下实现模态阻塞?有哪些方法可以利用用于模态窗口的阻塞机制?
我已就此主题进行了大量搜索,但无济于事。
答案 0 :(得分:1)
使用nsIProcess可以阻止线程。
您可以创建一个具有sleep或usleep方法或等效方法的可执行文件。然后同步运行该进程(nsIProcess.run)并将blocking参数设置为true。
当然,为了便于携带,您需要创建适合您希望支持的每个平台的可执行文件,并提供歧视代码。
基本代码如下所示。我已经在'nix(Mac OS X)上验证了此代码的工作原理,使用仅包含行sleep .03
的bash脚本:
let testex = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsIFile);
testex.initWithPath("/Users/allasso/Desktop/pause.sh");
let process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(testex);
let delay = 30; // convert this to milliseconds in the executable
process.run(true,[delay],1); // `run` method runs synchronously, first arg says to block thread
在扩展中,您可能希望使nsIFile文件对象更具可移植性:
Components.utils.import("resource://gre/modules/FileUtils.jsm");
let testex = FileUtils.getFile("ProfD",["extension@moz.org","resources","pause.sh"]);
当然要记住,Javascript基本上是单线程的,所以除非你阻止使用Web Workers生成的线程,否则你将在睡眠期间冻结整个UI(就像你打开一个模态窗口一样)
参考文献:
https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess
https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile
https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O#Getting_special_files
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/basic_usage
答案 1 :(得分:0)
此处enterModalState
中有leaveModalState
和nsIDOMWindowUtils
:MDN :: nsIDOMWindowUtils Reference
然而,他们似乎并不适合我。本主题可以解释原因:nsIDOMWindowUtils.isInModalState() not working他们的主题是isInModalState
标记为[noscript]
我看到了,但enterModalState
和leaveModalState
未标记为[noscript]
我不知道为什么它不起作用。
对我来说有用的是suppressEventHandling
:
var utils = Services.wm.getMostRecentWindow('navigator:browser').
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.suppressEventHandling(true); //set arg to false to unsupress
您可以打开一个小窗口,将源窗口作为要进行模态化的窗口,然后打开对话框,将其打开。它的对话框因此它不会显示OS标签栏的新窗口。但是按下alt + f4会关闭那个胜利,但是你可以附加事件监听器(或者可以使用utils.suppressEventHandling,因此键盘不能正常工作)以避免关闭,直到你想要它关闭。这是代码:
var sDOMWin = Services.wm.getMostRecentWindow(null);
var sa = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
var wuri = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
wuri.data = 'about:blank';
sa.AppendElement(wuri);
let features = "chrome,modal,width=1,height=1,left=-100";
if (PrivateBrowsingUtils.permanentPrivateBrowsing || PrivateBrowsingUtils.isWindowPrivate(sDOMWin)) {
features += ",private";
} else {
features += ",non-private";
}
var XULWindow = Services.ww.openWindow(sDOMWin, 'chrome://browser/content/browser.xul', null, features, sa);
/*
XULWindow.addEventListener('load', function() {
var DOMWindow = XULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
DOMWindow.gBrowser.selectedTab.linkedBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL);
DOMWindow.gBrowser.swapBrowsersAndCloseOther(DOMWindow.gBrowser.selectedTab, aTab);
//DOMWindow.gBrowser.selectedTab = newTab;
}, false);
*/