html 富文本编辑器相关--向编辑器内部插入文字图片等各种dom元素 通用方法

有问题的插入方案

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>#edit{height:500px;width:500px;border:1px solid red;}</style>
</head>
<body>
<div id="edit" contenteditable></div>
<input type="text" id="emojiInput">
<button id="sendEmoji">发送表情</button>

<script>
    var sendEmoji = document.getElementById(‘sendEmoji‘)

    // 定义最后光标对象
    var lastEditRange;

    // 编辑框点击事件
    document.getElementById(‘edit‘).onclick = function() {
        // 获取选定对象
        var selection = getSelection()
        // 设置最后光标对象
        lastEditRange = selection.getRangeAt(0)
    }

    // 编辑框按键弹起事件
    document.getElementById(‘edit‘).onkeyup = function() {
        // 获取选定对象
        var selection = getSelection()
        // 设置最后光标对象
        lastEditRange = selection.getRangeAt(0)
    }

    // 表情点击事件
    document.getElementById(‘sendEmoji‘).onclick = function() {
        // 获取编辑框对象
        var edit = document.getElementById(‘edit‘)
        // 获取输入框对象
        var emojiInput = document.getElementById(‘emojiInput‘)
        // 编辑框设置焦点
        edit.focus()
        // 获取选定对象
        var selection = getSelection()
        // 判断是否有最后光标对象存在
        if (lastEditRange) {
            // 存在最后光标对象,选定对象清除所有光标并添加最后光标还原之前的状态
            selection.removeAllRanges()
            selection.addRange(lastEditRange)
        }
        // 判断选定对象范围是编辑框还是文本节点
        if (selection.anchorNode.nodeName != ‘#text‘) {
            // 如果是编辑框范围。则创建表情文本节点进行插入
            var emojiText = document.createTextNode(emojiInput.value)

            if (edit.childNodes.length > 0) {
                // 如果文本框的子元素大于0,则表示有其他元素,则按照位置插入表情节点
                for (var i = 0; i < edit.childNodes.length; i++) {
                    if (i == selection.anchorOffset) {
                        edit.insertBefore(emojiText, edit.childNodes[i])
                    }
                }
            } else {
                // 否则直接插入一个表情元素
                edit.appendChild(emojiText)
            }
            // 创建新的光标对象
            var range = document.createRange()
            // 光标对象的范围界定为新建的表情节点
            range.selectNodeContents(emojiText)
            // 光标位置定位在表情节点的最大长度
            range.setStart(emojiText, emojiText.length)
            // 使光标开始和光标结束重叠
            range.collapse(true)
            // 清除选定对象的所有光标对象
            selection.removeAllRanges()
            // 插入新的光标对象
            selection.addRange(range)
        } else {
            //debugger;
            // 如果是文本节点则先获取光标对象
            var range = selection.getRangeAt(0)
            // 获取光标对象的范围界定对象,一般就是textNode对象
            var textNode = range.startContainer;
            // 获取光标位置
            var rangeStartOffset = range.startOffset;
            // 文本节点在光标位置处插入新的表情内容
            textNode.insertData(rangeStartOffset, emojiInput.value)
            // 光标移动到到原来的位置加上新内容的长度
            range.setStart(textNode, rangeStartOffset + emojiInput.value.length)
            // 光标开始和光标结束重叠
            range.collapse(true)
            // 清除选定对象的所有光标对象
            selection.removeAllRanges()
            // 插入新的光标对象
            selection.addRange(range)
        }
        // 无论如何都要记录最后光标对象
        lastEditRange = selection.getRangeAt(0)
    }
</script>
</body>
</html>

插入时 应该考虑的问题,

第一 原来容器内 有文本内容,现在在文本内容中间插入dom元素, 以上方法未解决,

第二 插入后定位到新插入的元素的位置

ok的方案

/**
 * 在输入区插入各种东东通用
 * @param html
 */
function insertImg(html) {
    var dthis = $("#input-content")[0];
    var sel = getSelection();
    if (window.getSelection) {
        // IE9 and non-IE
        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‘) {
        $(dthis).focus(); // 在非标准浏览器中 要先让你需要插入html的div 获得焦点
        ierange = document.selection.createRange();// 获取光标位置
        ierange.pasteHTML(html); // 在光标位置插入html 如果只是插入text 则就是fus.text="..."
        $(dthis).focus();
    }
}
时间: 2024-08-05 15:25:23

html 富文本编辑器相关--向编辑器内部插入文字图片等各种dom元素 通用方法的相关文章

selenium 关于富文本的处理

由于项目需要,涉及到富文本的处理.百度了下,发现已经有人总结的很全了. 大概思路如下: 1.switch_to_frame 2.find_element_by_tag_name('body').send_keys("123") 链接:http://blog.csdn.net/huilan_same/article/details/52386274 一般输入框有三种: 短的input框,如下: <input id="zenInput2" class="

