让contenteditable字段将新字符包装在单独的元素中在Firefox中...

问题描述

我正在制作一个展示字体的网站。该网站的一部分是让用户在文本字段中输入内容,以便他们可以更好地使用它。字体具有一些特殊功能,要求我能够将单个字符包装在单独的元素中(为此我选择了<i></i>)。然后,使用CSS我将为这些元素启用一些OpenType功能。重要的是要知道我不想在同一元素中使用多个字符。

我设法创建了一个可行的解决方案,但是目前我最大的问题是使其在Firefox和Chrome中都可以使用。我在Chrome中运行的代码

  const config = {
    attributes: true,childList: true,subtree: true,characterData: true,characterDataOldValue: true,attributeFilter: ['style'],}

  // Callback function to execute when mutations are observed
  const callback = function (mutationsList,observer) {
    observer.disconnect()
    observer.takeRecords()

    for (const mutation of mutationsList) {
      if (mutation.type === 'characterData') {
        if (mutation.target.parentElement && mutation.target.parentElement.tagName === 'I') {
          const change = mutation.target.nodeValue.replace(mutation.oldValue,'')
          mutation.target.parentElement.insertAdjacentHTML('afterend',`<i>${change}</i>`)
          mutation.target.nodeValue = mutation.oldValue
          const range = document.createrange()
          const sel = window.getSelection()
          const rangeEl = mutation.target.parentElement.nextSibling
          range.setStart(rangeEl,1)
          range.collapse(true)
          sel.removeAllRanges()
          sel.addRange(range)
        }
      } else if (mutation.type === 'childList' && mutation.addednodes.length > 0) {
        // remove spans that are somehow added by the browser
        const spans = Array.from(mutation.addednodes).filter((node) => node.tagName === 'SPAN')
        spans.forEach((span) => (span.outerHTML = span.innerHTML))
      } else if (mutation.type === 'attributes' && mutation.target !== textarea) {
        mutation.target.removeAttribute('style')
      }
    }

    observer.observe(textarea,config)
  }

  const observer = new MutationObserver(callback)
  observer.observe(textarea,config)

因此,我正在听contenteditable字段的更改,并检查是否在<i/>元素中添加了任何字符。如果是这种情况,我将该元素重置为其先前的值,然后在其后创建一个新元素。最后一部分是尝试保留插入符号/光标位置。

这一切都让人感觉很hacky,这也许不是最好的方法。因此,我想知道将每个新键入的字符包装到在最新浏览器中可用的<i></i>元素中的最佳方法是什么。

我在此处制作了一个示例页面https://jsbin.com/baguhu/edit?js,output

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)