contenteditable div在光标位置的{PXI}位置设置字体大小

时间:2018-04-26 11:42:05

标签: javascript html css

我有一个contenteditable div和一个combobx,可以在其上应用各种字体大小。

我已经完成了javascript实现,用于更改所选文本的字体大小,但不知道如何为下一个用户输入设置字体大小。

例如,

1) 在内容可编辑的div中,用户首先选择字体大小,然后开始键入,然后应将选定的fontsize应用于用户输入文本。

2)用户输入了文字"你好"现在他将字体大小更改为24px并键入" world"然后说'世界"字体大小应为24像素。

下面是带有javascript代码的HTML页面,用于在所选文本上应用字体大小。



    <!DOCTYPE html>
    <html>
    <head>
        <script type="text/javascript">
            function GetNextLeaf (node) {
                while (!node.nextSibling) {
                    node = node.parentNode;
                    if (!node) {
                        return node;
                    }
                }
                var leaf = node.nextSibling;
                while (leaf.firstChild) {
                    leaf = leaf.firstChild;
                }
                return leaf;
            }
    
            function GetPreviousLeaf (node) {
                while (!node.previousSibling) {
                    node = node.parentNode;
                    if (!node) {
                        return node;
                    }
                }
                var leaf = node.previousSibling;
                while (leaf.lastChild) {
                    leaf = leaf.lastChild;
                }
                return leaf;
            }
    
                // If the text content of an element contains white-spaces only, then does not need to colorize
            function IsTextVisible (text) {
                for (var i = 0; i < text.length; i++) {
                    if (text[i] != ' ' && text[i] != '\t' && text[i] != '\r' && text[i] != '\n')
                        return true;
                }
                return false;
            }
    
            function ColorizeLeaf (node, size) {
                if (!IsTextVisible (node.textContent))
                    return;
    
                var parentNode = node.parentNode;
                    // if the node does not have siblings and the parent is a span element, then modify its color
                if (!node.previousSibling && !node.nextSibling) {
                    if (parentNode.tagName.toLowerCase () == "span") {
                        //parentNode.style.color = color;
                        parentNode.style.fontSize = size+"px";
                        return;
                    }
                }
    
                    // Create a span element around the node
                var span = document.createElement("span");
                //span.style.color = color;
                span.style.fontSize = size + "px";
                var nextSibling = node.nextSibling;
    
                parentNode.removeChild (node);
                span.appendChild (node);
                parentNode.insertBefore (span, nextSibling);
            }
    
            function ColorizeLeafFromTo (node, size, from, to) {
                var text = node.textContent;
                if (!IsTextVisible (text))
                    return;
    
                if (from < 0)
                    from = 0;
                if (to < 0)
                    to = text.length;
    
                if (from == 0 && to >= text.length) {
                        // to avoid unnecessary span elements
                    ColorizeLeaf(node, size);
                    return;
                }
    
                var part1 = text.substring (0, from);
                var part2 = text.substring (from, to);
                var part3 = text.substring (to, text.length);
    
                var parentNode = node.parentNode;
                var nextSibling = node.nextSibling;
    
                parentNode.removeChild (node);
                if (part1.length > 0) {
                    var textNode = document.createTextNode (part1);
                    parentNode.insertBefore (textNode, nextSibling);
                }
                if (part2.length > 0) {
                    var span = document.createElement ("span");
                    //span.style.color = color;
                    span.style.fontSize = size+"px";
                    var textNode = document.createTextNode (part2);
                    span.appendChild (textNode);
                    parentNode.insertBefore (span, nextSibling);
                }
                if (part3.length > 0) {
                    var textNode = document.createTextNode (part3);
                    parentNode.insertBefore (textNode, nextSibling);
                }
            }
    
            function ColorizeNode (node, size) {
                var childNode = node.firstChild;
                if (!childNode) {
                    ColorizeLeaf(node, size);
                    return;
                }
    
                while (childNode) {
                        // store the next sibling of the childNode, because colorizing modifies the DOM structure
                    var nextSibling = childNode.nextSibling;
                    ColorizeNode(childNode, size);
                    childNode = nextSibling;
                }
            }
    
            function ColorizeNodeFromTo(node, size, from, to) {
                var childNode = node.firstChild;
                if (!childNode) {
                    ColorizeLeafFromTo(node, size, from, to);
                    return;
                }
    
                for (var i = from; i < to; i++) {
                    ColorizeNode(node.childNodes[i], size);
                }
            }
    
            function ColorizeSelection(size) {
    
                if (window.getSelection) {  // all browsers, except IE before version 9
                    var selectionRange = window.getSelection ();
    
                    if (selectionRange.isCollapsed) {
                       // no idea on how to apply font size here. at cursor point.
                    }                            
                    else {
                        var range = selectionRange.getRangeAt (0);
                            // store the start and end points of the current selection, because the selection will be removed
                        var startContainer = range.startContainer;
                        var startOffset = range.startOffset;
                        var endContainer = range.endContainer;
                        var endOffset = range.endOffset;
                            // because of Opera, we need to remove the selection before modifying the DOM hierarchy
                        selectionRange.removeAllRanges ();
    
                        if (startContainer == endContainer) {
                            ColorizeNodeFromTo(startContainer, size, startOffset, endOffset);
                        }
                        else {
                            if (startContainer.firstChild) {
                                var startLeaf = startContainer.childNodes[startOffset];
                            }
                            else {
                                var startLeaf = GetNextLeaf (startContainer);
                                ColorizeLeafFromTo(startContainer, size, startOffset, -1);
                            }
    
                            if (endContainer.firstChild) {
                                if (endOffset > 0) {
                                    var endLeaf = endContainer.childNodes[endOffset - 1];
                                }
                                else {
                                    var endLeaf = GetPreviousLeaf (endContainer);
                                }
                            }
                            else {
                                var endLeaf = GetPreviousLeaf (endContainer);
                                ColorizeLeafFromTo(endContainer, size, 0, endOffset);
                            }
    
                            while (startLeaf) {
                                var nextLeaf = GetNextLeaf (startLeaf);
                                ColorizeLeaf(startLeaf, size);
                                if (startLeaf == endLeaf) {
                                    break;
                                }
                                startLeaf = nextLeaf;
                            }
                        }
                    }
                }
                else {
                        // Internet Explorer before version 9
                    alert ("Your browser does not support this example!");
                }
            }
    
          

        </script>
    </head>
    <body contenteditable="true">
        Select some content on this page and use the buttons below to colorize the selected text.<br /><br />
        <button onclick="ColorizeSelection (12);">Font 12</button>
        <button onclick="ColorizeSelection (14);">Font 14</button>
        <button onclick="ColorizeSelection (18);">Font 18</button>
        <button onclick="ColorizeSelection (28);">Font 28</button>
        <br />
        <div>Some text for selection</div>
        <div contentEditable="true" id="editor"><b>Some bold text for selection.</b></div>
        <ul>
            <li>One </li>
            <li>Two </li>
            <li>Three </li>
            <li>Four </li>
        </ul>
    </body>
    </html>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

