我已经选择了一个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属性的情况下完成此操作,但很可能我错了,这是完成此任务的最佳方法。
答案 0 :(得分:1)
您可以使用element.previousSibling
和element.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)