简体   繁体   中英

Unable to get HTML className of selected text using vanilla Javascript in Chrome

I am developing a wysiwyg editor and I am unable to undo the effect that I applied earlier.

Example: If I select some text and bold it, it works fine. But if I want to remove the bold effect on it, I am unable to get the className applied to the selected text. (line # 6 in JS) In the console, I can see that it actually exists under sel > anchorNode > nextElementSibling > className but not sure why it is not allowing to fetch that.

 function replaceSelectedText(className) { var selectedText, sel, range; if (window.getSelection) { sel = window.getSelection(); // check if selection has a class if(sel.anchorNode){ console.dir(sel); if(sel.anchorNode.nextElementSibling){ console.log("className:" + sel.anchorNode.nextElementSibling.className); } } selectedText = window.getSelection().toString(); //console.log(selectedText); if (sel.rangeCount) { range = sel.getRangeAt(0); range.deleteContents(); var element = document.createElement('span'); element.className = className; element.textContent = selectedText; range.insertNode(element); } } else if (document.selection && document.selection.createRange) { range = document.selection.createRange(); range.text = replacementText; } } var toolbarButtons = document.querySelectorAll("#toolbar button"); //console.log(toolbarButtons); for (var i = 0; i < toolbarButtons.length; ++i) { toolbarButtons[i].addEventListener('click', function(){ replaceSelectedText(this.id); console.log(document.getElementById("editable").innerHTML); }); } 
 #editable{ border: 1px solid #000000; margin-top: 20px; height: 50px; font-family: Arial; } .bold{ font-weight: bold; } .italic{ font-style: italic; } 
 <div id="toolbar"> <button id="bold">Bold</button> <button id="italic">Italic</button> </div> <div id="editable" contentEditable="true"> <div>Lorem Ipsum Lorem Ipsum</div> </div> 

It works in Firefox but not in Chrome.

How do I get the className in Chrome?

There seems to be individual solutions for Chrome and Firefox.

Firefox : sel.anchorNode.nextElementSibling.className
Chrome : sel.baseNode.parentElement.className

I fixed it by detecting the browser.

Detecting the browser:

var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
// Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
var isFirefox = typeof InstallTrigger !== 'undefined';   // Firefox 1.0+
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
// At least Safari 3+: "[object HTMLElementConstructor]"
var isChrome = !!window.chrome && !isOpera;              // Chrome 1+
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6

JS Conditions:

    if(isChrome){
        if(sel.baseNode.parentElement.className){
            console.log("isChrome className:" + sel.baseNode.parentElement.className);
            sel.baseNode.parentElement.className = "";
            return false;
        }
    }

    if(isFirefox){
        if(sel.anchorNode.nextElementSibling){
            console.log("isFirefox className:" + sel.anchorNode.nextElementSibling.className);
            sel.anchorNode.nextElementSibling.className = "";
            return false;
        }
    }

Demo: http://jsfiddle.net/590tcmqz/12/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM