编写一个属于自己的富文本编辑器(简单,实用)

1.编写HTML部分




<h2>文章发布</h2>

文章标题 <input id="t" placeholder="文章标题" style="width:400px;" /><br /><br />
文章积分 <input id="ss" placeholder="文章积分" value="30"  /><br /><br />
文章封面
<input type="file" id="fm" onchange="showPic()" /><br /><br />
<img id="fmpic" width="300" /><br /><br />
文章内容
<div style="border:2px solid black;padding:10px">
    <button onclick="jiaCu()">加粗</button>
    选择颜色 <input type="color" id="c" onchange="changeColor()" />
    上传图片 <input type="file" id="f" onchange="addPic()" />

    上传视频 <input type="file" id="v" onchange="addVideo()" />
    <button>文字变红</button>
    <button onclick="juzhong('left')">左对齐</button>
    <button onclick="juzhong('right')">右对齐</button>
    <button onclick="juzhong('center')">居中</button>
 字体大小:<select onchange="changeFontSize()" id="s">
        <option value="10">10px</option>
        <option value="12">12px</option>
        <option value="14">14px</option>
        <option value="16">16px</option>
        <option value="18">18px</option>
        <option value="20">20px</option>
        <option value="24">24px</option>
        <option value="28">28px</option>
        <option value="32">32px</option>
        <option value="40">40px</option>
        <option value="50">50px</option>
    </select>
    <br /><br />
    <div id="d1"
         onkeyup="saveContent()"
         contenteditable
         style="overflow:auto;outline:none;padding:10px;width:1000px;height:300px;border: 1px solid #999">
    </div>
</div>
<div id="pic_menu" style="cursor:pointer;color:white;font-size:12px;background:orange;display:none;position:absolute;left:0px;top:0px;">
    <div onclick="changePicWidth()">调整大小</div>
    <!--这三个可以自己试试编写-->
    <div>设置透明度</div>
    <div>旋转</div>
    <div>设置提示文字</div>
</div>
<br /><br />
<button onclick="save()">发布</button>

2.编写js部分

 let currentImg;
    let pic_src;

    function addVideo(){

        let req = new XMLHttpRequest();
        req.open("post","http://localhost:8084/wechat/upload");
        const formdata = new FormData();
        formdata.append("file",v.files[0]);
        req.upload.onprogress = function(e){
            console.log(e);
        };
        req.send(formdata);
        req.onreadystatechange = function(){
            if(req.readyState==4&&req.status==200){
                video_src = req.responseText

                const range = window.getSelection().getRangeAt(0);
                const video = document.createElement("video");
                video.style.width = "300px";
                video.autoplay = "autoplay";
                video.muted = true;
                video.controls = "controls";
                video.src = "http://localhost:8084/wechat/find_img?fileName="+video_src
                range.insertNode(video);
            }
        }

    }

    function save(){
        let req = new XMLHttpRequest();
        req.open("post","http://localhost:8080/wechat/add_article");
        req.setRequestHeader("content-type","application/json;charset=utf-8")
        req.send(JSON.stringify({
            title:t.value,
            content:d1.innerHTML,
            pic:pic_src,
            score:ss.value
        }));
        req.onreadystatechange = function(){
            if(req.readyState==4&&req.status==200){
                alert(req.responseText)
            }
        }
    }

    let video_src;
    function showPic(){
        const reader = new FileReader();
        reader.readAsDataURL(fm.files[0]);
        reader.onload = function(){
            fmpic.src = reader.result;
            let req = new XMLHttpRequest();
            req.open("post","http://localhost:8084/wechat/upload");
            const formdata = new FormData();
            formdata.append("file",fm.files[0]);
            req.send(formdata);
            req.onreadystatechange = function(){
                if(req.readyState==4&&req.status==200){
                    pic_src = req.responseText


                }
            }
        }
    }
    ///wechat/add_article
    function changePicWidth(){
        pic_menu.style.display = "none";
        const w = prompt("请输入图片的宽度")
        currentImg.style.width = w+"px";
        currentImg.style.border = "none";

    }

    if(localStorage.cnt){
        d1.innerHTML = localStorage.cnt;
    }
    function saveContent(){
        localStorage.cnt = d1.innerHTML;
    }

    function addPic(){
        const range = window.getSelection().getRangeAt(0);
        const img = document.createElement("img");
        img.style.width = "300px";

        img.oncontextmenu = function(){
            currentImg = this;
            pic_menu.style.display = "block";
            pic_menu.style.left = img.offsetLeft+d1.offsetLeft;
            pic_menu.style.top = img.offsetTop + d1.offsetTop -10;

            return false;
        }

        const filereader = new FileReader();
        filereader.readAsDataURL(f.files[0]);
        filereader.onload = function(){
            img.src = filereader.result;
            range.insertNode(img);
        }
    }

    function changeColor(){
        const span = document.createElement("span");
        span.style.color = c.value;
        const range = window.getSelection().getRangeAt(0);
        range.surroundContents(span);
    }

    function jiaCu(){
        const span = document.createElement("span");
        span.style['font-weight'] = 900;
        const range = window.getSelection().getRangeAt(0);
        range.surroundContents(span);
    }

    function juzhong(x){
        const span = document.createElement("div");
        span.style['text-align'] =x;
        const range = window.getSelection().getRangeAt(0);
        range.surroundContents(span);
    }

    function changeFontSize(){
        const span = document.createElement("span");
        span.style['font-size'] = s.value+"px";
        const range = window.getSelection().getRangeAt(0);
        range.surroundContents(span);
    }

