【问题标题】:How can I display the output of my userscript in a floating box on the side of the page?如何在页面侧面的浮动框中显示我的用户脚本的输出?
【发布时间】:2012-09-10 15:39:10
【问题描述】:

我正在为Unicreatures 编写用户脚本,用于跟踪探索期间的事件。它正在工作(嗯,它可以工作,但仍需要一些工作,哈哈)但我需要一种方法来显示我正在收集的信息,而不涉及每个步骤的弹出警报。

如何在页面上创建一个框并在其中显示内容?

我希望在此页面的菜单左侧创建一个框架、窗口等任何内容,并在我的脚本运行时将各种变量的值写入其中。

我在 localStorage 中收集这些数据,所以我的脚本将首先更新各种 localStorage 属性,然后以某种方式在此框中显示结果:

localStorage.steps = Number(localStorage.steps) + 1;
displayValueInFloatingBox(localStorage.steps + ' in Sargasso' );

我还想在此框中添加一个按钮来重置这些属性的值,这样我就可以选择永久跟踪还是只跟踪一两个会话,而不必每次都编辑脚本(尤其是如果我决定分享脚本)。我假设这只会将变量设置为零,所以我只需要知道如何创建按钮并让它做某事......这可能会以某种方式使用 eventListener。

请坚持使用纯 JavaScript,不要使用 jQuery……我现在还几乎没有接触到 JavaScript。并且请解释答案,以便我了解某些东西是如何工作的 - 我不只是想要让我回到类似问题的代码 sn-ps,因为我不明白为什么要使用一些代码。

附录 A:我当前的脚本

// ==UserScript==
// @name Unicreatures Egg pop-up
// @namespace Unicreatures Egg pop-up
// @description Unicreatures Egg pop-up
// @include http://unicreatures.com/explore.php*
// @include http://www.unicreatures.com/explore.php*
// ==/UserScript==
var regexp = /You find an? (Exalted )?(.*?) egg nearby/;
var match = regexp.exec( document.body.innerHTML );
if ( match ) {
  if ( match[1] ) {
      alert( "Exalted egg found: " + match[2] );
  } else {
      alert( "Normal egg found: " + match[2] );
  }
}
var y = document.body.innerHTML;
var links = document.getElementsByTagName( 'a' );

for ( var i = 0; i < links.length; i++ ) {
var link = links[i];
if ( /area=sea(?!\&gather)/.test( link.href )) {
      link.addEventListener( 'click', function () {
      localStorage.steps=Number(localStorage.steps)+1
      // alert(localStorage.steps + ' in Sargasso' );
    }, true );
  }
}

//document.addEventListener('click', function(){alert('page clicked')}, true);

if(y.indexOf("You find a Noble")> 0)
{
  alert('Noble Egg Alert');
}

if(y.indexOf("You find an Exalted")> 0)
{
  localStorage.exaltedEggCount=Number(localStorage.exaltedEggCount)+1;
  alert('Exalted Egg Alert '+localStorage.exaltedEggCount);
}

if(y.indexOf("egg nearby!")> 0)
{
  localStorage.eggCount=Number(localStorage.eggCount)+1;

  alert('Egg Alert '+localStorage.eggCount);
}

