2

如果我使用hx-swap-oob,则会出现错误:

<script src="https://unpkg.com/htmx.org@1.3.3/dist/htmx.js"></script>
<div id="sum">?</div>
<table>
 <tr>
  <td><button 
   hx-get="https://run.mocky.io/v3/b5a6902e-fc46-479b-92e4-9b4befc7a920"
   hx-target="closest tr">1</button>
  </td>
  <td>one</td>
 </tr>
</table>

按“运行代码片段”后,然后按1

htmx:swapError
{
  "message": "e.querySelectorAll is not a function",
  "filename": undefined,
  "lineno": undefined,
  "colno": undefined
}

模拟http 端点返回:


<tr>
  <td>2</td><td>two</td>
 </tr>

<div id="sum" hx-swap-oob="true">MAGIC</div>

在上面的示例中,我使用了非缩小版本,因此错误消息是:eltOrSelector.querySelectorAll is not a function

如果我使用这个端点,它不会失败:https ://run.mocky.io/v3/2ab904eb-23a9-4006-b68b-f112b55841f3

但在我的用例中,新的 html 片段应该是<tr>...</tr>,而不是<div>......

JS 堆栈跟踪:

Uncaught TypeError: eltOrSelector.querySelectorAll is not a function
    at findAll (htmx.js:295)
    at handleOutOfBandSwaps (htmx.js:501)
    at selectAndSwap (htmx.js:712)
    at doSwap (htmx.js:2284)
    at handleAjaxResponse (htmx.js:2358)
    at XMLHttpRequest.xhr.onload (htmx.js:2163)

更新

我可以将问题缩小到这个:

开发工具

这失败了:

makeFragment('<tr><td>a</td></tr> <div>X</div>')

更新2

嗯,现在我知道它为什么失败了:

制作片段

parseFromString()Chrome的根本原因是:

parseFromString

更新3

后续问题:Make parseFromString() 解析而不验证

更新4

我创建了一个问题,希望有更多创造力的人知道如何解决这个问题:https ://github.com/bigskysoftware/htmx/issues/469

4

1 回答 1

0

我创建了一个新端点,它返回一个稍微不同的 HTML 片段:

<table>
 <tr id="row1">
  <td>2</td><td>two</td>
 </tr>
</table>

<div id="sum" hx-swap-oob="true">MAGIC</div>

<script src="https://unpkg.com/htmx.org@1.3.3/dist/htmx.js"></script>
<div id="sum">?</div>
before table
<table>
 <tr id="row1">
  <td><button 
   hx-get="https://run.mocky.io/v3/28a8e653-491c-4186-abd4-4f48f3579273"
   hx-target="#row1" hx-select="#row1">1</button>
  </td>
  <td>one</td>
 </tr>
</table>
after table

HTMX 在内部使用parseFromString(),这个方法验证输入。如果存在无效的 HTML,它可能会截断元素。

makeFragment()的 HTMX 包装它发送到的字符串parseFromString()。HTMX 查看响应中的第一个元素。在上面的问题中是<tr>。因此 htmx 用于<table>包装整个 http 响应。

制作片段()

解决方案是将“正常”元素返回给 htmx(不是<tr>)。

htmx 中的普通 html 片段正好是一个元素,所以没关系。如果您使用hx-swap-oob服务器向客户端发送几个元素。

这或多或少是一种解决方法。如果 htmx 能够处理原始字符串,那就太好了。

于 2021-04-29T11:00:40.610 回答