【问题标题】:What is a wrap method to wrap only a part of a string?什么是仅包装字符串的一部分的包装方法?
【发布时间】:2016-01-26 13:56:35
【问题描述】:

我有一个这样的 HTML:

<div>
     <h3>How are you? Fine?</h3>
</div>

我想用两个数字 n 和 m 将其转化为不同的东西,例如: 如果 n=5 且 m=12

<div>
     <h3>How 
            <span class="yellow">are you?</span>
      Fine?</h3>
</div>

换句话说,我想使用两个数字来“突出显示”字符串的一部分,这两个数字指定“突出显示”的开始和结束(以字符为单位)。

我试过了,但没用:

//in the previous example it will be a xpath selector for div/h3
var selection=$(document.body).xpath(selector).text();

//it will be "are you?"
var substring=selection.substring(n,m);

//it would make that i want, but it doesn't
                                $(document.body).xpath(selector).contents().filter(function() {
                        return substring;
                    }).wrap("<span class=\"yellow\"></span>");
}

【问题讨论】:

  • 也许thisthat 回答可以帮助你
  • 你用的是什么 xpath 插件?

标签: javascript jquery select highlight


【解决方案1】:

一种方法是 - 代替包装,将 h3 的内容替换为切片操作版本。

查看这个 JSFiddle http://jsfiddle.net/9LeL3f3n/21/

<div>
    <h3>How are you? Fine?</h3>
</div>


$(document).ready(function() {

    var highlight = function(str, start, end) {
      return str.slice(0,start-1) + 
        '<span style="color:#ffff00">' + 
        str.substring(start-1, end) + 
        '</span>' +  
        str.slice(-1 * (str.length - end));
    };

    var n = 5;
    var m = 12;

    $('h3').html(highlight($('h3').html(),n,m)); 

});

