【问题标题】:Make selected text bold/unbold使选定的文本加粗/不加粗
【发布时间】:2014-01-02 09:55:07
【问题描述】:

当您单击按钮时,我将所选文本包装在跨度标签中。如果我随后选择另一段文本并单击按钮,该文本也会被包含在标签中。但是,当我选择一段已经包含在 span 标签中的文本时,我想删除这些标签以取消文本的加粗,而不是将这些标签包含在更多标签中。

HTML

<div contenteditable="true" class="textEditor">Some random text.</div>

<a href="#" class="embolden">Bold</a>

JS

$('.embolden').click(function(){
    var highlight = window.getSelection();  
    var span = '<span class="bold">' + highlight + '</span>';
    var text = $('.textEditor').html();
    $('.textEditor').html(text.replace(highlight, span));
});

JSFiddle Demo

我可能对这个请求很贪心,但我只选择了一段已经包含在 span 标签中的文本的一部分,但不是全部,我想在选择开始时关闭原始标签,然后立即打开一个新标签,然后在选择结束时关闭新标签,然后再打开一个新标签。

【问题讨论】:

  • 您的目标是特定浏览器吗?当我在 Chrome 中检查 window.getSelection() 时,我得到了一个对象。
  • 并非有意针对特定浏览器。我希望该解决方案可以在非常现代的浏览器中使用。无需支持任何 IE 或 Opera。
  • 给我一点,我会为你的目标写一个完整的解决方案——它有点复杂,b/c contenteditable 部分也可以有其他标签。编辑:做完整的解决方案 b/c 我认为这对我也很有用。 :)
  • 酷,期待它的伙伴:)
  • 为什么不直接使用document.execCommand('bold', false, null); 而不是spans?

标签: javascript jquery


【解决方案1】:

当您可以使用内置功能时,为什么要尝试手动加粗文本。现代浏览器实现了execCommand 功能,允许在文本上加粗、下划线等。你可以只写:

$('.embolden').click(function(){
    document.execCommand('bold');
});

并且选定的文本将变为粗体,如果它已经是粗体,文本样式将被删除。

可以在here 找到命令列表和一个小文档。 (更多关于浏览器支持here)。

$(document).ready(function() {
  $('#jBold').click(function() {
    document.execCommand('bold');
  });
});
#fake_textarea {
  width: 100%;
  height: 200px;
  border: 1px solid red;
}

button {
  font-weigth: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="jBold"><b>B</b></button>
<div id='fake_textarea' contenteditable>
  Select some text and click the button to make it bold...
  <br>Or write your own text
</div>

【讨论】:

  • 直到现在才意识到这是一种选择。您能否提供一个简短的教程来展示如何在 div 上实现基本命令?
  • 我自己回答了这个问题。但是,如果您使用 Fiddle 代码编辑您的答案,我会给您打勾。谢谢朋友,太棒了。
  • 这确实很不错,但请记住,某些浏览器在加粗文本时的行为会有所不同。使用这个时需要测试所有浏览器。可以在这里找到一些解释:quirksmode.org/dom/execCommand.html
  • @Jagi 是否可以更新您的代码?我知道你的答案已经超过 1 年了,但是找不到 jsfiddle :(
  • 我在苦苦挣扎,从你的链接中找到
【解决方案2】:

从这个答案复制的函数:Get parent element of a selected text

还没有真正完善这一点,我认为这只适用于精确选择,但它让您了解如何解决这个问题。 click 函数检查当前选择的父元素是否具有类“bold”,如果是,它会再次用原始选择替换该元素。

http://jsfiddle.net/XCb95/4/

jQuery(function($) {
    $('.embolden').click(function(){
        var highlight = window.getSelection();  
        var span = '<span class="bold">' + highlight + '</span>';
        var text = $('.textEditor').html();

       var parent = getSelectionParentElement();
        if($(parent).hasClass('bold')) {
              $('.textEditor').html(text.replace(span, highlight));
        } else {
            $('.textEditor').html(text.replace(highlight, span));
        }

    });
});

function getSelectionParentElement() {
    var parentEl = null, sel;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            parentEl = sel.getRangeAt(0).commonAncestorContainer;
            if (parentEl.nodeType != 1) {
                parentEl = parentEl.parentNode;
            }
        }
    } else if ( (sel = document.selection) && sel.type != "Control") {
        parentEl = sel.createRange().parentElement();
    }
    return parentEl;
}

