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 に答える