一、.md在網頁上顯示編輯器
- 先去官網下載editor.md的資源文件:eidtor.md官網
- 將下載好的editormd文件夾重命名爲editormd,並放在網站的根目錄下面,然後新建markdown.html文件,用作顯示。
- 在markdown.html中輸入以下內容用做顯示編輯器,注意資源引用的路徑哦,參考我的項目結構中引用的具體資源,再根據你項目結構,自行調整
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8" />
<title>Full example - Editor.md examples</title>
<link rel="stylesheet" href="../editormd/examples/css/style.css" />
<link rel="stylesheet" href="../editormd/css/editormd.min.css" />
<!--地址欄圖標-->
<link rel="shortcut icon" href="https://pandao.github.io/editor.md/favicon.ico" type="image/x-icon" />
</head>
<body>
<div id="editor">
<!-- Tips: Editor.md can auto append a `<textarea>` tag -->
<textarea style="display:none;">### Hello Editor.md !</textarea>
</div>
<script src="../editormd/examples/js/jquery.min.js"></script>
<script src="../editormd/editormd.min.js"></script>
<script type="text/javascript">
$(function() {
var editor = editormd("editor", {
width: "90%",
height: 800,
path : '../editormd/lib/',
theme : "light",
previewTheme : "light",
editorTheme : "pastel-on-light",
// markdown : md,
codeFold : true,
//syncScrolling : false,
saveHTMLToTextarea : true, // 保存 HTML 到 Textarea
searchReplace : true,
//watch : false, // 關閉實時預覽
htmlDecode : "style,script,iframe|on*", // 開啓 HTML 標籤解析,爲了安全性,默認不開啓
//toolbar : false, //關閉工具欄
//previewCodeHighlight : false, // 關閉預覽 HTML 的代碼塊高亮,默認開啓
emoji : true,
taskList : true,
tocm : true, // Using [TOCM]
tex : true, // 開啓科學公式TeX語言支持,默認關閉
flowChart : true, // 開啓流程圖支持,默認關閉
sequenceDiagram : true, // 開啓時序/序列圖支持,默認關閉,
//dialogLockScreen : false, // 設置彈出層對話框不鎖屏,全局通用,默認爲true
//dialogShowMask : false, // 設置彈出層對話框顯示透明遮罩層,全局通用,默認爲true
//dialogDraggable : false, // 設置彈出層對話框不可拖動,全局通用,默認爲true
//dialogMaskOpacity : 0.4, // 設置透明遮罩層的透明度,全局通用,默認值爲0.1
//dialogMaskBgColor : "#000", // 設置透明遮罩層的背景顏色,全局通用,默認爲#fff
imageUpload : true,
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "http://xx.xx.xx.xx:8080/API/wiki/beauty/uploadFile",
onload : function() {
console.log('onload', this);
//this.fullscreen();
//this.unwatch();
//this.watch().fullscreen();
//this.setMarkdown("#PHP");
//this.width("100%");
//this.height(480);
//this.resize("100%", 640);
}
});
});
</script>
</body>
</html>
- 這樣就可以在頁面中顯示出編輯框啦
二、圖片上傳
圖片上傳裏面很多坑,用官方的方法,試了很多次,都失敗了,圖片回顯url爲空,提示SecurityError: Blocked a frame with origin "http://localhost:63343" from acc...
之類的錯誤,以爲是跨域上傳圖片的問題,後來發現還是不行,最後請教了別人,別用官方的方法了,自己寫上傳函數,終於把這個東西給解決了,親測可用!親測可用!親測可用!
- 我們只修改了一個文件,就是
editormd/plugins/image-dialog/image-dialog.js
這個文件(具體在哪,參考我的項目結構)。 - 我將修改完後的文件代碼貼在下面,大家直接複製黏貼覆蓋就好啦,核心點就是我們採用ajax方法直接上傳,然後獲取返回值,進行賦值。
- 後端採用的是spring boot哦,大家還有疑問的話,歡迎郵件我,我會一一回復的:[email protected]
- 文末有福利哦
/*!
* Image (upload) dialog plugin for Editor.md
*
* @file image-dialog.js
* @author pandao
* @version 1.3.4
* @updateTime 2015-06-09
* {@link https://github.com/pandao/editor.md}
* @license MIT
*/
(function() {
var factory = function (exports) {
var pluginName = "image-dialog";
exports.fn.imageDialog = function() {
var _this = this;
var cm = this.cm;
var lang = this.lang;
var editor = this.editor;
var settings = this.settings;
var cursor = cm.getCursor();
var selection = cm.getSelection();
var imageLang = lang.dialog.image;
var classPrefix = this.classPrefix;
var iframeName = classPrefix + "image-iframe";
var dialogName = classPrefix + pluginName, dialog;
cm.focus();
var loading = function(show) {
var _loading = dialog.find("." + classPrefix + "dialog-mask");
_loading[(show) ? "show" : "hide"]();
};
if (editor.find("." + dialogName).length < 1)
{
var guid = (new Date).getTime();
var action = settings.imageUploadURL + (settings.imageUploadURL.indexOf("?") >= 0 ? "&" : "?") + "guid=" + guid;
if (settings.crossDomainUpload)
{
action += "&callback=" + settings.uploadCallbackURL + "&dialog_id=editormd-image-dialog-" + guid;
}
//註釋的是官方的寫法
// var dialogContent = ( (settings.imageUpload) ? "<form action=\"" + action +"\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">" ) +
// ( (settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "" ) +
// "<label>" + imageLang.url + "</label>" +
// "<input type=\"text\" data-url />" + (function(){
// return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
// "<input type=\"file\" name=\"" + classPrefix + "image-file\" accept=\"image/*\" />" +
// "<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
// "</div>" : "";
// })() +
// "<br/>" +
// "<label>" + imageLang.alt + "</label>" +
// "<input type=\"text\" value=\"" + selection + "\" data-alt />" +
// "<br/>" +
// "<label>" + imageLang.link + "</label>" +
// "<input type=\"text\" value=\"http://\" data-link />" +
// "<br/>" +
// ( (settings.imageUpload) ? "</form>" : "</div>");
//這是我個人寫法
var dialogContent = ( (settings.imageUpload) ? "<form action=\"#\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">" ) +
( (settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "" ) +
"<label>" + imageLang.url + "</label>" +
"<input type=\"text\" data-url />" + (function(){
return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
"<input type=\"file\" name=\"" + classPrefix + "image-file\" id=\"" + classPrefix + "image-file\" accept=\"image/*\" />" +
"<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
"</div>" : "";
})() +
"<br/>" +
"<label>" + imageLang.alt + "</label>" +
"<input type=\"text\" value=\"" + selection + "\" data-alt />" +
"<br/>" +
"<label>" + imageLang.link + "</label>" +
"<input type=\"text\" value=\"http://\" data-link />" +
"<br/>" +
( (settings.imageUpload) ? "</form>" : "</div>");
//這是官方的,不知道爲什麼,官方把它給註釋掉了
//var imageFooterHTML = "<button class=\"" + classPrefix + "btn " + classPrefix + "image-manager-btn\" style=\"float:left;\">" + imageLang.managerButton + "</button>";
dialog = this.createDialog({
title : imageLang.title,
width : (settings.imageUpload) ? 465 : 380,
height : 254,
name : dialogName,
content : dialogContent,
mask : settings.dialogShowMask,
drag : settings.dialogDraggable,
lockScreen : settings.dialogLockScreen,
maskStyle : {
opacity : settings.dialogMaskOpacity,
backgroundColor : settings.dialogMaskBgColor
},
buttons : {
enter : [lang.buttons.enter, function() {
var url = this.find("[data-url]").val();
var alt = this.find("[data-alt]").val();
var link = this.find("[data-link]").val();
if (url === "")
{
alert(imageLang.imageURLEmpty);
return false;
}
var altAttr = (alt !== "") ? " \"" + alt + "\"" : "";
if (link === "" || link === "http://")
{
cm.replaceSelection("![" + alt + "](" + url + altAttr + ")");
}
else
{
cm.replaceSelection("[![" + alt + "](" + url + altAttr + ")](" + link + altAttr + ")");
}
if (alt === "") {
cm.setCursor(cursor.line, cursor.ch + 2);
}
this.hide().lockScreen(false).hideMask();
//刪除對話框
this.remove();
return false;
}],
cancel : [lang.buttons.cancel, function() {
this.hide().lockScreen(false).hideMask();
//刪除對話框
this.remove();
return false;
}]
}
});
dialog.attr("id", classPrefix + "image-dialog-" + guid);
if (!settings.imageUpload) {
return ;
}
var fileInput = dialog.find("[name=\"" + classPrefix + "image-file\"]");
fileInput.bind("change", function() {
var fileName = fileInput.val();
var isImage = new RegExp("(\\.(" + settings.imageFormats.join("|") + "))$", "i"); // /(\.(webp|jpg|jpeg|gif|bmp|png))$/
if (fileName === "")
{
alert(imageLang.uploadFileEmpty);
return false;
}
if (!isImage.test(fileName))
{
alert(imageLang.formatNotAllowed + settings.imageFormats.join(", "));
return false;
}
loading(true);
var submitHandler = function() {
var uploadIframe = document.getElementById(iframeName);
uploadIframe.onload = function() {
loading(false);
//註釋的是官方寫法
// var body = (uploadIframe.contentWindow ? uploadIframe.contentWindow : uploadIframe.contentDocument).document.body;
// var json = (body.innerText) ? body.innerText : ( (body.textContent) ? body.textContent : null);
//
// json = (typeof JSON.parse !== "undefined") ? JSON.parse(json) : eval("(" + json + ")");
//
// if(!settings.crossDomainUpload)
// {
// if (json.success === 1)
// {
// dialog.find("[data-url]").val(json.url);
// }
// else
// {
// alert(json.message);
// }
// }
//
// return false;
//這是我個人寫法
var formData = new FormData();
formData.append("editormd-image-file",$("#editormd-image-file")[0].files[0]);
var action = settings.imageUploadURL + (settings.imageUploadURL.indexOf("?") >= 0 ? "&" : "?") + "guid=" + guid;
$.ajax({
type:"post",
url:action,
data:formData,
dataType:"json",
async:false,
processData : false, // 使數據不做處理
contentType : false, // 不要設置Content-Type請求頭
success:function(data){
// 成功拿到結果放到這個函數 data就是拿到的結果
console.log(data);
if(data.success == 1){
console.log(data.message);
dialog.find("[data-url]").val(data.url);
}else{
alert(data.message);
}
},
});
return false;
};
};
dialog.find("[type=\"submit\"]").bind("click", submitHandler).trigger("click");
});
}
dialog = editor.find("." + dialogName);
dialog.find("[type=\"text\"]").val("");
dialog.find("[type=\"file\"]").val("");
dialog.find("[data-link]").val("http://");
this.dialogShowMask(dialog);
this.dialogLockScreen();
dialog.show();
};
};
// CommonJS/Node.js
if (typeof require === "function" && typeof exports === "object" && typeof module === "object")
{
module.exports = factory;
}
else if (typeof define === "function") // AMD/CMD/Sea.js
{
if (define.amd) { // for Require.js
define(["editormd"], function(editormd) {
factory(editormd);
});
} else { // for Sea.js
define(function(require) {
var editormd = require("./../../editormd");
factory(editormd);
});
}
}
else
{
factory(window.editormd);
}
})();