好久没写随笔了,因为最近比较忙,小公司基本都是一个前端干所有属于和部分不属于前端的事情,所以就没空弄了,即使想分享,也因为没有时间和精力就搁置了。

这周周六日休息,正好时间比较充裕(ps:目前处在单休中。。。),就分析了以下bootstrap-wysiwyg的源码,虽然只有200多行,但是本人js水平还是欠佳,所以大概用了一天的时间(ps:可怜我偶尔的双休还是变成了单休),对bootstrap-wysiwyg的源码进行了解读和部分的注释,在这里放出来,给需要的人,毕竟不是人人都喜欢百度的编辑器的(ps:我就是因为不喜欢百度编辑器的样式和一大堆文件的原因才会去看bootstrap-wysiwyg的源码的),这样,理解了内部构造也好扩展和修改,因为最近的项目图片不能转码提交,而是要上传到淘宝的oss上才返回地址显示在富文本编辑器中,这也是促使我对bootstrap-wysiwyg源码的解读,好了,废话太多了,简易注释的源码在下面:

  ps:里面我添加了对富文本编辑器中点击图片的监听事件(这个还是很有用的,比如修改图片大小),或者读到这篇文章的也可以去自己定义接口

    同时我也放在了github上,地址是:

    https://github.com/woleicom/bootstrap-wysiwyg-notes

    如果github被墙,国内可以访问oschina,地址是:

    https://git.oschina.net/woleicom/bootstrap-wysiwyg-notes

    喜欢的就给星吧,哈哈

 /* http://github.com/mindmup/bootstrap-wysiwyg */