最后,我已经找到了解决方法来满足我的需求,如下所述。

  • 声明了一个变量“font_size”,默认大小为14。
  • 声明了一个点击处理程序,以便在按键时触发
  • 声明了一个函数“updateFontSizeForNewText”,用于在按键上创建新的span元素并应用保存在上述变量中​​的字体大小。
  • 通过将按下的键捕获到新创建的范围中来附加文本。

完整的更新代码如下所述。

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript">
        function GetNextLeaf(node) {
            while (!node.nextSibling) {
                node = node.parentNode;
                if (!node) {
                    return node;
                }
            }
            var leaf = node.nextSibling;
            while (leaf.firstChild) {
                leaf = leaf.firstChild;
            }
            return leaf;
        }

        function GetPreviousLeaf(node) {
            while (!node.previousSibling) {
                node = node.parentNode;
                if (!node) {
                    return node;
                }
            }
            var leaf = node.previousSibling;
            while (leaf.lastChild) {
                leaf = leaf.lastChild;
            }
            return leaf;
        }

        // If the text content of an element contains white-spaces only, then does not need to colorize
        function IsTextVisible(text) {
            for (var i = 0; i < text.length; i++) {
                if (text[i] != ' ' && text[i] != '\t' && text[i] != '\r' && text[i] != '\n')
                    return true;
            }
            return false;
        }

        function ColorizeLeaf(node, size) {
            if (!IsTextVisible(node.textContent))
                return;

            var parentNode = node.parentNode;
            // if the node does not have siblings and the parent is a span element, then modify its color
            if (!node.previousSibling && !node.nextSibling) {
                if (parentNode.tagName.toLowerCase() == "span") {
                    //parentNode.style.color = color;
                    parentNode.style.fontSize = size + "px";
                    return;
                }
            }

            // Create a span element around the node
            var span = document.createElement("span");
            //span.style.color = color;
            span.style.fontSize = size + "px";
            var nextSibling = node.nextSibling;

            parentNode.removeChild(node);
            span.appendChild(node);
            parentNode.insertBefore(span, nextSibling);
        }

        function ColorizeLeafFromTo(node, size, from, to) {
            var text = node.textContent;
            if (!IsTextVisible(text))
                return;

            if (from < 0)
                from = 0;
            if (to < 0)
                to = text.length;

            if (from == 0 && to >= text.length) {
                // to avoid unnecessary span elements
                ColorizeLeaf(node, size);
                return;
            }

            var part1 = text.substring(0, from);
            var part2 = text.substring(from, to);
            var part3 = text.substring(to, text.length);

            var parentNode = node.parentNode;
            var nextSibling = node.nextSibling;

            parentNode.removeChild(node);
            if (part1.length > 0) {
                var textNode = document.createTextNode(part1);
                parentNode.insertBefore(textNode, nextSibling);
            }
            if (part2.length > 0) {
                var span = document.createElement("span");
                //span.style.color = color;
                span.style.fontSize = size + "px";
                var textNode = document.createTextNode(part2);
                span.appendChild(textNode);
                parentNode.insertBefore(span, nextSibling);
            }
            if (part3.length > 0) {
                var textNode = document.createTextNode(part3);
                parentNode.insertBefore(textNode, nextSibling);
            }
        }

        function ColorizeNode(node, size) {
            var childNode = node.firstChild;
            if (!childNode) {
                ColorizeLeaf(node, size);
                return;
            }

            while (childNode) {
                // store the next sibling of the childNode, because colorizing modifies the DOM structure
                var nextSibling = childNode.nextSibling;
                ColorizeNode(childNode, size);
                childNode = nextSibling;
            }
        }

        function ColorizeNodeFromTo(node, size, from, to) {
            var childNode = node.firstChild;
            if (!childNode) {
                ColorizeLeafFromTo(node, size, from, to);
                return;
            }

            for (var i = from; i < to; i++) {
                ColorizeNode(node.childNodes[i], size);
            }
        }
        var font_size = 14;
        var selection_range;
        function ColorizeSelection(size) {

            if (window.getSelection) {  // all browsers, except IE before version 9
                var selectionRange = window.getSelection();

                if (selectionRange.isCollapsed) {
                    font_size = size;
                    document.getElementById("editor").addEventListener("keypress", clickHandler);
                    selection_range = selectionRange;
                }
                else {
                    var range = selectionRange.getRangeAt(0);
                    // store the start and end points of the current selection, because the selection will be removed
                    var startContainer = range.startContainer;
                    var startOffset = range.startOffset;
                    var endContainer = range.endContainer;
                    var endOffset = range.endOffset;
                    // because of Opera, we need to remove the selection before modifying the DOM hierarchy
                    selectionRange.removeAllRanges();

                    if (startContainer == endContainer) {
                        ColorizeNodeFromTo(startContainer, size, startOffset, endOffset);
                    }
                    else {
                        if (startContainer.firstChild) {
                            var startLeaf = startContainer.childNodes[startOffset];
                        }
                        else {
                            var startLeaf = GetNextLeaf(startContainer);
                            ColorizeLeafFromTo(startContainer, size, startOffset, -1);
                        }

                        if (endContainer.firstChild) {
                            if (endOffset > 0) {
                                var endLeaf = endContainer.childNodes[endOffset - 1];
                            }
                            else {
                                var endLeaf = GetPreviousLeaf(endContainer);
                            }
                        }
                        else {
                            var endLeaf = GetPreviousLeaf(endContainer);
                            ColorizeLeafFromTo(endContainer, size, 0, endOffset);
                        }

                        while (startLeaf) {
                            var nextLeaf = GetNextLeaf(startLeaf);
                            ColorizeLeaf(startLeaf, size);
                            if (startLeaf == endLeaf) {
                                break;
                            }
                            startLeaf = nextLeaf;
                        }
                    }
                }
            }
            else {
                // Internet Explorer before version 9
                alert("Your browser does not support this example!");
            }
        }

        function pasteHtmlAtCaret(html) {
            var sel, range;
            if (window.getSelection) {
                // IE9 and non-IE
                sel = window.getSelection();
                if (sel.getRangeAt && sel.rangeCount) {
                    range = sel.getRangeAt(0);
                    range.deleteContents();

                    // Range.createContextualFragment() would be useful here but is
                    // non-standard and not supported in all browsers (IE9, for one)
                    var el = document.createElement("div");
                    el.innerHTML = html;
                    var frag = document.createDocumentFragment(), node, lastNode;
                    while ((node = el.firstChild)) {
                        lastNode = frag.appendChild(node);
                    }
                    range.insertNode(frag);

                    // Preserve the selection
                    if (lastNode) {
                        range = range.cloneRange();
                        range.setStartAfter(lastNode);
                        range.collapse(lastNode);
                        sel.removeAllRanges();
                        sel.addRange(range);
                    }
                }
            } else if (document.selection && document.selection.type != "Control") {
                // IE < 9
                document.selection.createRange().pasteHTML(html);
            }
        }

        var clickHandler = function (event) {
            document.getElementById("editor").removeEventListener("keypress", clickHandler);
            updateFontSizeForNewText(event);
        };

        function updateFontSizeForNewText(e) {

            var timestamp = new Date().getUTCMilliseconds();
            var key="";
            if (isValidKeyPress(e)) {

                event.preventDefault();
                key = e.key;
                var span = document.createElement("span");
                span.id = timestamp;
                var txt = document.createTextNode(key);
                span.style.fontSize = font_size + "px";
                span.appendChild(txt);
                var wrap = document.createElement('div');
                wrap.appendChild(span.cloneNode(true));
                pasteHtmlAtCaret(wrap.innerHTML);
            }

        }
        function isValidKeyPress(e) {
            var keycode = e.keyCode;
            var valid =
                (keycode > 47 && keycode < 58) || // number keys
                (keycode > 64 && keycode < 91) || // letter keys
                (keycode > 95 && keycode < 112) || // numpad keys
                (keycode > 185 && keycode < 193) || // ;=,-./` (in order)
                (keycode > 218 && keycode < 223);   // [\]' (in order)
            return valid;
        }
    </script>