【问题讨论】:

  • 您要求通过 GreaseMonkey(或 UserScript)做的事情中有 90% 与制作在页面上运行的普通 Javascript 程序所做的事情完全相同。我们在 StackOverflow 的大多数人不介意帮助已经做出努力的人,但我们通常不愿意只交出代码块。回来看看你尝试过的具体例子。我会 start 在普通页面上只使用常规 javascript。更容易测试。 通常之后将其转换为 UserScript 相当容易。
  • 如果您更好地阅读我的问题,您会发现我不只是想要一段代码。我正在寻求帮助以找到答案,或者如果给出了代码,我想知道是什么让它工作的,以便我知道如何在其他地方做它......而且真的有那么大的代码块只是为了放页面上的小侧边栏?考虑到我需要的所有按钮的代码是知道如何将按钮放在那里,以及在该代码中的哪里放置我的指令?我没有意识到要制作一个带有 1 个按钮和 1 个复选框的空侧边栏需要这么多代码,所以我可以看到它是如何完成的
  • 实际上根本不需要那么多代码——但是稍加研究就会发现很多关于如何操作 DOM、添加 div 元素并添加或添加checkbox。这个问题表明没有尝试基础研究。
  • @KatCox 在页面左侧添加一个元素比在页面中添加一个“标题栏”需要更多的工作。我建议你先试试。我只是将一个新的 div 附加到正文 - 确保它是页面上的第一个元素。您可以使用 document.insertBefore(newElement, document.childNodes[0]);,其中 newElement 是这样创建的 document.createElement('div') document.childNodes[0] 只返回文档对象的第一个子对象。因此,如果您在第一个退出元素之前插入一个新元素,您将把您的元素添加到页面的最顶部。
  • @enhzflep 谢谢,现在我知道要查找什么了!我真的很感谢伸出援助之手......我真的不知道我应该看 div,并且由于某种原因我没有想到在我的任何搜索中使用插入(或者我的问题的标题可能会更清楚。现在,也许我的多动症会让我忘记这个足够长的时间去睡觉哈哈!谢谢!如果你添加你的评论作为答案,我可能会接受它。

标签: javascript button greasemonkey webpage


【解决方案1】:

这是在页面左上角添加框的一种简单方法。首先,我们需要创建一个div 元素作为盒子。 (其他 HTML 元素也可以,但div 是一个不错的选择,因为它没有特殊含义,只是一个简单的容器。)

var box = document.createElement( 'div' );

我们将为我们的盒子提供一个 ID,以便我们以后可以使用document.getElementsById() 找到它,以便我们可以style it with CSS

box.id = 'myAlertBox';

现在我们需要设置盒子的样式。由于我们使用的是 GreaseMonkey,我们可以使用GM_addStyle 将 CSS 样式规则添加到文档中:

GM_addStyle( 
    ' #myAlertBox {             ' +
    '    background: white;     ' +
    '    border: 2px solid red; ' +
    '    padding: 4px;          ' +
    '    position: absolute;    ' +
    '    top: 8px; left: 8px;   ' +
    '    max-width: 400px;      ' +
    ' } '
);

请注意在 JavaScript 中包含 multi-line string 的尴尬语法。 (还有其他方法可以设置框的样式,也可以在 GreaseMonkey 之外使用。我将在下面展示其中的一些。)

查看 CSS 样式规则本身,前三行只是说我们的盒子应该有一个白色背景和一个 2 像素宽的红色边框,并且边框和内容之间应该有 4 个像素的填充。所有这些只是makes it look like 一个典型的简单警报框。

下面一行说我们的盒子应该是页面上的absolutely positioned——也就是说,不管页面上还有什么,总是在一个固定的位置——下面的那个指定我们想要给它的位置:此处,距页面左上角四个像素。最后一行只是说,无论我们在其中塞入多少内容,框的宽度都不应超过 400 像素。

说到这里,当然我们也需要添加一些内容。我们可以只使用纯文本:

box.textContent = "Here's some text! This is not HTML, so <3 is not a tag.";

或者我们可以使用 HTML:

box.innerHTML = "This <i>is</i> HTML, so &lt;3 needs to be escaped.";

最后,我们需要将框添加到页面中以使其显示出来:

document.body.appendChild( box );

你去吧!页面上的一个框。


好的,但是我们如何摆脱它呢?好吧,最简单的方法就是让它在点击时消失:

box.addEventListener( 'click', function () {
    box.parentNode.removeChild( box );
}, true );

或者,我们可以为该框创建一个单独的关闭按钮,并仅为该框设置点击处理程序:

var closeButton = document.createElement( 'div' );
closeButton.className = 'myCloseButton';
closeButton.textContent = 'X';

GM_addStyle( 
    ' .myCloseButton {           ' +
    '    background: #aaa;       ' +
    '    border: 1px solid #777; ' +
    '    padding: 1px;           ' +
    '    margin-left: 8px;       ' +
    '    float: right;           ' +
    '    cursor: pointer;        ' +
    ' } '
);

box.insertBefore( closeButton, box.firstChild );
closeButton.addEventListener( 'click', function () {
    box.parentNode.removeChild( box );
}, true );

在框中的任何其他内容之前插入关闭按钮,并赋予其样式float: right 使其浮动到右上角并使文本围绕它流动。 cursor: pointer 规则使鼠标光标在按钮上方时看起来像一只手,表明它是可点击的。

您还可以以相同的方式将其他按钮添加到框(或页面上的其他位置)。 我给按钮一个类名而不是一个 ID,这样,如果你愿意,你可以给你的所有按钮一个相同的类,它们的样式也一样。

也可以将按钮的 HTML 代码放在 box.innerHTML 中,找到结果元素,例如使用box.getElementById() 并以这种方式为它们添加点击处理程序。


我说过我会提到其他样式元素的方式。一种简单的方法是直接将 CSS 规则写入其style 属性:

box.style.cssText =
    ' background: white;     ' +
    ' border: 2px solid red; ' +
    ' padding: 4px;          ' +
    ' position: absolute;    ' +
    ' top: 8px; left: 8px;   ' +
    ' max-width: 400px;      ' ;

(这样,我们甚至不需要给盒子一个 ID。)也可以一次设置(和读取)一个样式:

box.style.background = 'white';
box.style.border = '2px solid red';
box.style.padding = '4px';
box.style.position = 'absolute';
box.style.top = '8px';
box.style.left = '8px';
box.style.maxWidth = '400px';

您会注意到有些名称是不同的;例如,max-width 不是一个有效的 JavaScript 属性名,所以它变成了maxWidth。相同的规则适用于其他带有连字符的 CSS 属性名称。

不过,我更喜欢GM_addStyle,因为它更灵活。例如,如果您想将框内的所有链接设为红色,您可以这样做:

GM_addStyle( 
    ' #myAlertBox a {  ' +
    '    color: red;   ' +
    ' } '
);

顺便说一句,这是一个巧妙的技巧:如果您将 position: absolute 替换为 position: fixed,那么该框将不会随着页面滚动 - 相反,即使您滚动它也会固定在浏览器的角落下来。

另一个提示:如果您还没有Firebug,请安装它。这将使检查页面内容和调试 JavaScript so 变得更加容易。

【讨论】:

  • 上帝,我喜欢你的回答!很清楚,很好解释,还有很多参考链接!几个问题...如果我使用GM_addStyle 并且未设置某些值,我可以稍后在脚本中使用box.style.** 格式设置它们吗?我会假设是的,但编码规则并不总是有意义的。根据您发送给我的多行字符串页面,您的字符串组合方法性能最差,因此对于较大的脚本,我肯定应该使用不同的方法......他们并不清楚.join 方法还是尾部的反斜杠是最有效的吗?
  • 我也刚刚意识到,如果我愿意的话,我可能可以使用我的网页创建程序之一来完成这部分......但对于像这样的小东西,它可能毫无意义。我曾经安装过 Firebug,但它对我的电脑做了一些讨厌的事情......由于我所有的标签组,firefox 已经占用了很多 CPU 和内存......他们可能从那时起更新了它,所以我可能会在我的时候尝试它没有卡在拨号上。我一直在使用似乎没什么用处的网络开发工具。
  • 在您的GM_addStyle 中,您有',而在油脂罐维基上,他们使用"。有区别吗?
  • 哎呀,忘记接受答案了,哈哈。无论如何,我刚刚找到了 Firebug 和 Web 开发人员工具的替代品,用于查找您可能会感兴趣的页面的类、ID 和其他内容 - westciv.com/xray 您将书签放入 Firefox 或 IE,然后在任何页面上单击它...酷
  • 你当然可以组合GM_addStyle.style,但是它们的交互并不像人们想象的那么简单:GM_addStyle将规则添加到整个文档的样式表中,而.style改变了特定元素的“内联样式”。基本上,任何用.style 设置的样式属性都会覆盖那些用GM_addStyle 设置的样式属性(除非后者被标记为!important 而前者没有)。
猜你喜欢
  • 1970-01-01
  • 2014-11-24
  • 2011-01-21
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
  • 2021-04-07
相关资源
最近更新 更多