0

我有一个 jQuery 插件,在输入单词时会突出显示文本中的相应值。单词也可以用空格分隔。我的问题是当有一个带有特殊字符(ü、ö 或 ä)的单词时。例如,当我输入“dölor”或“faücibus”时,突出显示会中断,使其看起来像“d lor”或“fa cibus”。

jsfiddle:http: //jsfiddle.net/qbwe4/1/

HTML

<body>
  <input type="text" class="span1 disabled" id="field1" name="field1"><br>
  <input type="text" class="span1 disabled" id="field2" name="field2"><br>
  <p>Vestibulum rhoncus urna sed urna euismod, ut cursus erüos molestie.
  Nulla sed ante ut diam gravida auctor eu quis augue.
  Donec egäet diam malesuada, consectetur orci at, ultrices tellus.
  Duis id dui vel sem consequat rütrum eget non orci.
  Nullam sit amet libero odiö. Vestibulum sapien sapien, molestie quis porta nec,
  sodales nec felis. Mauris vehicula, erat eu consectetur viverra,
  dui tellus laoreet dölor, quis faücibus turpis eros non mi.</p>
</body>

CSS:

.highlight2, .highlight1 {
  background-color: #fff34d;
  -moz-border-radius: 5px;
  /* FF1+ */
  -webkit-border-radius: 5px;
  /* Saf3-4 */
  border-radius: 5px;
  /* Opera 10.5, IE 9, Saf5, Chrome */
  -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  /* FF3.5+ */
  -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  /* Saf3.0+, Chrome */
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  /* Opera 10.5+, IE 9.0 */
}
.highlight2, .highlight1 {
  padding:1px 4px;
  margin:0 -4px;
}
.highlight2 {
  background-color: #cecece;
}

脚本:

$(function () {
  $('#field1').bind('keyup change', function (ev) {
    // pull in the new value
    var searchTerm = $(this).val();
    // remove any old highlighted terms
    $('body').removeHighlight('span.highlight1');
    // disable highlighting if empty
    if (searchTerm) {
      var terms = searchTerm.split(/\W+/);
      $.each(terms, function (_, term) {
        // highlight the new term
        term = term.trim();
        if (term != "") $('body').highlight(term, 'highlight1');
      });
    }
  });
  $('#field2').bind('keyup change', function (ev) {
    // pull in the new value
    var searchTerm = $(this).val();
    // remove any old highlighted terms
    $('body').removeHighlight(['span.highlight2']);
    // disable highlighting if empty
    if (searchTerm) {
      var terms = searchTerm.split(/\W+/);
      $.each(terms, function (_, term) {
        // highlight the new term
        term = term.trim();
        if (term != "") $('body').highlight(term, 'highlight2');
      });
    }
  });
});

jQuery.fn.highlight = function (pat, className) {
  function innerHighlight(node, pat) {
    var skip = 0;
    if (node.nodeType == 3) {
      var pos = node.data.toUpperCase().indexOf(pat);
      if (pos >= 0) {
        var spannode = document.createElement('span');
        spannode.className = className || 'highlight';
        var middlebit = node.splitText(pos);
        var endbit = middlebit.splitText(pat.length);
        var middleclone = middlebit.cloneNode(true);
        spannode.appendChild(middleclone);
        middlebit.parentNode.replaceChild(spannode, middlebit);
        skip = 1;
      }
    } else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
      for (var i = 0; i < node.childNodes.length; ++i) {
        i += innerHighlight(node.childNodes[i], pat);
      }
    }
    return skip;
  }
  return this.each(function () {
    innerHighlight(this, pat.toUpperCase());
  });
};

jQuery.fn.removeHighlight = function (classNames) {
  function newNormalize(node) {
    for (var i = 0, children = node.childNodes, nodeCount = children.length; i < nodeCount; i++) {
      var child = children[i];
      if (child.nodeType == 1) {
        newNormalize(child);
        continue;
      }
      if (child.nodeType != 3) {
        continue;
      }
      var next = child.nextSibling;
      if (next == null || next.nodeType != 3) {
        continue;
      }
      var combined_text = child.nodeValue + next.nodeValue;
      new_node = node.ownerDocument.createTextNode(combined_text);
      node.insertBefore(new_node, child);
      node.removeChild(child);
      node.removeChild(next);
      i--;
      nodeCount--;
    }
  }
  var selectors = classNames;
  if(Object.prototype.toString.call(classNames) === '[object Array]')
    selectors = classNames.join(',');
  return this.find(selectors).each(function () {
    var thisParent = this.parentNode;
    thisParent.replaceChild(this.firstChild, this);
    newNormalize(thisParent);
  }).end();
};

我想存在某种编码问题。帮助任何人?我尝试了一些插入 jQuery 编码的方法,但它没有用......

4

1 回答 1

3

如果你不顾一切地写作searchTerm.split(/\s+/);searchTerm.split(/\W+/);一切都会好起来的。

这是工作示例http://jsfiddle.net/5ANZG/

\W+ 匹配任何非单词字符,\W 等价于 [^a-zA-Z_0-9] 并且不包括 unicode 类别。

于 2013-06-08T07:34:23.137 回答