像简书那样将粘贴的链接自动转换为Markdown格式

原创
2016/10/07 14:33
阅读数 806

参考 JavaScript get clipboard data on paste event (Cross browser)Insert text into textarea at cursor position (Javascript)实现了基本的功能,可以像简书那样将粘贴的链接自动转换为Markdown格式。在Chrome 51测试。未做其他的兼容性测试。

效果如下:

输入图片说明

代码结构

输入图片说明

源码

https://github.com/letiantian/paste-as-markdown

这里贴下源码:

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Paste as Markdown</title>
    <link href="//cdn.bootcss.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
        textarea {
            width: 100%;
            height: 200px;
        }
    </style>
</head>
<body>

<div class="row">
    <div class="col-md-3"></div>
    <div class="col-md-6">
        <h1>复制粘贴为Markdown格式</h1>
        <hr/>
            <p>这是一段文本</p>
            <p><a href="/bundle.js">Link One</a></p>
            <p><a href="https://github.com/letiantian">Link Two</a></p>
            <p><img src="./art.png" /></p>
        <hr/>
        <p>
            <button id="addText" class="btn-primary">在光标位置添加文本</button>
        </p>
        <textarea id="content">Paste</textarea>
    </div>
    <div class="col-md-3"></div>
</div>

<script src="//cdn.bootcss.com/jquery/2.2.2/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
<script src="./bundle.js"></script>
</body>
</html>

bundle.js

var editableTextArea = document.getElementById('content');

function handlepaste (e) {
    var types, pastedData, savedContent;

    // Browsers that support the 'text/html' type in the Clipboard API (Chrome, Firefox 22+)
    if (e && e.clipboardData && e.clipboardData.types && e.clipboardData.getData) {

        console.log(e.clipboardData);

        // Check for 'text/html' in types list. See abligh's answer below for deatils on
        // why the DOMStringList bit is needed. We cannot fall back to 'text/plain' as
        // Safari/Edge don't advertise HTML data even if it is available
        types = e.clipboardData.types;
        if (((types instanceof DOMStringList) && types.contains("text/html")) || (types.indexOf && types.indexOf('text/html') !== -1)) {

            // Extract data and pass it to callback
            pastedData = e.clipboardData.getData('text/html');

            console.log(pastedData);

            typeInTextarea($('#content'), processHtmlData(pastedData));

            // Stop the data from actually being pasted
            e.stopPropagation();
            e.preventDefault();
            return false;
        }
    }
}

function typeInTextarea(el, newText) {
      var start = el.prop("selectionStart")
      var end = el.prop("selectionEnd")
      var text = el.val()
      var before = text.substring(0, start)
      var after = text.substring(end, text.length)
      el.val(before + newText + after)
      el[0].selectionStart = el[0].selectionEnd = start + newText.length
      el.focus()
      return false
}

function processHtmlData(data) {
    data = '<div>' + data + '</div>';   // let find() run
    var dataDom = $(data);
    dataDom.filter('script').remove();
    dataDom.filter('style').remove();

    // process <a></a>
    dataDom.find('a').each(function(idx, item) {
        console.log('find a link');
        var url = $(item).attr("href");
        var content = $(item).text();
        $(this).text('['+content+'](' + url + ')');
    });

    // process <img/>
    dataDom.find('img').each(function(idx, item) {
        console.log('find an img');
        var url = $(item).attr("src");
        var content = '';
        $(this).after('<span>!['+content+'](' + url + ')</span>');
    });

    console.log('after process img: ' + dataDom.html());

    // process p,h1,h2,... 
    ['p', 'h1', 'h2', 'h3', 'h4'].forEach(function(tag, idx){
        dataDom.find(tag).each(function(index, item) {
            var content = $(item).html().trim();
            if (content.length > 0)
                $(this).html(content + '&#13;&#10;');  // add new line
        });
    });

    return dataDom.text().trim();
}

// Modern browsers. Note: 3rd argument is required for Firefox <= 6
editableTextArea.addEventListener('paste', handlepaste, false);


// add text button
function processButtonClick() {
    typeInTextarea($('#content'), 'Hello, ~');
}
document.getElementById('addText').addEventListener('click', processButtonClick, false);
展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部