/*global jQuery, $, FileReader*/
/*jslint browser:true*/
(function ($) {
'use strict';
/*转码图片*/
var readFileIntoDataUrl = function (fileInfo) {
var loader = $.Deferred(), //jq延迟对象
fReader = new FileReader();
fReader.onload = function (e) {
loader.resolve(e.target.result);
};
fReader.onerror = loader.reject; //拒绝
fReader.onprogress = loader.notify;
fReader.readAsDataURL(fileInfo); //转码图片
return loader.promise(); //返回promise
};
/*清空内容*/
$.fn.cleanHtml = function () {
var html = $(this).html();
return html && html.replace(/(<br>|\s|<div><br><\/div>|&nbsp;)*$/, '');
};
$.fn.wysiwyg = function (userOptions) {
var editor = this, //设置ui-jq='设置的插件别名的dom元素'(此句注释可忽略,是针对我的项目结构写的)
selectedRange,
options,
toolbarBtnSelector,
//更新工具栏
updateToolbar = function () {
if (options.activeToolbarClass) {
$(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
var command = $(this).data(options.commandRole);
//判断光标所在位置以确定命令的状态,为真则显示为激活
if (document.queryCommandState(command)) {
$(this).addClass(options.activeToolbarClass);
} else {
$(this).removeClass(options.activeToolbarClass);
}
});
}
},
//插入内容
execCommand = function (commandWithArgs, valueArg) {
var commandArr = commandWithArgs.split(' '),
command = commandArr.shift(),
args = commandArr.join(' ') + (valueArg || '');
document.execCommand(command, 0, args);
updateToolbar();
},
//用jquery.hotkeys.js插件监听键盘
bindHotkeys = function (hotKeys) {
$.each(hotKeys, function (hotkey, command) {
editor.keydown(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.stopPropagation();
execCommand(command);
}
}).keyup(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.stopPropagation();
}
});
});
},
//获取当前range对象
getCurrentRange = function () {
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0); //从当前selection对象中获得一个range对象。
}
},
//保存
saveSelection = function () {
selectedRange = getCurrentRange();
},
//恢复
restoreSelection = function () {
var selection = window.getSelection(); //获取当前既获区,selection是对当前激活选中区(即高亮文本)进行操作
if (selectedRange) {
try {
//移除selection中所有的range对象,执行后anchorNode、focusNode被设置为null,不存在任何被选中的内容。
selection.removeAllRanges();
} catch (ex) {
document.body.createTextRange().select();
document.selection.empty();
}
//将range添加到selection当中,所以一个selection中可以有多个range。
//注意Chrome不允许同时存在多个range,它的处理方式和Firefox有些不同。
selection.addRange(selectedRange);
}
},
//插入文件(这里指图片)
insertFiles = function (files) {
editor.focus();
//遍历插入(应为可以多文件插入)
$.each(files, function (idx, fileInfo) {
//只可插入图片文件
if (/^image\//.test(fileInfo.type)) {
//转码图片
$.when(readFileIntoDataUrl(fileInfo))
.done(function (dataUrl) {
execCommand('insertimage', dataUrl); //插入图片dom及src属性值
})
.fail(function (e) {
options.fileUploadError("file-reader", e);
});
} else {
//非图片文件会调用config的错误函数
options.fileUploadError("unsupported-file-type", fileInfo.type);
}
});
},
//TODO 暂不了解用意
markSelection = function (input, color) {
restoreSelection();
//确定命令是否被支持,返回true或false
if (document.queryCommandSupported('hiliteColor')) {
document.execCommand('hiliteColor', 0, color || 'transparent');
}
saveSelection();
input.data(options.selectionMarker, color);
},
//绑定工具栏相应工具事件
bindToolbar = function (toolbar, options) {
//给所有工具栏上的控件绑定点击事件
toolbar.find(toolbarBtnSelector).click(function () {
restoreSelection();
editor.focus(); //获取焦点
//设置相应配置的工具execCommand
execCommand($(this).data(options.commandRole));
//保存
saveSelection();
});
//对[data-toggle=dropdown]进行单独绑定点击事件处理 字体大小
toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
//对input控件进行单独处理,webkitspeechchange为语音事件
toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
var newValue = this.value; //获取input 的value
this.value = ''; //清空value防止冲突
restoreSelection();
if (newValue) {
editor.focus();//获取焦点
//设置相应配置的工具execCommand
execCommand($(this).data(options.commandRole), newValue);
}
saveSelection();
}).on('focus', function () { //获取焦点
var input = $(this);
if (!input.data(options.selectionMarker)) {
markSelection(input, options.selectionColor);
input.focus();
}
}).on('blur', function () { //失去焦点
var input = $(this);
if (input.data(options.selectionMarker)) {
markSelection(input, false);
}
});
toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
restoreSelection();
if (this.type === 'file' && this.files && this.files.length > 0) {
insertFiles(this.files);
}
saveSelection();
this.value = '';
});
},
//初始化拖放事件
initFileDrops = function () {
editor.on('dragenter dragover', false)
.on('drop', function (e) {
var dataTransfer = e.originalEvent.dataTransfer;
e.stopPropagation();
e.preventDefault();
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
insertFiles(dataTransfer.files);
}
});
};
//合并传入的配置对象userOptions和默认的配置对象config
options = $.extend({}, $.fn.wysiwyg.defaults, userOptions);
//设置查找字符串:a[data-edit] button[data-edit] input[type=button][data-edit]
toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
//设置热键 容器有[data-role=editor-toolbar]属性的dom元素
bindHotkeys(options.hotKeys);
//是否允许拖放 允许则配置拖放
if (options.dragAndDropImages) {initFileDrops();}
//配置工具栏
bindToolbar($(options.toolbarSelector), options);
//设置编辑区域为可编辑状态并绑定事件mouseup keyup mouseout
editor.attr('contenteditable', true)
.on('mouseup keyup mouseout', function () {
saveSelection();
updateToolbar();
});
//编辑区域绑定图片点击事件
//TODO 这是我自己添加的,因为有时要对图片进行一些操作
editor.on('mousedown','img', function (e) {
e.preventDefault();
}).on('click', 'img', function (e) {
var $img = $(e.currentTarget);
console.log($img);
e.preventDefault();
e.stopPropagation();
});
//window绑定touchend事件
$(window).bind('touchend', function (e) {
var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
currentRange = getCurrentRange(),
clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
if (!clear || isInside) {
saveSelection();
updateToolbar();
}
});
return this;
};
//配置参数
$.fn.wysiwyg.defaults = {
hotKeys: { //热键 应用hotkeys.js jquery插件
'ctrl+b meta+b': 'bold',
'ctrl+i meta+i': 'italic',
'ctrl+u meta+u': 'underline',
'ctrl+z meta+z': 'undo',
'ctrl+y meta+y meta+shift+z': 'redo',
'ctrl+l meta+l': 'justifyleft',
'ctrl+r meta+r': 'justifyright',
'ctrl+e meta+e': 'justifycenter',
'ctrl+j meta+j': 'justifyfull',
'shift+tab': 'outdent',
'tab': 'indent'
},
toolbarSelector: '[data-role=editor-toolbar]',
commandRole: 'edit',
activeToolbarClass: 'btn-info',
selectionMarker: 'edit-focus-marker',
selectionColor: 'darkgrey',
dragAndDropImages: true, //是否支持拖放,默认为支持
fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
};
}(window.jQuery));

简易富文本编辑器bootstrap-wysiwyg源码注释的更多相关文章

  1. vue+element ui项目总结点(三)富文本编辑器 vue-wangeditor

    1.参考 https://www.npmjs.com/package/vue-wangeditor 使用该富文本编辑器 <template> <div class="egi ...

  2. 轻量级富文本编辑器wangEditor源码结构介绍

    1. 引言 wangEditor——一款轻量级html富文本编辑器(开源软件) 网站:http://www.wangeditor.com/ demo演示:http://www.wangeditor.c ...

  3. 使用百度UMeditor富文本编辑器,修改自定义图片上传,修改源码

    富文本编辑器,不多说了,这个大家应该都用到过,至于用到的什么版本,那就分很多种 CKEditor:很早以前叫FCK,那个时候也用过,现在改名了,比较流行的一个插件,国外很多公司在用 UEDITOR:百 ...

  4. easyUI整合富文本编辑器KindEditor详细教程(附源码)

    原因 在今年4月份的时候写过一篇关于easyui整合UEditor的文章Spring+SpringMVC+MyBatis+easyUI整合优化篇(六)easyUI与富文本编辑器UEditor整合,从那 ...

  5. quillJS 富文本编辑器源码分析系列1

    quillJS 富文本编辑器目前是一款很火富文本编辑器,使用广泛,github 上面的 star 有 22,492,虽然说不以 star 论英雄,不过这可以说明它还是比较受欢迎的: 它的特点是:轻量, ...

  6. 富文本编辑器Simditor的简易使用

    最近打算自己做一个博客系统,并不打算使用帝国cms或者wordpress之类的做后台管理!自己处于学习阶段也就想把从前台到后台一起谢了.好了,废话不多说了,先来看看富文本编辑器SimDitor,这里是 ...

  7. 【前端】wangEditor(富文本编辑器) 简易使用示例

    转载请说明作者或者注明出处,谢谢 说到前端常用的编辑器,自然也少不了富文本编辑器(RichText Editor) 笔者在此之前也看了一些相关的在线编辑器,其中包括了当百度搜索“富文本编辑器”字样时出 ...

  8. Bootstrap富文本编辑器-bootstrap-wysiwyg

    在进行英语试题的录入中,因为英语试题经常会有类似如下的试题: My friend watches dragon boat races at the Dragon Boat Festival.(对划线部 ...

  9. Quill – 可以灵活自定义的开源的富文本编辑器

    Quill 的建立是为了解决现有的所见即所得(WYSIWYG)的编辑器本身就是所见即所得(指不能再扩张)的问题.如果编辑器不正是你想要的方式,这是很难或不可能对其进行自定义以满足您的需求. Quill ...

随机推荐

  1. javaFile循环列出指定目录下的所有文件(源代码)

    package javatest.basic22; import java.io.File; import java.io.IOException; public class FileTest { p ...

  2. 飘逸的python - 命令行漂亮的显示json数据

    之前做的一个脚本把信息用json格式存到文本中.这样的好处是简便,易编辑,并且拥有强大的表达能力. 不过从文本cat出来的是一堆很难看的字符串,没换行和缩进.这时候就在想,如果有个类似于IDE的格式化 ...

  3. T4模版

    T4模版 这讲适合所有的MVC程序 很荣幸,我们的系统有了体验的地址了.演示地址 之前我们发布了一个简单的代码生成器,其原理就是读取数据库的表结构,生成文本的一个方式来生成代码! 为了替代重复的劳动, ...

  4. 网际协议:无连接数据报交付(IPv4)

    一.数据报格式:

  5. ASP.NET MVC 使用MSBuild生成的几个注意事项

    做新项目,当时参考NopCommerce的结构,后台Nop.Admin是一个独立的Area Web Site,但部署的时候发现,使用一键发布,Admin Area会丢失. 研究了下NopCommerc ...

  6. Code First 启用迁移时出错 "No context type was found in the assembly"

    问题:Code First 启用迁移时找不到上下文DbContext所在的项目. PM> Enable-Migrations No context type was found in the a ...

  7. HashTable

    算法打基础——HashTable 这一节主要讲很多方面非常重要的hash table等问题. 由于平时很少用到这些,基本都忘了... 怎样快速的在内存中插入.删除.和搜索呢? 这就需要哈希表了 这一节 ...

  8. BDD

    Binding business requirements to .NET code http://www.specflow.org/ 行为驱动开发 BDD:Behavior Driven Devel ...

  9. [转]Creating an iPhone Daemon

    ref: http://chrisalvares.com/blog/7/creating-an-iphone-daemon-part-1/ http://chrisalvares.com/blog/3 ...

  10. Router

    backbone库学习-Router backbone库的结构http://www.cnblogs.com/nuysoft/archive/2012/03/19/2404274.html 本文的例子来 ...