【问题标题】:jQuery: wrapAll() span elements while retaining white spacejQuery:wrapAll() 跨越元素,同时保留空白
【发布时间】:2017-01-12 21:32:57
【问题描述】:

我有一个文本,每个单词都用span 元素包裹,以使它们可点击。我希望能够通过单击要突出显示的第一个和最后一个单词来突出显示文本的一部分,然后单击一个单独的按钮以执行突出显示(即,将每个单词包装在所选的第一个和最后一个单词之间(包括)。在突出显示的部分之后也会添加评论。我已经取得了进展,并且已经完成了这部分:

HTML:

<div id="textbox">
<span>Foo</span> <span>foo</span> <span>foo</span> <span>foo</span> 
<span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> 
<span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span>.
</div>
<input id="commentbox" placeholder="Type your comment here"> 
<button id="exechighlight" value="Highlight">

JavaScript:

$('#textbox > span').click(function() {
  $(this).addClass('selected');
});

$('#exechighlight').click(function(){
if($('#commentbox').val() !== '') {
  $('.selected').filter(":last").after(' <span class="comment">' + $('#commentbox').val() + '</span>');
} else {
  $('.selected').filter(':last').after(' <span class="comment">Default comment</span>');
}
$('.selected').filter(":first").nextUntil('.comment').andSelf().wrapAll('<span class="highlight">');
$('.selected').removeClass('selected');
$('#commentbox').val('');
});

我可以很好地包装东西,但wrapAll() 似乎没有保留包装的span 元素之间的空格。我尝试过使用 CSS,但无济于事:

.highlight {
  background-color: #f00; 
  white-space: pre-wrap; 
  white-space: -moz-pre-wrap;
}

如何进行?我还需要能够撤消突出显示,即解开 &lt;span class='highlight'&gt; 并保留原始间距。

【问题讨论】:

  • 如果您使用 Stack Snippets(@ 987654329@ 工具栏按钮)。
  • 感谢您指出这一点。下次我需要发布问题时,我会确保记住这一点!

标签: jquery jquery-selectors jquery-events


【解决方案1】:

wrapAll() 似乎没有保留包裹的span 元素之间的空格

确实不应该,因为它们不在您说要包装的 jQuery 集中。 nextUntil 只查看元素,而不查看文本节点。

您需要自己构建 jQuery 集,包括跨度之间的文本节点。见 cmets:

$("#btn").on("click", function() {
  // Find the selected span
  var sel = $(".selected");
  
  // Find the comment span (raw, no jQuery wrapper)
  var comment = sel.siblings(".comment")[0];
  
  // Gather up all nodes (including text nodes) following it, up until the comment element
  var node = sel[0];
  var nodes = [];
  while (node && node !== comment) {
    nodes.push(node);
    node = node.nextSibling;
  }
  
  // Disregard final text node if any
  if (nodes.length && nodes[nodes.length - 1].nodeType === 3) {
    --nodes.length;
  }
  
  // Get a jQuery set for them, and wrap it
  $(nodes).wrapAll("<span class='wrapper'></span>");
});
.wrapper {
  border: 1px solid red;
}
<div>
  <span class="selected">one</span>
  <span>two</span>
  <span>three</span>
  <span class="comment">The comment</span>
</div>
<input type="button" id="btn" value="Click Me">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

【讨论】:

    【解决方案2】:

    nextUntil() 方法不包括textnode。您还需要借助 jQuery 中的 contents() 方法获取 textNode

    $('#textbox > span').click(function() {
      $(this).addClass('selected');
    });
    
    $('#exechighlight').click(function() {
      if ($('#commentbox').val() !== '') {
        $('.selected').filter(":last").after(' <span class="comment">' + $('#commentbox').val() + '</span>');
      } else {
        $('.selected').filter(':last').after(' <span class="comment">Default comment</span>');
      }
      getAllNode($('.selected').filter(":first").nextUntil('.comment').andSelf()).wrapAll('<span class="highlight">');
      $('.selected').removeClass('selected');
      $('#commentbox').val('');
    });
    
    // method for getting the element which also includes textnode
    function getAllNode($sel) {
      // get the first element from selector
      var $first = $sel.first(),
        // get the last element from selector
        $last = $sel.last(),
        // flag variable for filter method
        match = false;
      // get all nodes includes text node of it's parent
      return $sel.parent().contents().filter(function() {
        // filter out element eleemnt in between the first and last including the first and last
        if ($(this).is($first) || $(this).is($last)) {
          match = !match;
          return true;
        }
        return match;
      });
    }
    .highlight {
      background-color: #f00;
      white-space: pre-wrap;
      white-space: -moz-pre-wrap;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="textbox">
      <span>Foo</span>  <span>foo</span>  <span>foo</span>  <span>foo</span> 
      <span>foo</span>  <span>foo</span>  <span>foo</span>  <span>foo</span> 
      <span>foo</span>  <span>foo</span>  <span>foo</span>  <span>foo</span>.
    </div>
    <input id="commentbox" placeholder="Type your comment here">
    <button id="exechighlight" value="Highlight">

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 2020-07-23
      • 2012-07-02
      • 2010-09-20
      相关资源
      最近更新 更多