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

后端 未结 3 1332
礼貌的吻别
礼貌的吻别 2020-12-23 14:35

I want to paste some rich text which has different fonts, font sizes, font weights, etc. into a content-editable div and ONLY keep boldness and italics. Any ide

3条回答
  •  醉酒成梦
    2020-12-23 15:14

    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.

    (2) reduce html for needed style format,

    (3) append to contenteditable div.

    !important ::

    we depend on Clipboard API, to get data.

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

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

    http://caniuse.com/clipboard

    so in IE Browser it wont work as expected.

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

    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 ) ,

    i am not aware of version IE 10, 11.

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

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

    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.

    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/

提交回复
热议问题