4

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

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

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

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

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

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

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

附录 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);
}
4

1 回答 1

11

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

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

我们将给我们的盒子一个 ID,以便我们以后可以找到它document.getElementsById(),以便我们可以使用 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 中包含多行字符串的笨拙语法。(还有其他方法来设置盒子的样式,也可以在 GreaseMonkey 之外使用。我将在下面展示其中的一些。)

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

下面一行说我们的盒子应该绝对定位在页面上——也就是说,不管页面上还有什么,总是在一个固定的位置——下面的那个指定我们想要给它的位置:这里,四个像素从页面的左上角。最后一行只是说,无论我们在其中塞入多少内容,框的宽度都不应超过 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,找到结果元素,例如 withbox.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: absoluteposition: fixed,那么框将不会随着页面滚动——相反,即使你向下滚动,它也会固定在浏览器的角落。

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

于 2012-09-10T18:28:22.940 回答