</head>
<body>
    Select some content on this page and use the buttons below to colorize the selected text.<br /><br />
    <button onclick="ColorizeSelection (12);">Font 12</button>
    <button onclick="ColorizeSelection (14);">Font 14</button>
    <button onclick="ColorizeSelection (18);">Font 18</button>
    <button onclick="ColorizeSelection (28)">Font 28</button>
    <!--<button onclick="ColorizeSelection ('#FF0000');">Set color to red!</button>
    <button onclick="ColorizeSelection ('#0000FF');">Set color to blue!</button>-->
    <br />
    <div>Some text for selection</div>
    <div contentEditable="true" id="editor"><b>Some bold text for selection.</b></div>
    <ul>
        <li>One </li>
        <li>Two </li>
        <li>Three </li>
        <li>Four </li>
    </ul>
</body>
</html>

答案 1 :(得分:0)

您正在使用click事件处理程序触发所有内容。此时,您将计算所选内容并从那里开始。问题是,当您点击某些内容时,未选中。由于click事件触发了焦点更改,您将丢失任何当前选择!

我已将onclick处理程序更改为onmousedown处理程序。这会使代码工作,但可能不是您想要的。只要按下任何鼠标按钮,mousedown事件就会重复触发。您可以检测mouseup事件并确保只运行一次代码直到下一次mouseup,或者有一种方法可以使其适应onclick。为此,您还可以实现一个onselect处理程序。