【讨论】:

    【解决方案3】:

    这样的事情应该可以解决问题:

    var span = '';
    
    jQuery(function($) {
        $('.embolden').click(function(){
            var highlight = window.getSelection();
            if(highlight != ""){
                span = '<span class="bold">' + highlight + '</span>';
            }else{
                highlight = span;
                span = $('span.bold').html();
            }
            var text = $('.textEditor').html();
            $('.textEditor').html(text.replace(highlight, span));
        });
    });
    

    【讨论】:

      【解决方案4】:

      终于明白了:

      <!DOCTYPE html>
      <html>
      <head>
      <style type="text/css">
      .emphasized {
        text-decoration: underline;
        font-weight: bold;
        font-style: italic;
      }
      </style>
      </head>
      <body>
        <button type="button" onclick="applyTagwClass(this);" data-tag="span" data-tagClass="emphasized">Bold</button>
        <div contenteditable="true" class="textEditor">
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In malesuada quis lorem non consequat. Proin diam magna, molestie nec leo non, sodales eleifend nibh. Suspendisse a tellus facilisis, adipiscing dui vitae, rutrum mi. Curabitur aliquet
            lorem quis augue laoreet feugiat. Nulla at volutpat enim, et facilisis velit. Nulla feugiat quis augue nec sodales. Nulla nunc elit, viverra nec cursus non, gravida ac leo. Proin vehicula tincidunt euismod.</p>
          <p>Suspendisse non consectetur arcu, ut ultricies nulla. Sed vel sem quis lacus faucibus interdum in sed quam. Nulla ullamcorper bibendum ornare. Proin placerat volutpat dignissim. Ut sit amet tellus enim. Nulla ut convallis quam. Morbi et
            sollicitudin nibh. Maecenas justo lectus, porta non felis eu, condimentum dictum nisi. Nulla eu nisi neque. Phasellus id sem congue, consequat lorem nec, tincidunt libero.</p>
          <p>Integer eu elit eu massa placerat venenatis nec in elit. Ut ullamcorper nec mauris et volutpat. Phasellus ullamcorper tristique quam. In pellentesque nisl eget arcu fermentum ornare. Aenean nisl augue, mollis nec tristique a, dapibus quis urna.
            Vivamus volutpat ullamcorper lectus, et malesuada risus adipiscing nec. Ut nec ligula orci. Morbi sollicitudin nunc tempus, vestibulum arcu nec, feugiat velit. Aenean scelerisque, ligula sed molestie iaculis, massa risus ultrices nisl, et placerat
            augue libero vitae est. Pellentesque ornare adipiscing massa eleifend fermentum. In fringilla accumsan lectus sit amet aliquam.</p>
        </div>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script>
            function applyTagwClass(self) {
              var selection = window.getSelection();
              if (selection.rangeCount) {
                var text = selection.toString();
                var range = selection.getRangeAt(0);
                var parent = $(range.startContainer.parentNode);
                if (range.startOffset > 0 && parent.hasClass(self.attributes['data-tagClass'].value)) {
                  var prefix = '<' + self.attributes['data-tag'].value + ' class="' + self.attributes['data-tagClass'].value + '">' + parent.html().substr(0,selection.anchorOffset) + '</' + self.attributes['data-tag'].value + '>';
                  var suffix = '<' + self.attributes['data-tag'].value + ' class="' + self.attributes['data-tagClass'].value + '">' + parent.html().substr(selection.focusOffset) + '</' + self.attributes['data-tag'].value + '>';
                  parent.replaceWith(prefix + text + suffix);
                } else {
                  range.deleteContents();
                  range.insertNode($('<' + self.attributes['data-tag'].value + ' class="' + self.attributes['data-tagClass'].value + '">' + text + '</' + self.attributes['data-tag'].value + '>')[0]);
                  //Remove all empty elements (deleteContents leaves the HTML in place)
                  $(self.attributes['data-tag'].value + '.' + self.attributes['data-tagClass'].value + ':empty').remove();
                }
              }
            }
          </script>
      </body>
      </html>
      

      您会注意到我将按钮扩展为具有一对data- 属性。它们应该是不言自明的。

      这也将取消应用于当前目标元素内的选定文本的子部分(所有内容都按类名进行)。

      如您所见,我使用的类是事物的组合,因此这为您提供了更多功能。

      【讨论】:

      • 感谢朋友的回答。我给了你一个赞成票。我决定给 Jagi 打勾,因为您的解决方案中仍然存在一些错误。例如,当你有两个单独的词加粗,中间有另一个词,然后选择所有 3 个词来加粗,就搞砸了。
      • @Moppy 好收获!我已经调整了上面的代码以纠正这种情况。
      • 如何使用 textarea 而不是 contenteditable div?@Jeremy Miller
      • 与上述@JeremyMiller 相同的问题
      【解决方案5】:

      此代码通过 textEditor 的内容并删除所有 span 标签。它应该可以解决问题。

      jQuery(function($) {
          $('.embolden').click(function(){
              $('.textEditor span').contents().unwrap();
              var highlight = window.getSelection();  
              var span = '<span class="bold">' + highlight + '</span>';
              var text = $('.textEditor').html();
              $('.textEditor').html(text.replace(highlight, span));
          });
      });
      

      【讨论】:

      • 我相信其他 span 标签需要保留,只处理单个封闭...就像你有 5 个段落和 3 个单词被加粗。
      • 谢谢队友,但当前选择之外的任何跨度标签都需要保持完整,这样该解决方案将不起作用。
      • 哦,我明白了。让我看看我能不能弄清楚。当我这样做时,我会编辑我的答案。
      【解决方案6】:

      现代浏览器利用 execCommand 功能,可以很容易地使文本加粗。它还提供下划线等其他样式。

      <a href="#" onclick="emboldenFont()">Bold</a>
      
      function emboldenFont() {
          document.execCommand('bold', false, null);
      }
      

      【讨论】:

        【解决方案7】:

        如果您希望使用 键盘 来加粗字符,可以使用以下 (Mac):

        $(window).keydown(function(e) {
          if (e.keyCode >= 65 && e.keyCode <= 90) {
            var char = (e.metaKey ? '⌘-' : '') + String.fromCharCode(e.keyCode)
            if(char =='⌘-B') {
            document.execCommand('bold')
            }
          }
        }) 
        

        使用键盘加粗字符:

        【讨论】:

          【解决方案8】:

          check this 是你想要的吗???

          使用

          .toggleclass()
          

          (仅将文本编辑器类中的所有文本设为粗体)

          【讨论】:

          • 他只想要文本编辑器的子选择加粗。不是整个文本编辑器。
          猜你喜欢
          • 1970-01-01
          • 2014-04-15
          • 2020-04-27
          • 2016-06-07
          • 2014-01-25
          • 1970-01-01
          • 1970-01-01
          • 2011-06-03
          • 2017-01-23
          相关资源
          最近更新 更多