Contenteditable 显示最后插入的 html 元素

2024-05-03

我使用 contenteditable div 作为输入字段来输入一些文本,并通过该文本中的按钮(小 html 图片)插入图标。

只要文本比 contenteditable 字段窄,就可以了。

一旦文本比字段长(因此它被部分隐藏):

当我输入文本字符时,这也很好,按下按键后会自动显示最后一个字符,以便您始终可以看到您正在输入的内容。 但是,当我通过按钮输入图标时,该图标就在那里,但它是隐藏的,因为字段内容不会移动以使新输入的图标可见,直到我输入另一个文本字符。

有什么解决方案可以让用户始终看到最后输入的元素(文本或 html)吗?

function pasteIcon(html) {
  var sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
      range = sel.getRangeAt(0);
      range.deleteContents();
      var el = document.createElement("div");
      el.innerHTML = html;
      var frag = document.createDocumentFragment(),
        node, lastNode;
      while ((node = el.firstChild)) {
        lastNode = frag.appendChild(node);
      }
      range.insertNode(frag);
      if (lastNode) {
        range = range.cloneRange();
        range.setStartAfter(lastNode);
        range.collapse(true);
        sel.removeAllRanges();
        sel.addRange(range);
      }
    }
  } else if (document.selection && document.selection.type != "Control") {
    document.selection.createRange().pasteIcon(html);
  }
}

$(document).ready(function() {
  $('.buttOn').click(function() {
    $('.contEd').focus();
    pasteIcon('<img class="icOn" src="http://www.bmgstuff.com/files/interface/generator_frame/text_blood.png">');
  })
});
[contenteditable="true"] {
  display: inline;
  white-space: nowrap;
  overflow: hidden !important;
  text-overflow: inherit;
  -webkit-user-select: text !important;
  -moz-user-select: text !important;
  -ms-user-select: text !important;
  user-select: text !important;
}

[contenteditable="true"] br {
  display: none;
}

.contAiner {
  display: flex;
}

.buttOn {
  width: 24px;
  height: 24px;
  border: none;
  background: #666;
  color: white;
}

.contEd {
  height: 22px;
  text-align: center;
  width: 100px;
  line-height: 23px;
  color: black;
  font-size: 10.5px;
  font-family: arial;
  border: 1px solid black;
}

.icOn {
  width: 9px;
  height: 13px;
  top: 1px;
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="contAiner">
  <input class="buttOn" type="button" value="B">
  <div class="contEd" contenteditable="true" spellcheck="false" autocomplete="off"></div>
</div>

这里是jsFiddle https://jsfiddle.net/n03hcrnh/36/

这是我从中获取了“pasteIcon”函数。

PS:我尝试在 PasteIcon 函数之后触发键码 39(右箭头)以模拟按键,但它不起作用。


您只需将编辑器滚动到插入的图标即可。请注意移动选择后的两行代码。希望它能按您的预期工作:)

UPDATE:

为了涵盖所有情况,我们需要检查插入的图像是否在编辑器范围之内或之外。 首先,我们将 id 添加到编辑器元素中,这样会更容易。然后我们可以利用函数 getBoundingClientRect 返回屏幕上实际元素的矩形。最后,我们比较矩形,如果图像矩形不在编辑器内 (imgRect.left editorRect.right),则我们滚动。

更新2:

在调查最新评论中描述的问题期间,我发现在编辑一定长度的内容后,jQuery 函数“offset”返回不准确的结果。最有可能的是,这是因为在这种情况下编辑器的 leftOffset 不会自动更新。 最后,我将所需的滚动位置计算更改为图像 DOM 元素的 offsetLeft 减去编辑器元素的 offsetLeft 减去 1(边框大小),现在它适用于任何内容长度。