注意:有的事件我是绑定后端服务器接口的

java环境是 SpringBoot  只需要创建一个SpringBoot项目即可

代码如下:

@RestController
public class HomeController {
          

    @PostMapping("/api/add_article")
    public String add_article(@RequestBody Map map) throws IOException, SQLException {
        Connection dbcon = DriverManager.getConnection(
  "jdbc:mysql://数据库连接主机名:3306/数据库名?useSSL=false","用户名","密码");

        PreparedStatement ps;

        String insertSQL = "insert into article values (null,?,?,?,now(),?)";
        ps = dbcon.prepareStatement(insertSQL);
        ps.setString(1,map.get("title")+"");
        ps.setString(2,map.get("content")+"");
        FileWriter fw = new FileWriter(new File(map.get("pic")+".html"));
        fw.write("<meta charset='utf-8' /><meta name='viewport' " +
                "content='width=device-width' />"+map.get("content")+"");
        fw.close();
        ps.setString(3,map.get("pic")+"");
        ps.setString(4,map.get("score")+"");
        int i = ps.executeUpdate();
        ps.close();
        dbcon.close();
        return (i==1)+"";
    }


    @GetMapping("/wechat/find_img")
    public void find_img(String fileName, HttpServletResponse response) throws IOException {
        File file = new File(getBasePath() +fileName);
        FileInputStream fis = new FileInputStream(file);

        byte[] b = new byte[1024];
        int num;

        response.setHeader("content-Type","image/*");

        while((num=fis.read(b))!=-1){
            response.getOutputStream().write(b,0,num);
        }
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }



   @PostMapping("/wechat/upload")
    public String upload(MultipartFile file) throws IOException, SQLException {
        String basepath = getBasePath();
        String fn = System.currentTimeMillis()+"_"+file.getOriginalFilename();
        file.transferTo(new File(basepath+fn));
        return fn;
    }


    @NotNull
    private String getBasePath(){
        String osName = System.getProperties().getProperty("os.name");

            //注意路径一定要正确

           //苹果系统
        String basepath = "存放文件的路径";
           //windos系统
        if(osName.contains("Windows")){
            //basepath = "存放文件的路径";
            
            basepath = "d://uploads/";
        }
        return basepath;
    }


}

数据库文章表结构

为了方便大家,我就直接上SQL语句了

CREATE TABLE `article` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  `content` longtext,
  `pic` varchar(1000) DEFAULT NULL,
  `createtime` datetime DEFAULT NULL,
  `score` int DEFAULT '30',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

网页界面如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值