使用onselect,每次进行选择时,处理程序都会运行。您可以在此时获取当前选择并将其保存在变量中。然后,当点击处理程序触发时,您可以检查已保存的变量,该变量将包含最后一个已知选择。

&#13;
&#13;
                function GetNextLeaf (node) {
                    while (!node.nextSibling) {
                        node = node.parentNode;
                        if (!node) {
                            return node;
                        }
                    }
                    var leaf = node.nextSibling;
                    while (leaf.firstChild) {
                        leaf = leaf.firstChild;
                    }
                    return leaf;
                }
        
                function GetPreviousLeaf (node) {
                    while (!node.previousSibling) {
                        node = node.parentNode;
                        if (!node) {
                            return node;
                        }
                    }
                    var leaf = node.previousSibling;
                    while (leaf.lastChild) {
                        leaf = leaf.lastChild;
                    }
                    return leaf;
                }
        
                    // If the text content of an element contains white-spaces only, then does not need to colorize
                function IsTextVisible (text) {
                    for (var i = 0; i < text.length; i++) {
                        if (text[i] != ' ' && text[i] != '\t' && text[i] != '\r' && text[i] != '\n')
                            return true;
                    }
                    return false;
                }
        
                function ColorizeLeaf (node, size) {
                    if (!IsTextVisible (node.textContent))
                        return;
        
                    var parentNode = node.parentNode;
                        // if the node does not have siblings and the parent is a span element, then modify its color
                    if (!node.previousSibling && !node.nextSibling) {
                        if (parentNode.tagName.toLowerCase () == "span") {
                            //parentNode.style.color = color;
                            parentNode.style.fontSize = size+"px";
                            return;
                        }
                    }
        
                        // Create a span element around the node
                    var span = document.createElement("span");
                    //span.style.color = color;
                    span.style.fontSize = size + "px";
                    var nextSibling = node.nextSibling;
        
                    parentNode.removeChild (node);
                    span.appendChild (node);
                    parentNode.insertBefore (span, nextSibling);
                }
        
                function ColorizeLeafFromTo (node, size, from, to) {
                    var text = node.textContent;
                    if (!IsTextVisible (text))
                        return;
        
                    if (from < 0)
                        from = 0;
                    if (to < 0)
                        to = text.length;
        
                    if (from == 0 && to >= text.length) {
                            // to avoid unnecessary span elements
                        ColorizeLeaf(node, size);
                        return;
                    }
        
                    var part1 = text.substring (0, from);
                    var part2 = text.substring (from, to);
                    var part3 = text.substring (to, text.length);
        
                    var parentNode = node.parentNode;
                    var nextSibling = node.nextSibling;
        
                    parentNode.removeChild (node);
                    if (part1.length > 0) {
                        var textNode = document.createTextNode (part1);
                        parentNode.insertBefore (textNode, nextSibling);
                    }
                    if (part2.length > 0) {
                        var span = document.createElement ("span");
                        //span.style.color = color;
                        span.style.fontSize = size+"px";
                        var textNode = document.createTextNode (part2);
                        span.appendChild (textNode);
                        parentNode.insertBefore (span, nextSibling);
                    }
                    if (part3.length > 0) {
                        var textNode = document.createTextNode (part3);
                        parentNode.insertBefore (textNode, nextSibling);
                    }
                }
        
                function ColorizeNode (node, size) {
                    var childNode = node.firstChild;
                    if (!childNode) {
                        ColorizeLeaf(node, size);
                        return;
                    }
        
                    while (childNode) {
                            // store the next sibling of the childNode, because colorizing modifies the DOM structure
                        var nextSibling = childNode.nextSibling;
                        ColorizeNode(childNode, size);
                        childNode = nextSibling;
                    }
                }
        
                function ColorizeNodeFromTo(node, size, from, to) {
                    var childNode = node.firstChild;
                    if (!childNode) {
                        ColorizeLeafFromTo(node, size, from, to);
                        return;
                    }
        
                    for (var i = from; i < to; i++) {
                        ColorizeNode(node.childNodes[i], size);
                    }
                }
                
                function UpdateCurrentSelection(event) {
                  var selection = window.getSelection();
                  
                }
        
                function ColorizeSelection(size) {
                    if (window.getSelection) {  // all browsers, except IE before version 9
                        var selectionRange = window.getSelection ();
        
                        if (selectionRange.isCollapsed) {
                           // no idea on how to apply font size here. at cursor point.
                        }                            
                        else {
                            var range = selectionRange.getRangeAt (0);
                                // store the start and end points of the current selection, because the selection will be removed
                            var startContainer = range.startContainer;
                            var startOffset = range.startOffset;
                            var endContainer = range.endContainer;
                            var endOffset = range.endOffset;
                                // because of Opera, we need to remove the selection before modifying the DOM hierarchy
                            selectionRange.removeAllRanges ();
        
                            if (startContainer == endContainer) {
                                ColorizeNodeFromTo(startContainer, size, startOffset, endOffset);
                            }
                            else {
                                if (startContainer.firstChild) {
                                    var startLeaf = startContainer.childNodes[startOffset];
                                }
                                else {
                                    var startLeaf = GetNextLeaf (startContainer);
                                    ColorizeLeafFromTo(startContainer, size, startOffset, -1);
                                }
        
                                if (endContainer.firstChild) {
                                    if (endOffset > 0) {
                                        var endLeaf = endContainer.childNodes[endOffset - 1];
                                    }
                                    else {
                                        var endLeaf = GetPreviousLeaf (endContainer);
                                    }
                                }
                                else {
                                    var endLeaf = GetPreviousLeaf (endContainer);
                                    ColorizeLeafFromTo(endContainer, size, 0, endOffset);
                                }
        
                                while (startLeaf) {
                                    var nextLeaf = GetNextLeaf (startLeaf);
                                    ColorizeLeaf(startLeaf, size);
                                    if (startLeaf == endLeaf) {
                                        break;
                                    }
                                    startLeaf = nextLeaf;
                                }
                            }
                        }
                    }
                    else {
                            // Internet Explorer before version 9
                        alert ("Your browser does not support this example!");
                    }
                }
        
              
&#13;
        <!DOCTYPE html>
        <html>
        <body contenteditable="true">
            Select some content on this page and use the buttons below to colorize the selected text.<br /><br />
            <button onmousedown="ColorizeSelection (12);">Font 12</button>
            <button onmousedown="ColorizeSelection (14);">Font 14</button>
            <button onmousedown="ColorizeSelection (18);">Font 18</button>
            <button onmousedown="ColorizeSelection (28);">Font 28</button>
            <br />
            <div>Some text for selection</div>
            <div contentEditable="true" id="editor"><b>Some bold text for selection.</b></div>
            <ul>
                <li>One </li>
                <li>Two </li>
                <li>Three </li>
                <li>Four </li>
            </ul>
        </body>
        </html>
&#13;
&#13;
&#13;