function pasteIcon(html) {
  var sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
      range = sel.getRangeAt(0);
      range.deleteContents();
      var el = document.createElement("div");
      el.innerHTML = html;
      var frag = document.createDocumentFragment(),
        node, lastNode;
      while ((node = el.firstChild)) {
        lastNode = frag.appendChild(node);
      }
      range.insertNode(frag);
      if (lastNode) {
        range = range.cloneRange();
        range.setStartAfter(lastNode);
        range.collapse(true);
        sel.removeAllRanges();
        sel.addRange(range);

   	    var editorRect = $(contEdit)[0].getBoundingClientRect();
       	var imgRect = $(lastNode)[0].getBoundingClientRect();
       	if (imgRect.left < editorRect.left || imgRect.right > editorRect.right) {
          var actualLeft = $(lastNode)[0].offsetLeft - editorRect.left - 1;
          $(".contEd").scrollLeft(actualLeft);
        }
      }
    }
  } else if (document.selection && document.selection.type != "Control") {
    document.selection.createRange().pasteIcon(html);
  }
}

$(document).ready(function() {
  $('.buttOn').click(function() {
    $('.contEd').focus();
    pasteIcon('<img class="icOn" src="http://www.bmgstuff.com/files/interface/generator_frame/text_blood.png">');
  })
});
[contenteditable="true"] {
  display: inline;
  white-space: nowrap;
  overflow: hidden !important;
  text-overflow: inherit;
  -webkit-user-select: text !important;
  -moz-user-select: text !important;
  -ms-user-select: text !important;
  user-select: text !important;
}

[contenteditable="true"] br {
  display: none;
}

.contAiner {
  display: flex;
}

.buttOn {
  width: 24px;
  height: 24px;
  border: none;
  background: #666;
  color: white;
}

.contEd {
  height: 22px;
  text-align: center;
  width: 100px;
  line-height: 23px;
  color: black;
  font-size: 10.5px;
  font-family: arial;
  border: 1px solid black;
}

