insertAdjacentHTML 为函数显示 [object, Object]

Posted

技术标签:

【中文标题】insertAdjacentHTML 为函数显示 [object, Object]【英文标题】:insertAdjacentHTML displaying [object, Object] for Functions 【发布时间】:2020-04-08 05:59:10 【问题描述】:

下面有一些 JSX 在 firstComment 元素之前注入到 DOM 中。

里面有几个简单地返回 svgs 的函数。当浏览器运行thumbsUp()thumbsDown()函数时,它们会显示为[object Object][object Object]

如何在不直接用 svg 替换函数的情况下使此代码正常工作?如果需要,我愿意使用与 insertAdjacenthtml 不同的方法。

const postComment = (inputValue) =>

  const d1 = document.getElementById('firstComment')
  d1.insertAdjacentHTML('beforebegin',
    ` 
      <div>
        <div class="comment-avatar"></div>
          <div class="comment-container">
            <h5 class="commentorName">Guest</h5>
            <div class="dateOfComment">Just Now</div>
            <p class="comment">$inputValue</p>
            <div class="thumbs">
              <span class="thumbsUpIcon">
                $thumbsUp(16)
              </span>
              <span class="thumbsDownIcon">
                $thumbsDown(16)
              </span>
            </div>
            <p class="replyText">REPLY</p>
          </div>
      </div>
    `
  )

功能

const thumbsUp = (width) => 
  return (
    <svg width=width xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M198 448h172c15.7 0 28.6-9.6 34.2-23.4l57.1-135.4c1.7-4.4 2.6-9 2.6-14v-38.6c0-21.1-17-44.6-37.8-44.6H306.9l18-81.5.6-6c0-7.9-3.2-15.1-8.3-20.3L297 64 171 191.3c-6.8 6.9-11 16.5-11 27.1v192c0 21.1 17.2 37.6 38 37.6zM48 224h64v224H48z"/></svg>
    ) 


const thumbsDown = (width) => 
    return (
      <svg width=width xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M314 64H142c-15.7 0-28.6 9.6-34.2 23.4L50.6 222.8c-1.7 4.4-2.6 9-2.6 14v38.6c0 21.1 17 44.6 37.8 44.6h119.3l-18 81.5-.6 6c0 7.9 3.2 15.1 8.3 20.3l20 20.1L341 320.7c6.8-6.9 11-16.5 11-27.1v-192c0-21.1-17.2-37.6-38-37.6zM400 64h64v224h-64z"/></svg>
      ) 
  

【问题讨论】:

您能否在您的问题中也发布thumbsUp 函数和thumbsDown 函数。 当然。但这就像我说的那样。他们所做的就是返回 svg。我在应用程序的许多地方都使用了它们,因此该功能可以按预期工作。 如果你把返回的 SVG 代码变成一个字符串,这样行吗?例如:const thumbsUp = (width) =&gt; return '&lt;svg&gt;&lt;/svg&gt;'. @JustinFeakes 这行得通,但是在我要导入该函数的所有其他区域中破坏了我的代码。 嗯,您在哪里调用 $thumbsUp(16),您可以将其转换为字符串并保持函数不变吗?例如$thumbsUp(16).toString() 【参考方案1】:

可以通过在 thumbs 函数中使用两个单独的返回并使用一个参数作为检查来解决(不破坏导入 svgs 的其他代码部分)。将 insert 设置为 true 会将 svg 作为字符串返回,并且在函数调用中排除参数会返回正常的 svg。

不确定它是否最佳,但它有效。

const thumbsDown = (width, insert) => 
  if (insert) 
    return (
      `<svg width=$width xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M314 64H142c-15.7 0-28.6 9.6-34.2 23.4L50.6 222.8c-1.7 4.4-2.6 9-2.6 14v38.6c0 21.1 17 44.6 37.8 44.6h119.3l-18 81.5-.6 6c0 7.9 3.2 15.1 8.3 20.3l20 20.1L341 320.7c6.8-6.9 11-16.5 11-27.1v-192c0-21.1-17.2-37.6-38-37.6zM400 64h64v224h-64z"/></svg>`
    ) 
   
    return (
      <svg width=width xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M314 64H142c-15.7 0-28.6 9.6-34.2 23.4L50.6 222.8c-1.7 4.4-2.6 9-2.6 14v38.6c0 21.1 17 44.6 37.8 44.6h119.3l-18 81.5-.6 6c0 7.9 3.2 15.1 8.3 20.3l20 20.1L341 320.7c6.8-6.9 11-16.5 11-27.1v-192c0-21.1-17.2-37.6-38-37.6zM400 64h64v224h-64z"/></svg>
    )
  

【讨论】:

【参考方案2】:

如果您将 thumbsUp/thumbsDown 函数返回的 svg 代码包装在反引号中,使其成为模板文字,它似乎会返回您期望的 svg。我没有得到您描述的 [object Object] 结果,但是如果没有它们,这些函数无法在 sn-p 编辑器中为我正确返回 svg。

