从DOM节点

时间:2018-01-25 07:55:33

标签: javascript

我已经选择了一个DOM节点,如果它既有前缀并且后缀为$,我想进行一些处理。因此,选择<code>元素,我想处理这种情况:

<p>I assert $<code>1 + 1 = 2</code>$, it's true!</p>

并将其转换为:

<p>I assert <code class="language-inline-math">1 + 1 = 2</code>, it's true!</p>

也就是说,如果我选择的DOM节点前面有一些令牌,并且某个令牌立即成功,我想剥离这些令牌并在节点上进行一些处理。

我通过操纵innerHTML / outerHTML来实现这一点,但是通过序列化HTML而不是DOM API来操作DOM元素是错误的。有没有一种方法可以在不写innerHTML的情况下完成此任务?

// given a pre-selected `var el` DOM node
var parent = el.parentNode;
var inlineMath = "$" + el.outerHTML + "$";
if (parent.innerHTML.indexOf(inlineMath) !== -1) {
    el.classList.add("language-inline-math");
    parent.innerHTML = parent.innerHTML.replace("$" + el.outerHTML + "$", el.outerHTML);
}

为了避免XY problem,这是我尝试解决的实际任务:

我有一些(共同标记)降价,我想在(通用标记兼容)降价解析器之上引入轻量级扩展语法。对于块区,这是显而易见的选择:

```math
1 + 1 = 2
```

成为

<pre><code class="language-math">1 + 1 = 2
</code></pre>

根据CommonMark规范。这很容易找到,然后从JavaScript输入数学显示库。但是,对于内联数学,内联代码语法不支持添加语言类,因此必须在顶部添加一些其他语法。

代码块的重用在语义上很有用,因为它们定义了markdown不进行任何处理的范围。处理LaTeX / MathJax / KaTeX或其他系统的内联数学的常用方法是通过$ - fencing。所以我选择采用GitLab的语法并使用$ <no space> <inline-code-block> <no space> $来表示内联数学方程式。

而不是

I assert $`1 + 1 = 2`$, it's true!

可以让人们写

I assert `$1 + 1 = 2$`, it's true!
如果没有JavaScript,那么 会有类似的回退,但问题是$code$是人们希望能够正常写入的东西,因此我更喜欢外部防护。

鉴于我有一个有效的解决方案,正确的答案可能是&#34;没有比你已经做过的更好的方式&#34;。我觉得有一种更好的方法可以在不使用基于文本的序列化HTML属性的情况下完成此操作,但很可能我错了,这是完成此任务的最佳方法。

1 个答案:

答案 0 :(得分:1)

您可以使用element.previousSiblingelement.nextSibling属性获取元素之前和之后的文本节点,并检查它们是否以$开头和结尾。然后,您可以使用element.splitText(n)方法将文本节点分为两个节点:一个包含$,另一个包含其余节点。然后使用element.remove()方法删除$文本节点。

        var n = e.nextSibling;
        var p = e.previousSibling;
        if (n && p && /^\$/.test(n.data) && /\$$/.test(p.data)) {
            // Whatever you wanted to do with `e` here.
            n.splitText(1); n.remove();
            p.splitText(p.data.length - 1).remove();
        }

(这就是我在这里使用的:https://github.com/m-ou-se/rust-horrible-katex-hack/blob/565ffd921d3c0eef2037aef58215c56ba1a09ddc/src/lib.rs#L10-L15