.icOn {
  width: 9px;
  height: 13px;
  top: 1px;
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="contAiner">
  <input class="buttOn" type="button" value="B">
  <div id="contEdit" class="contEd" contenteditable="true" spellcheck="false" autocomplete="off"></div>
</div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Contenteditable 显示最后插入的 html 元素 的相关文章

随机推荐

  • 使用 gevent 在应用程序上下文之外工作的 Flask 蓝图

    我正在尝试通过 Flask mail 使用 gevent 在 Flask 中异步发送电子邮件 我正在 在应用程序上下文之外工作 我知道 app app context 但我无法让它与我的设置一起使用 我的应用程序是使用这样的应用程序工厂创建
  • Flutter:酒吧失败

    Flutter 项目向我显示警告 Packages get has not been run以及建议的解决方案 获取依赖项 升级依赖项 Ignore 正如建议的Darky https stackoverflow com users 8394
  • PHP 正则表达式修复被黑的 WordPress 网站

    我有一个客户安装了多个 WordPress 但他没有保持最新状态 结果 他被黑了 当我试图找出黑客是如何进入并永久解决问题时 我正在尝试创建一个脚本来快速 自动地修复它们 我找到了这个脚本 它可以满足我的要求 http designpx c
  • Yml配置文件与Spring boot的“继承”

    我在网上找不到直接答案 Spring Boot 的 yml 文件是否相互 继承 我的意思是如果我有 application yml其中有 server port 80 host foo and application profile1 ym
  • 在 HTTPS 而不是 HTTP 中启动 React 应用程序

    我想知道如何启动一个使用 https 而不是 HTTP 中的 create react app 命令制作的 React 应用程序 使用根 SSL 证书之类的东西 生成密钥 openssl genrsa des3 out rootCA key
  • 在 C# 中使用逗号和小数格式化数字

    我需要显示一个带有逗号和小数点的数字 例如 情况 1 十进制数是 432324 没有逗号或小数点 需要将其显示为 432 324 00 不 432 324 情况 2 十进制数是 2222222 22 没有逗号 需要将其显示为 2 222 2
  • 用 Chronos 取代 Celerybeat

    成熟到什么程度Chronos http airbnb github io chronos 它是像 celery beat 这样的调度程序的可行替代品吗 现在 我们的调度实现了一个定期的 心跳 任务 该任务检查 未完成的 事件 并在过期时触发
  • 无法锚定到不是父级或同级 QML QtQuick 的项目

    我正在使用 QML 开发 python 桌面应用程序 我的 QML 文件中有这个 SplitView anchors fill parent orientation Qt Horizontal Rectangle color 272822
  • 如何查找 DICOM 研究中的图像数量?

    是否可以通过读取该研究中文件的 DICOM 标头来查找 DICOM 研究中的图像数量 我正在开发一个 Java 应用程序 该应用程序接收来自不同来源的 DICOM 研究 我只是想检查是否已完全收到研究 不幸的是 我不能依赖阅读 DICOMD
  • 如何在 Node CLI 程序中使用 babel?

    我正在 Node 中编写一个小型 CLI 工具 并希望使用 ES6 来实现 index js 看起来像 usr bin env node require babel register module exports require app 我
  • 如何创建一个自定义中继器,根据属性显示页眉、页脚?

    我想创建一个根据属性显示页眉 页脚的中继器 仅当DataSource是空的 public class Repeater System Web UI WebControls Repeater public bool ShowHeaderOnE
  • 由于对象的当前状态,操作无效 - Linq on List

    对列表运行 Linq 查询时会引发此错误 我使用 Unity3D 3 0 和 C Unity3D 使用 Mono 2 6 据我所知 Unity3D是单线程的 它的工作原理是将继承基类的 脚本 c cs 文件 附加到 GameObject 此
  • 在 vim 中,+register 和 +register 与 .命令?

    我很难理解这个问题的解决方案维姆高尔夫挑战赛 http vimgolf com challenges 5192f96ad8df110002000002 最好的建议解决方案是 cw
  • Phonegap 之类的 Mac App Store 平台? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在使用phonegap 在iOS 本机应用程序中运行我的HTML JS 代码 有没有办法在 Mac
  • 线程终止时的 Java ExecutorService 回调

    我正在使用缓存线程池 ExecutorService 来运行一些异步后台任务 我提供了 ThreadFactory 它将线程分发给 ExecutorService 只要需要它们 我对缓存线程池的理解是 线程空闲 60 秒后 它会被 Exec
  • 如何在速度模板中显示图像

    如何在速度模板中显示此图像 显示图像需要什么配置吗 我有速度的java 配置 请帮我 提前致谢 非常感谢glw的热心回复 问题已经解决了 我忘记了电子邮件模板仅采用部署的实时图像路径 而不是像 src pageContext request
  • 嵌套列表的非递归遍历——在Python中构建类似的嵌套列表

    我需要遍历一个嵌套列表 处理每个非列表项str 并返回保持结构的类似列表 使用递归 这会相当容易 但我需要以这种迭代的方式进行 下面是我的尝试while loop def myiter e a e initial list c final
  • 是否可以在 .Net Windows 表单内托管 Microsoft Access 表单?

    我问是否可以在 Net 表单中托管 Microsoft Access 表单 不 我没有发疯 我们正在维护一个完全用 VBA 编写的庞大系统 由一个不太了解 VBA 的人尝试使用 Microsoft Access 作为 IDE 它基本上是数千
  • 媒体查询:根据屏幕尺寸限制一些CSS样式

    当我在layout css中编写一些样式时 它适用于每个屏幕尺寸和 Media Queries 部分 您有以下部分 Smaller than standard 960 devices and browsers Tablet Portrait
  • Contenteditable 显示最后插入的 html 元素

    我使用 contenteditable div 作为输入字段来输入一些文本 并通过该文本中的按钮 小 html 图片 插入图标 只要文本比 contenteditable 字段窄 就可以了 一旦文本比字段长 因此它被部分隐藏 当我输入文本字