原生JS写一个功能强大的编辑器

因为一个同学,要做一个能加入图片的留言板功能,类型与QQ空间留言板和百度贴吧发帖的那种形式,同时在网上找了找发生网上对这方面的交流很少,所以发表这篇文章抛砖引玉,希望能帮助广大的学习者,也同时希望大佬能对此文章及本人写的代码,不吝赐教。
主要采用了原生JS与调用Selection API结合html的contentible功能实现功能。

1.先来看看效果
《原生JS写一个功能强大的编辑器》
2.主要功能

1.在当前光标位置添加指定图片,并=点击以后修改图片大小
2.修改选中文字的大小,字体颜色及添加斜体、粗体、下划线

3.代码及一些难点部分
首先看一个很很很关键和重要的函数

function getSelectionRange() { 
    var select;
    //兼容处理
    if (window.getSelection) { 
        select = window.getSelection();
           range = select.getRangeAt(0);//获取selection对象,并获取range对象
    } else if (document.selection) { 
        //IE浏览器
        range = document.selection.createRange();//IE可以直接获取
    };
};

这个函数是调用seleciton API并用range保存当前光标位置,方便后面插入图片和给代码修改文字样式

其次另外一个也很关键的函数是

//插入节点
function insert(newNode){
    var fragNode = document.createDocumentFragment().appendChild(newNode);//创建文档碎片并放入新节点
    range.deleteContents();//删除Rnge中的内容
    range.insertNode(fragNode);//再插入新碎片
}

这个函数接收一个新的也就是要插入节点的形参,然后删除当前位置的内容(如果选中的是文字这把当前这选中的文字删除掉)最后把新创建的节点插入到光标的位置。

我们在来看看另外一个难点部分,就是获取选中的文字,,这里我采用的是鼠标的监听事件,mousedown->mousemove->mouseup,分别的监听,来判断是否鼠标发生移动,及得到鼠标选中的文本

//获取选中的字符
edit.addEventListener("click",function(){
    getSelectionRange();//获取Range
});
edit.addEventListener("mousedown",function(){
    edit.addEventListener("mousemove",listenMove);
});
function listenMove(){
    moved=true;
};
edit.addEventListener("mouseup",function(){
    if(!moved){
        return;
    }
    //当有选中内容才进行操作
    edit.removeEventListener("mousemove",listenMove);
    getSelectionRange();
    selectTxt= range.toString();//将选择的内容从对象中提取出来,直接转字符串就行了。
    moved = false;
});

先在mousedown函数里面获取一次range,然后在mouseup的函数里面再次获取range得到选中的文字用selectTxt保存,这里在我看来只要是理清楚思路这里很好理解。
到了这里我们就已经把几个比较困难的问题解决了,剩下的插入文字和图片及改变图片的大小,都是很简单的基本操作。
我以插入图片为例,大家可以拿到代码以后自己理一理插入文字的思路:

//插入图片
var imgSrc='';
aInsertBtn[0].onclick=function(){
    var txt=document.getElementById('txtImg');
    //如果同时存在本地上传图片和网络图片的地址,只插入网络图片
    console.log(txt.value)
    if(txt.value){
        imgSrc=txt.value;
        txt.value=" ";
    }
    addImg(imgSrc);
    insertImg.style.display="none";
}
function fileChange(){
    var val=this.value.toLowerCase().split('.');
    if(val){
        if(val[1]=='gif'||val[1]=='png'||val[1]=='jpg'||val[1]=='jpeg'){
            var reader = new FileReader();
                reader.onload = function (e) {
                imgSrc = e.target.result;                
            }
            reader.readAsDataURL(this.files[0]);
        }else{
            alert("目前支持gif,png,jpg,jpeg格式的图片!")
        }
    }
}
function addImg(src){
    var newImg=new Image();
    newImg.className="insertNewImg";
    newImg.src=src;
    insert(newImg);
}

这里需特别的说明一下,如果是插入的是本地图片,由于浏览器为了安全限制file.value并不是图片的真实地址,换句话说img.src=file.value是得不到图片的,所以这里我们需要借用FileReader对象来得到真实的图片地址,当然这里网络的图片地址肯定是可以直接用的,然后将的到的src地址传入addImg函数生成img节点以后插入当前光标指向的文本位置。
所以添加文本样式也是一样的方法,无非就是在创建完文本节点以后给他添加style样式。

所以根据这种方法,读者可以根据自己的需求添加更多的功能,比如:在编辑框里面插入一个可以点击的a标签或者添加一个代码块…..

希望能读到此文章的读者,能在下方一起交流,更希望大佬提出错误,谢谢!!!
GitHub地址:https://github.com/LiChangyi/…

    原文作者:李昌义
    原文地址: https://segmentfault.com/a/1190000011634322
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