const postComment = (inputValue) =>

  const d1 = document.getElementById('firstComment')
  d1.insertAdjacentHTML('beforebegin',
    ` 
      <div>
        <div class="comment-avatar"></div>
          <div class="comment-container">
            <h5 class="commentorName">Guest</h5>
            <div class="dateOfComment">Just Now</div>
            <p class="comment">$inputValue</p>
            <div class="thumbs">
              <span class="thumbsUpIcon">
                $thumbsUp(16)
              </span>
              <span class="thumbsDownIcon">
                $thumbsDown(16)
              </span>
            </div>
            <p class="replyText">REPLY</p>
          </div>
      </div>
    `
  )


const thumbsUp = (width) => 
  return (
    `<svg width=$width xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M198 448h172c15.7 0 28.6-9.6 34.2-23.4l57.1-135.4c1.7-4.4 2.6-9 2.6-14v-38.6c0-21.1-17-44.6-37.8-44.6H306.9l18-81.5.6-6c0-7.9-3.2-15.1-8.3-20.3L297 64 171 191.3c-6.8 6.9-11 16.5-11 27.1v192c0 21.1 17.2 37.6 38 37.6zM48 224h64v224H48z"/></svg>`
    ) 


const thumbsDown = (width) => 
    return (
      `<svg width=$width xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M314 64H142c-15.7 0-28.6 9.6-34.2 23.4L50.6 222.8c-1.7 4.4-2.6 9-2.6 14v38.6c0 21.1 17 44.6 37.8 44.6h119.3l-18 81.5-.6 6c0 7.9 3.2 15.1 8.3 20.3l20 20.1L341 320.7c6.8-6.9 11-16.5 11-27.1v-192c0-21.1-17.2-37.6-38-37.6zM400 64h64v224h-64z"/></svg>`
      ) 


postComment('hello whirled')
&lt;div id='firstComment'&gt;&lt;/div&gt;

【讨论】:

是的,这确实有效,但也会破坏我导入拇指 svgs 的代码中的所有其他区域。 您的代码在调用可变宽度 svg 函数的其他地方有何不同? 代码的其他地方没有插入任何html。该函数最初只是为了替换长 svg 文本,使我的 react 组件更具可读性。所以不同的是,在这种情况下,我在一些 html 中调用 thumbs 函数来插入。 啊,从 React 组件的 render 方法内部调用这些函数的解释与将它们插入使用 vanilla JS 的解释不同。如果没有看到你所有的代码,我无法判断,但我想知道为什么你不能使用 React 的 API 而不是 insertAdjacentHTML 产生相同的行为。如果您向我们展示您的 React 组件,也许我们可以找到类似的解决方案。否则,您的两次返回答案似乎是一个不错的选择【参考方案3】:

您可以使用createElement() 方法创建一个div 元素,然后使用innerHTML() 属性将您的html 内容推送到该div。您现在可以使用insertAdjacentElement() 方法在您的firstComment 元素上呈现您的HTML。


运行以下代码片段,或者您可以查看此JSFiddle以获取上述方法的实际示例:

/* javascript */
let div = document.getElementById("firstComment");

const thumbsUp = (width) => 
	return `<svg width=$width xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M198 448h172c15.7 0 28.6-9.6 34.2-23.4l57.1-135.4c1.7-4.4 2.6-9 2.6-14v-38.6c0-21.1-17-44.6-37.8-44.6H306.9l18-81.5.6-6c0-7.9-3.2-15.1-8.3-20.3L297 64 171 191.3c-6.8 6.9-11 16.5-11 27.1v192c0 21.1 17.2 37.6 38 37.6zM48 224h64v224H48z"/></svg>`

const thumbsDown = (width) => 
	return `<svg width=$width xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M314 64H142c-15.7 0-28.6 9.6-34.2 23.4L50.6 222.8c-1.7 4.4-2.6 9-2.6 14v38.6c0 21.1 17 44.6 37.8 44.6h119.3l-18 81.5-.6 6c0 7.9 3.2 15.1 8.3 20.3l20 20.1L341 320.7c6.8-6.9 11-16.5 11-27.1v-192c0-21.1-17.2-37.6-38-37.6zM400 64h64v224h-64z"/></svg>`


const htmlContent = document.createElement("div");
htmlContent.innerHTML = `
  	<div class="comment-avatar"></div>
  	<div class="comment-container">
  		<h5 class="commentorName">Guest</h5>
  		<div class="dateOfComment">Just Now</div>
  		<p class="comment">SomeValue</p>
  		<div class="thumbs">
  			<span class="thumbsUpIcon">
  				$thumbsUp(16)
  			</span>
  			<span class="thumbsDownIcon">
  				$thumbsDown(16)
  			</span>
  		</div>
  		<p class="replyText">REPLY</p>
  	</div>
`;

div.insertAdjacentElement("beforebegin", htmlContent);
/* CSS */
html, body width: 100%; height: 100%; margin: 0; padding: 0;
<!-- HTML -->
<div id="firstComment"></div>

【讨论】:

以上是关于insertAdjacentHTML 为函数显示 [object, Object]的主要内容,如果未能解决你的问题,请参考以下文章

insertAdjacentHTML 不是函数

Element.insertAdjacentHTML() API 在 chrome 55.0.2883.87 中引发错误

全栈JavaScript之路( 二十 )HTML5 插入 html标记 ( 二 )insertAdjacentHTML

insertAdjacentHTML方法详解

markdown insertAdjacentHTML

原生js添加节点的高级简便写法