【讨论】:

    【解决方案2】:

    我建议编写你自己的插件来实现这一点,如果只是因为它看起来对重复使用很有用。也就是说,我将提供以下方法,该方法有效地拆分 textNode 节点,使用textNode.splitText() 并将相关部分附加到创建的元素,然后再重新插入该节点,并将 textNodes 周围的元素重新插入父元素:

    // a simple plugin approach, taken from:
    // https://learn.jquery.com/plugins/basic-plugin-creation/
    (function ($) {
    
        // defining the name of the plugin ('highlight'):
        $.fn.highlight = function (opts) {
    
            // the default settings, used if no arguments are
            // passed into the plugin via the 'opts' Object:
            var settings = {
                'start' : 0,
                'end' : 1,
                'wrapper' : 'span',
                'class' : 'highlight',
                'css' : {
                    'color' : 'yellow'
                }
            },
                // 'empty' declared variables for later use:
                node, textMiddle, textEnd;
    
            // iterating over the 'opts' Object using
            // a for...in loop:
            for (var prop in opts) {
    
                // if the 'opts' Object has an own property 'prop'
                // (not one inherited from its prototype chain):
                if (opts.hasOwnProperty(prop)) {
    
                    // we update the 'settings' Object to
                    // be equal to the 'opts' Object property-value:
                    settings[prop] = opts[prop];
                }
            }
    
            // using parseInt() to ensure that we're working
            // with numbers, rather than strings, and that those
            // numbers are in base-10:
            settings.start = parseInt(settings.start, 10);
            settings.end = parseInt(settings.end, 10);
    
            // normalising the settings.wrapper string, ensuring that
            // if the user passes in '<span>' (or '<<<<<span>', etc)
            // we remove those (this could be made even safer by only
            // allowing the first consecutive string of alphabetical
            // characters):
            settings.wrapper = settings.wrapper.replace(/<|>/g,'');
    
            // here we iterate over, and return, the jQuery collection
            // to allow for chaining to continue (here 'this' is the
            // jQuery collection of nodes/elements):
            return this.each(function () {
    
                // here this is the DOM node from the collection.
    
                // and here we iterate over the childNodes of each
                // DOM node from that collection:
                $(this).contents().each(function () {
    
                    // if the current childNode is nodeType 3 (a textNode)
                    // AND the length of the nodeValue (the text itself)
                    // is greater than, or equal to, the settings.end:
                    if (this.nodeType === 3 && this.nodeValue.length >= settings.end) {
    
                        // we create a new element equal to the
                        // settings.wrapper argument passed in by
                        // the user (or the default):
                        node = document.createElement(settings.wrapper);
    
                        // if we have a settings.css Object:
                        if (settings.css) {
    
                            // we iterate over that Object with a
                            // for...in loop (as above):
                            for (var prop in settings.css){
                                if (settings.css.hasOwnProperty(prop)) {
    
                                    // setting the node's style property
                                    // to be equal to the property-value
                                    // of the settings.css Object:
                                    node.style[prop] = settings.css[prop];
                                }
                            }
                        }
    
                        // if we have a settings.class:
                        if (settings.class) {
    
                            // we use Array.prototype.forEach
                            Array.prototype.forEach
                              // with Function.prototype.call()
                              // to iterate over the resulting array
                              // of splitting the settings.class
                              // String on white-space characters:
                              .call(settings.class.split(/\s+/),
                                  // the 'classname' argument is the
                                  // class-name from the string, now
                                  // in the Array over which we're iterating:
                                  function (classname) {
    
                                      // here we add the trimmed classname
                                      // string (removing the leading and
                                      // trailing white=space) to the
                                      // list of classes of the node:
                                      node.classList.add(classname.trim());
                                  });
                        }
    
                        // here we split the textNode (this) using
                        // Text.splitText(offset); which converts
                        // one textNode into two separate textNodes
                        // and returns the second (newly-created) 
                        // textNode ('this' remains 'this' but with
                        // shortened text):
                        textMiddle = this.splitText(settings.start);
    
                        // and again, but this time we have to compensate
                        // for already shortening the textNode, and
                        // and so subtract the offset from the settings.end:
                        textEnd = textMiddle.splitText(settings.end - settings.start);
    
                        // appending the textNode to the created
                        // element:
                        node.appendChild(textMiddle);
    
                        // inserting the created node after the original
                        // textNode:                        
                        this.parentNode.insertBefore(node, this.nextSibling);
    
    
                    }
                });
    
            });
        };
    
    // passing jQuery into the plugin in order to allow us to use
    // the $ alias within the plugin:
    })(jQuery);
    
    // using the plugin:
    $('div h3').highlight({
        // setting the 'start' offset:
        'start' : 4,
        // the end index/offset:
        'end' : 12,
        // specifying classes to add to the created element(s):
        'class' : 'highlight classes',
        // setting the CSS properties of the created element(s):
        'css' : {
            'color' : '#f89',
            'text-decoration' : 'underline'
        }
    });
    

    (function($) {
      $.fn.highlight = function(opts) {
        var settings = {
            'start': 0,
            'end': 1,
            'wrapper': 'span',
            'class': 'highlight',
            'css': {
              'color': 'yellow'
            }
          },
          node, textMiddle, textEnd;
    
        for (var prop in opts) {
          if (opts.hasOwnProperty(prop)) {
            settings[prop] = opts[prop];
          }
        }
    
        settings.wrapper = settings.wrapper.replace(/<|>/g, '');
    
        return this.each(function() {
    
          $(this).contents().each(function() {
            if (this.nodeType === 3 && this.nodeValue.length >= settings.end) {
              node = document.createElement(settings.wrapper);
    
              if (settings.css) {
                for (var prop in settings.css) {
                  if (settings.css.hasOwnProperty(prop)) {
                    node.style[prop] = settings.css[prop];
                  }
                }
              }
    
              if (settings.class) {
                Array.prototype.forEach.call(settings.class.split(/\s+/), function(classname) {
                  node.classList.add(classname.trim());
                });
              }
    
              textMiddle = this.splitText(settings.start);
              textEnd = textMiddle.splitText(settings.end - settings.start);
              node.appendChild(textMiddle);
    
              this.parentNode.insertBefore(node, this.nextSibling);
    
    
            }
          });
    
        });
      };
    })(jQuery);
    
    $('div h3').highlight({
      'start': 4,
      'end': 12,
      'class': 'highlight classes',
      'css': {
        'color': '#f89',
        'text-decoration': 'underline'
      }
    });
    .highlight {
      font-style: italic;
    }
    .classes {
      font-variant: small-caps;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div>
      <h3>How are you? Fine?</h3>
    </div>

    外部JS Fiddle demo

    参考资料:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 2020-04-26
      相关资源
      最近更新 更多