提取HTML并插入DOM,但相对于特定路径进行解析

时间:2019-07-19 15:27:43

标签: javascript html dom

假设我在/path/fragment.html有这个html片段:

<h1>Hi there</h1>

<img src='./image.jpg'/>

我可以获取此文件并将其轻松插入DOM:

const dom = document.getElementById('root');
const response = await fetch('/path/fragment.html');
const fragment = await response.text();
dom.innerHTML = fragment;

但是,图像是相对于调用JavaScript的HTML文件加载的,因此显然是404s。

是否可以通过某种方式设置innerHTML,使其像在/path/中一样解析片段,从而正确加载图像(和其他相对路径资源)?

3 个答案:

答案 0 :(得分:3)

@Michael Crenshaw已经指出了许多可能解决方案的选择,但这是我的

使用绝对路径。这样,路径将始终是正确的。

答案 1 :(得分:1)

  1. 您可以走捷径: dom.innerHTML = fragment.replace('src=\'./', 'src=\'./path/');

  2. 或者在插入HTML之后,您可以遍历<img>元素并更新源。

  3. 您还可以使用<iframe>来包含源,以便正确使用相对路径。

据我所知,在设置适当元素的路径信息时,还没有完整,智能的方式来插入HTML。

答案 2 :(得分:1)

绝对路径

我同意绝对路径会起作用,尽管将绝对路径放入动态URL中可能会有问题。

模板字符串

我认为建议在源代码中使用模板字符串,例如{{ baseUrl }}

<img src="{{ baseURL }}/bar.jpg">

不太可能发生冲突,它们.replace(/{{\s*baseUrl\s*}}/, '../foo')的速度和效率都很高

DOM编辑

如果您不喜欢用“笨拙”的方式替换所有模板字符串,或者想要进行更复杂的分析,则可以创建一个DOM元素并事先选择它们:

// fragment = ...
var div = document.createElement('div');
div.innerHTML = fragment;

// Modify the DOM in-memory
div.querySelectorAll('img[src^="/foo"]').forEach(function (el) {
  el.src = el.src.replace(/\/foo/, "../foo");
});

// Append to the live DOM to be drawn
var widget = document.querySelector('.js-widget');
widget.appendChild(div);

但是,由于DOM实现的遗留工件,这实际上比字符串操作要慢,具体取决于您如何使用它。

未经请求的建议

  • CSS id :纯粹的邪恶。它们会污染javascript全局名称空间,从而导致意外的行为和难以调试的行为。改用 class es
  • querySelector()querySelectorAll():它们完成$(sel)的工作。基本上,从许多年前开始,所有jQuery都已进入本机DOM,因此可以在任何地方使用。大多数API是jQuery的直接端口-querySelector()是例外,而不是规则。