富文本使用之wangEditor3

一.介绍: wangEditor -- 轻量级 web 富文本编辑器,配置方便,使用简单.支持 IE10+ 浏览器. 二.使用方式: 直接下载:https://github.com/wangfupeng1988/wangEditor/releases 使用npm下载:npm install wangeditor (注意 wangeditor 全部是小写字母) 使用bower下载:bower install wangEditor (前提保证电脑已安装了bower) 使用CDN://unpkg.co

[开发总结]富文本前端框架对比分析

[排序不分先后,只是标记数量] 1. 如果你想直接引入,完全不定制,扔进项目就直接用 CKEditor TinyMCE Froala Quill Summernote(框架不太友善) Trix 2. 想有非常高度的定制 可以看看 Slate.js,它基于 React.js. 用了 Slate.js 的知名产品有 Taskade,Taskade 的编辑器非常漂亮而且格式很多. 如果想开发和 Taskade 一样的编辑器,我觉得用如上里任何一个现成编辑器都是很难开发出来的(甚至不可能,因为要改动那么

富文本常用封装(NSAttributedString浅析)

最近经常遇到关于富文本的一些需求,特此封装了几个最常用的API分享给大家,但授之以鱼不如授之以渔,接下来会顺便谈谈NSAttributedString,确保你读了本篇文章能够自己封装关于富文本的API,本文封装API的示例Demo再此,拿去用吧!骚年们! 一.常用需求封装 需求:在我们日常开发中,某些句子中会有改变某些字颜色的需求,当然颜色一般而言就是为了着重强调,常为同一种颜色,所以下面代码是单纯改变一句话中的某些字的颜色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

富文本常用封装(NSAttributedString)

最近经常遇到关于富文本的一些需求,特此封装了几个最常用的API分享给大家,但授之以鱼不如授之以渔,接下来会顺便谈谈NSAttributedString,确保你读了本篇文章能够自己封装关于富文本的API,本文封装API的示例Demo再此,拿去用吧!骚年们! 一.常用需求封装 需求:在我们日常开发中,某些句子中会有改变某些字颜色的需求,当然颜色一般而言就是为了着重强调,常为同一种颜色,所以下面代码是单纯改变一句话中的某些字的颜色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

iOS之富文本

之前做项目时遇到一个问题: 使用UITextView显示一段电影的简介,由于字数比较多,所以字体设置的很小,行间距和段间距也很小,一大段文字挤在一起看起来很别扭,想要把行间距调大,结果在XCode中查遍其所有属性才发现,UITextView居然没有调整行间距的接口,于是忍住不心里抱怨了一下下. 但是问题还是要解决的,上网一查才发现,iOS不仅有富文本处理的功能,而且对于文字排版的处理能力那是相当的强大,看来我是孤陋寡闻了. 正题开始之前插播一点基础知识: 在iOS中或者Mac OS X中怎样才能

iOS之富文本(二)

之前做项目时遇到一个问题: 使用UITextView显示一段电影的简介,由于字数比较多,所以字体设置的很小,行间距和段间距也很小,一大段文字挤在一起看起来很别扭,想要把行间距调大,结果在XCode中查遍其所有属性才发现,UITextView居然没有调整行间距的接口,于是忍住不心里抱怨了一下下. 但是问题还是要解决的,上网一查才发现,iOS不仅有富文本处理的功能,而且对于文字排版的处理能力那是相当的强大,看来我是孤陋寡闻了. 正题开始之前插播一点基础知识: 在iOS中或者Mac OS X中怎样才能

ios富文本

之前做项目时遇到一个问题: 使用UITextView显示一段电影的简介,由于字数比较多,所以字体设置的很小,行间距和段间距也很小,一大段文字挤在一起看起来很别扭,想要把行间距调大,结果在XCode中查遍其所有属性才发现,UITextView居然没有调整行间距的接口,于是忍住不心里抱怨了一下下. 但是问题还是要解决的,上网一查才发现,iOS不仅有富文本处理的功能,而且对于文字排版的处理能力那是相当的强大,看来我是孤陋寡闻了. 正题开始之前插播一点基础知识: 在iOS中或者Mac OS X中怎样才能

Android检测富文本中的&lt;img标签并实现点击效果

本文旨在:通过点击一张图片Toast输出位置与url链接. 闲话少说,实现原理大概是酱紫的::通过正则表达式检测富文本内的图片集合并获取url,在src=“xxx” 后面添加 onclick方法,至于js如何load进去本人是自己拼接了一个html标签的上下文 js调用java方法请自行搜索不在本文讨论范围. public class HtmlUtils { /** * 获取html中的所有图片 * @param compatText * @return */ public static Lis