jQuery 将富文本粘贴到内容可编辑的 div 中,并仅保留粗体和斜体格式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21257688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 01:30:44  来源:igfitidea点击:

Paste rich text into content-editable div and only keep bold and italics formatting

jqueryhtml

提问by Cristi Pufu

I want to paste some rich text which has different fonts, font sizes, font weights, etc. into a content-editable divand ONLY keep boldness and italics. Any idea how to go about this?

我想将一些具有不同字体、字体大小、字体粗细等的富文本粘贴到内容可编辑中,div并且仅保留粗体和斜体。知道如何解决这个问题吗?

The following code turns rich text into plain text when pasted into content-editable div.

当粘贴到内容可编辑的 div 中时,以下代码将富文本转换为纯文本。

$('[contenteditable]').on('paste',function(e) {
    e.preventDefault();
    var text = (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('Paste something..');
    document.execCommand('insertText', false, text);
});

I've tried looking at the textvariable in the above code, but it doesn't seem to be formatted.

我试过查看text上面代码中的变量,但它似乎没有被格式化。

回答by Cristi Pufu

Here's a working demo: http://jsfiddle.net/SJR3H/7/

这是一个工作演示:http: //jsfiddle.net/SJR3H/7/

$(document).ready(function(){

        $('[contenteditable]').on('paste',function(e) {

            e.preventDefault();

            var text = (e.originalEvent || e).clipboardData.getData('text/html') || prompt('Paste something..');
            var $result = $('<div></div>').append($(text));

            $(this).html($result.html());

            // replace all styles except bold and italic
            $.each($(this).find("*"), function(idx, val) {

                var $item = $(val);
                if ($item.length > 0){
                   var saveStyle = {
                        'font-weight': $item.css('font-weight'),
                        'font-style': $item.css('font-style')
                    };
                    $item.removeAttr('style')
                         .removeClass()
                         .css(saveStyle); 
                }
            });

            // remove unnecesary tags (if paste from word)
            $(this).children('style').remove();
            $(this).children('meta').remove()
            $(this).children('link').remove();

        });

    });

Later edit:http://jsfiddle.net/SJR3H/8/

后来编辑:http : //jsfiddle.net/SJR3H/8/

i added the following lines:

我添加了以下几行:

$item.replaceWith(function(){
       return $("<span />", {html: $(this).html()});
});

It actually replaces all htmltags with spans. There you can optionally choose to let some tags as they were in the original text (h1, p, etc), styling them as you desire.

它实际上htmlspans替换了所有标签。在那里,您可以选择让某些标签保持原始文本(、 等)中的原样h1,根据需要对它们进行p样式设置。

回答by sudhan kantharuban

Let begin with your code :

让我们从你的代码开始:

//on paste
var text = (e.originalEvent || e).clipboardData.getData('text/plain')


//html in clipboard are saved as Plain Unicode string , 

getData('text/plain') //return data as string,

//if MIME TYPE 'text/html' is used you will get data as html with style attributes

// insert text

document.execCommand('insertText', false, text);

//this will simply insert the text to contenteditable div.

//so there is no chance of knowing recieved text is bold / italics.

(1) we must get data as html,to get style properties: fontWeight, fontStyle.

(1) 我们必须以html形式获取数据,才能获取样式属性:fontWeight、fontStyle。

(2) reduce html for needed style format,

(2) 减少 html 所需的样式格式,

(3) append to contenteditable div.

(3) 附加到 contenteditable div。

!important ::

!重要的 ::

we depend on Clipboard API, to get data.

我们依赖剪贴板 API 来获取数据。

it is not fully supported by newer browsers, please check links below:

较新的浏览器不完全支持它,请检查以下链接:

https://developer.mozilla.org/en-US/docs/Web/Reference/Events/paste

https://developer.mozilla.org/en-US/docs/Web/Reference/Events/paste

http://caniuse.com/clipboard

http://caniuse.com/clipboard

so in IE Browser it wont work as expected.

所以在 IE 浏览器中它不会按预期工作。

the data format argument we pass in getData() is different in IE Browser:

我们在 getData() 中传递的数据格式参数在 IE 浏览器中是不同的:

http://msdn.microsoft.com/en-us/library/ie/ms536436(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/ie/ms536436(v=vs.85).aspx

so we get only plain string from getData() method, i checked in IE 9.0.8112.16421 ( not updated ) ,

所以我们只从 getData() 方法获得纯字符串,我在 IE 9.0.8112.16421(未更新)中检查,

i am not aware of version IE 10, 11.

我不知道版本 IE 10、11。

I coded in a way, if getData("Html") supported in ie 10,11 code, requirements will get done.

我以某种方式编码,如果 ie 10,11 代码支持 getData("Html"),则要求将完成。

Code works : Like @Cristi did, get all html elements.

代码有效:像@Cristi 一样,获取所有 html 元素。

iterate through them, instead of changing style attributes we use tags.

遍历它们,而不是更改样式属性,我们使用标签。

tags for bold & tag for italics.

粗体标记和斜体标记。

Iterations are done asynchronously, because pasting large text content may hang browser.

迭代是异步完成的,因为粘贴大文本内容可能会挂掉浏览器。

I had Tested in Chrome, Firefox.

我曾在 Chrome、Firefox 中进行过测试。

pasteArea.addEventListener('paste', function(e) {

    // prevent pasting text by default after event
    e.preventDefault(); 

    var clipboardData = {},
    rDataText,
    rDataHTML;

    clipboardData = e.clipboardData;
    rDataHTML = clipboardData.getData('text/html');
    rDataPText = clipboardData.getData('text/plain');


    if (rDataHTML && rDataHTML.trim().length != 0) {

        //Function Call to Handle HTML

        return false; // prevent returning text in clipboard
    }

    if (rDataPText && rDataPText.trim().length != 0) {

        //Function Call to Handle Plain String

        return false; // prevent returning text in clipboard
    }

}, false);

// Handle Plain Text
function PlainTextHandler(pText) {
    // Remove Line breaks
    // append to contenteditable div - using range.insertNode()
    // document.execCommand();  had issue in ie9 so i didn't used it 
}

// Handle HTML
function formatHtml(elem, complete) {
        var flag_italic = false;
        var flag_weight = false;
        var fontStyle;
        var fontWeight;

        if (elem.nodeType == 1) { // only pass html elements

            // get style in css 
            var CSSStyle = window.getComputedStyle(elem);
            fontStyle = CSSStyle.fontStyle;
            fontWeight = CSSStyle.fontWeight;

            // get style defined by inline
            var InlineStyle = elem.style;
            inlineFontStyle = InlineStyle['font-style'];
            inlineFontWeight = InlineStyle['font-weight'];
            if (inlineFontStyle && inlineFontStyle.trim() != '') fontStyle = inlineFontStyle;
            if (inlineFontWeight && inlineFontWeight.trim() != '') fontWeight = inlineFontWeight;

            // get style defined in MSword
            var msStyle = elem.getAttribute('style');
            if (/mso-bidi/.test(msStyle)) {
                var MSStyleObj = {};
                var styleStrArr = msStyle.split(";");
                for (i = 0; i < styleStrArr.length; i++) {
                    var temp = styleStrArr[i].split(":");
                    MSStyleObj[temp[0]] = temp[1];
                }
                fontStyle = MSStyleObj['mso-bidi-font-style'];
                fontWeight = MSStyleObj['mso-bidi-font-weight'];
            }

            if (fontStyle && fontStyle == 'italic') flag_italic = true; // flag true if italic

            if (fontWeight && (fontWeight == 'bold' || 600 <= (+fontWeight))) flag_weight = true;  // flag true if bold - 600 is semi bold

            // bold & italic are not applied via style
            // these styles are applied by appending contents in new tags string & bold
            if (flag_italic && flag_weight) {
                var strong = document.createElement('strong');
                var italic = document.createElement('i');
                strong.appendChild(italic);
                newtag = strong;
            } else {
                if (flag_italic) {
                    newtag = document.createElement('i');
                } else if (flag_weight) {
                    newtag = document.createElement('strong');
                } else {
                    // remove un wanted attributes & element
                    var tagName = elem.tagName;
                    // strong are not skipped because, by creating new unwanted attributes will be removed
                    if (tagName == 'STRONG' || tagName == 'B') {
                        newtag = document.createElement('strong');
                    } else if (tagName == 'I') {
                        newtag = document.createElement('i');
                    } else {
                        newtag = document.createElement('span');
                    }
                }
            }

            // content appended
            var elemHTML = elem.innerHTML;
            if (flag_italic && flag_weight) {
                newtag.childNodes[0].innerHTML = elemHTML;
            } else {
                newtag.innerHTML = elemHTML;
            }

            // curr element is replaced by new
            elem.parentNode.insertBefore(newtag, elem);
            elem.parentNode.removeChild(elem);
        }
        complete() // completed one iteration
    }

Fiddle: http://jsfiddle.net/aslancods/d9cfF/7/

小提琴:http: //jsfiddle.net/aslancods/d9cfF/7/

回答by user956584

I used this on my website for long time

我在我的网站上使用了很长时间

$(document).on('paste','#tesc', function() {
                 setTimeout(function() {
                        asd = strip_tags( $('#tesc').html(), '<b><b/><i></i>');

                        $('#tesc').html( asd );
                },100);

        });

function strip_tags (input, allowed) {
    /* http://kevin.vanzonneveld.net*/

    if ( input == undefined ) { return ''; }

    allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
    var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
        commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
    return input.replace(commentsAndPhpTags, '').replace(tags, function (##代码##, ) {
        return allowed.indexOf('<' + .toLowerCase() + '>') > -1 ? ##代码## : '';
    });
}