在之前的React官網教程中,提到了用Remarkable為插件的markdown評論框。現在就來正兒八經地用另外一個插件marked.js做一個markdown編輯器吧!
准備工作
或許在做之前,應該布個局。
<div class="brand">
<h1>Markdown Previewer</h1>
</div>
<div id=container>
<div id="markdownApp">
<div class="edit-area">
<textarea placeholder="請輸入markdown文本" class="editor"></textarea>
</div>
<div class="shower">
</div>
</div>
</div>
/*simple css-reset*/
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
a{
text-decoration: none;
}
/*major*/
.brand{
width: 100%;
height: 80px;
background: rgb(21,127,178);
}
.brand h1{
text-align: center;
font-size: 30px;
color: #fff;
line-height: 80px;
font-weight: normal;
}
#markdownApp{
width: 100%;
}
.edit-area,.shower{
float: left;
width: 50%;
}
.edit-area textarea{
max-width: 80%;
min-width: 80%;
margin: 20px;
min-height:600px;
border: 1px solid rgb(21,127,178)
}
大概這樣就OK了。
本demo使用的是以下環境(marked.js,highlight.js及其樣式庫)。
<link rel="stylesheet" type="text/css" href="css/css.css"/>
<link rel="stylesheet" href="css/bootstrap.min.css">
<!-- 高亮樣式庫,為了讓樣式總體好看,使用bootstrap的樣式庫 -->
<script src="js/react.js"></script>
<script src="js/react-dom.js"></script>
<script src="js/browser.min.js"></script>
<script src="js/marked.js"></script>
<script src="js/highlight.pack.js"></script>
<script >hljs.initHighlightingOnLoad();</script>
<script src="js/js.js"></script>
關於marked.js的設置用法參見marked.js簡明手冊。
基本實現
基本上就是keyUp事件:
var rendererMD = new marked.Renderer();
marked.setOptions({
renderer: rendererMD,
highlight: function (code) {
return hljs.highlightAuto(code).value;
},
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false
});
var markdownString = '```js\n console.log("hello"); \n```';
var oEditor=document.getElementById('editor');
var oShower=document.getElementById('shower');
//oShower.innerHTML=marked(markdownString)
oEditor.onkeyup=function(){
oShower.innerHTML = marked(this.value);
}
React思路
靜態結構
按照html結構先把靜態結構寫上去:
var MarkdownApp=React.createClass({
render:function(){
return (
<div id="markdownApp">
<Editor />
<div className="shower" id="shower"></div>
</div>
);
}
});
var Editor=React.createClass({
render:function(){
return (
<div className="edit-area">
<textarea placeholder="請輸入markdown文本" id="editor" className="editor"></textarea>
</div>
);
}
});
ReactDOM.render(
<MarkdownApp/>,
document.getElementById('container')
)
動態實現
var str="Heading\n=======\n\nSub-heading\n-----------\n \n### Another deeper heading\n \nParagraphs are separated\nby a blank line.\n\nLeave 2 spaces at the end of a line to do a \nline break\n\nText attributes *italic*, **bold**, \n`monospace`, ~~strikethrough~~ .\n\nShopping list:\n\n * apples\n * oranges\n * pears\n\nNumbered list:\n\n 1. apples\n 2. oranges\n 3. pears\n\nThe rain---not the reign---in\nSpain.\n\n *[Herman Fassett](https://freecodecamp.com/hermanfassett)*\n```javascript\nfunction(){\n alert(hehe);\n}\n```"
var MarkdownApp=React.createClass({
getInitialState:function(){
return {
content:str,
}
},
handleChange:function(value){
this.setState({
content:value,
});
},
render:function(){
return (
<div id="markdownApp">
<Editor
handleChange={(value)=>this.handleChange(value)}
value={this.state.content}/>
<Shower content={this.state.content} />
</div>
);
}
});
var Editor=React.createClass({
handleChange:function(e){
var _this=e.target;
this.props.handleChange(_this.value);
},
render:function(){
return (
<div className="edit-area">
<textarea
placeholder="請輸入markdown文本"
id="editor"
className="editor"
value={this.props.value}
onChange={this.handleChange}>
</textarea>
</div>
);
}
});
var Shower=React.createClass({
convertor:function(content){
var rendererMD = new marked.Renderer();
marked.setOptions({
renderer: rendererMD,
highlight: function (code) {
return hljs.highlightAuto(code).value;
},
gfm: true,
tables: true,
breaks: true,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
});
//console.log(marked(content));
return ({
__html:marked(content)
});//注意是兩個下划線!
},
render:function(){
return (
<div
className="shower"
id="shower"
dangerouslySetInnerHTML={this.convertor(this.props.content)}></div>
);
}
});
ReactDOM.render(
<MarkdownApp/>,
document.getElementById('container')
);
看了一下,確實不用怎么想。
