用普通 javascript 遍历文本节点

Traverse text nodes with plain javascript

var history = document.getElementById('tooltip')
 
console.log(history)
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <span id="tooltip">
  26 Sep, 17:01  <strong>2.25</strong> <span class="plus">+0.10</span><br>
  26 Sep, 16:46  <strong>2.15</strong> <span class="plus">+0.10</span><br>
  26 Sep, 12:32  <strong>2.05</strong> <span class="minus">-0.20</span><br>
  25 Sep, 13:30  <strong>2.25</strong> <span class="plus">+0.05</span><br>
  <br>Opening:<br>25 Sep, 02:28  <strong>2.20</strong><br>
  </span>
</body>
</html>

我尝试从 ID 为 tooltip 的范围中获取信息,并将其带到某个结构化的 javascript 对象中。不幸的是我不能使用 jQuery。 (它是带有 nightmare.js 评估的注入代码)。

控制台returns

[object History] {
  back: function back() { [native code] },
  forward: function forward() { [native code] },
  go: function go() { [native code] },
  length: 4,
  pushState: function pushState() { [native code] },
  replaceState: function replaceState() { [native code] },
  scrollRestoration: "auto",
  state: null
}

我觉得像 https://www.w3schools.com/jsref/obj_history.asp

函数 getElementById 应该 return 一个元素,这样我就可以遍历它的子节点并将数据收集到这样的东西中:

[
  {date: '26 Sep, 17:01', value: 2.25, change: 0.10 },
  {date: '26 Sep, 16:46', value: 2.15, change: 0.10 }
  // ...
]

所以这是有史以来最愚蠢的解决方案,但是嘿...:) 您需要做的就是更改变量名称!

var myHistory = document.getElementById('tooltip')
 
console.log(myHistory)
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <span id="tooltip">
  26 Sep, 17:01  <strong>2.25</strong> <span class="plus">+0.10</span><br>
  26 Sep, 16:46  <strong>2.15</strong> <span class="plus">+0.10</span><br>
  26 Sep, 12:32  <strong>2.05</strong> <span class="minus">-0.20</span><br>
  25 Sep, 13:30  <strong>2.25</strong> <span class="plus">+0.05</span><br>
  <br>Opening:<br>25 Sep, 02:28  <strong>2.20</strong><br>
  </span>
</body>
</html>

history 是一个只读的全局对象,所以你的赋值不会做任何事情。除了像上面的例子那样改变变量名,一个更结构化的解决方案是确保你的脚本 运行 在局部范围内,而不是在全局范围内。

一种久经考验的方法是将您的代码包装在 immediately invoked function expression (IIFE)

(function(){
var history = document.getElementById('tooltip')
 
console.log(history)
})() // <-- immediately invoke the function here!
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <span id="tooltip">
  26 Sep, 17:01  <strong>2.25</strong> <span class="plus">+0.10</span><br>
  26 Sep, 16:46  <strong>2.15</strong> <span class="plus">+0.10</span><br>
  26 Sep, 12:32  <strong>2.05</strong> <span class="minus">-0.20</span><br>
  25 Sep, 13:30  <strong>2.25</strong> <span class="plus">+0.05</span><br>
  <br>Opening:<br>25 Sep, 02:28  <strong>2.20</strong><br>
  </span>
</body>
</html>

您真的应该养成在代码周围使用 IIFE 或一些更高级的模块系统的习惯,以确保您的代码从不 在全局范围内运行。否则,每次您在全局范围内分配给一个变量时,您实际上是在向 window 对象添加属性!这是 Javascript 的阴暗面之一,但我们不得不忍受它。

var x = 10
console.info(window.x)

要了解有关使用匿名函数进行范围界定、创建 'private' 变量和其他更高级的 JS 主题的更多信息,我建议阅读 this article by Douglas Crockford, or better yet, order his book Javascript, the good parts。非常好的读物恕我直言。

(我希望推荐一本书不违反政策。如果是,请随意编辑。)

你是这个意思吗?

  1. 从可能的保留字更改变量名称
  2. 换行拆分
  3. 如果需要零件,请拆分 space

var tt = document.getElementById('tooltip')
 
console.log(tt.innerText.split("\n"))
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <span id="tooltip">
  26 Sep, 17:01  <strong>2.25</strong> <span class="plus">+0.10</span><br>
  26 Sep, 16:46  <strong>2.15</strong> <span class="plus">+0.10</span><br>
  26 Sep, 12:32  <strong>2.05</strong> <span class="minus">-0.20</span><br>
  25 Sep, 13:30  <strong>2.25</strong> <span class="plus">+0.05</span><br>
  <br>Opening:<br>25 Sep, 02:28  <strong>2.20</strong><br>
  </span>
</body>
</html>

您可以使用 regex 以您想要的格式从工具提示中获取数据。

我定义了表达式 /([a-zA-Z0-9,: ]+) ([0-9.]+) ([0-9+\-.]+)/g 将每行分成 3 个不同的组。

  1. ([a-zA-Z0-9,: ]+) 与你的约会有关
  2. ([0-9.]+) 对应值
  3. ([0-9+\-.]+) 涉及变化

在第 3 组中,我保留了 +/-,因为我猜您可能想要跟踪变化是积极的还是消极的。如果你不想要你可以将第 3 组更改为 [+|-]([0-9.]+)

const re = RegExp(/([a-zA-Z0-9,: ]+) ([0-9.]+) ([0-9+\-.]+)/g);

const tooltip = document.getElementById('tooltip');

// get the outerText of the tooltip element

const data = [];

while (item = re.exec(tooltip.outerText)) {
  data.push({
    date: item[1],
    value: item[2],
    change: item[3]
  });
}

/** [[object Object] {
  change: "+0.10",
  date: "26 Sep, 17:01",
  value: "2.25"
}, [object Object] {
  change: "+0.10",
  date: "26 Sep, 16:46",
  value: "2.15"
}, [object Object] {
  change: "-0.20",
  date: "26 Sep, 12:32",
  value: "2.05"
}, [object Object] {
  change: "+0.05",
  date: "25 Sep, 13:30",
  value: "2.25"
}] **/

console.log(data);

https://jsbin.com/dovahum/edit?html,js,console