当.find()术语在具有多个匹配的变量时出现jQuery问题

时间:2016-04-15 10:50:26

标签: javascript jquery

我的目标是让用户使用光标选择文本,并将选择输出到另一个div中,并在<span>标记中突出显示文本。

所以,我有这样的选择集:

var sel = jQuery.selection();

然后我将选择包装到<span>并输出:

var $title = jQuery(this).parent().find('.title').text();
var $result;
$result = $title.replace(sel, '<span>'+sel+'</span>');

// output result
jQuery(this).parent().find('.output').html($result);

工作正常。

问题在于,如果文本包含相同的术语两次并且用户选择第二个术语,则它将查找并替换第一个术语。

例如,随机文字:

hello world lorem ipsum hello

如果用户选择第二个hello,它将包装第一个var arr = [1, 2, 3, 4, 5, 6, 8]; var diff = _.difference(_.range(Math.min.apply(Math, arr), Math.max.apply(Math, arr)), arr);

是否有适用于解决此类情况的解决方案?

jsFiddle进行测试。

2 个答案:

答案 0 :(得分:4)

Get the offset from which you can start replacing ...

$('button').click(function() {
  var sel = jQuery.selection();
  var $title = jQuery(this).parent().find('.title').text();
  var $result;
  var highlightFrom = window.getSelection().anchorOffset;


    $result = $title.substr(0,highlightFrom) + $title.substr(highlightFrom, $title.length).replace(sel, '<span>' + sel + '</span>');


  // output result
  jQuery(this).parent().find('.output').text($result);
});

In your sample, highlighfrom gives 24 when selecting second hello.

Updated Fiddle

AnchorOffset is supported by IE9+ and other major browsers. If you need a valid alternative, I refer to Rangy as stated here: AnchorOffset alternative

See here for more info on textselection ranges and browser compatibility

TESTED - Chrome, IE11+, FF

答案 1 :(得分:0)

我知道,使用锚点偏移量仍存在浏览器兼容性问题。但我想出的第一件事就是将给定的字符串分成三部分。选择前的部分,选定的部分和其余部分。 然后包裹所选部分并再次将它们组合在一起......

$('button').click(function() {
  var $sel = jQuery.selection();
  var $highlightStart = window.getSelection().anchorOffset;
  var $highlightEnd = window.getSelection().focusOffset;

  var $title = jQuery(this).parent().find('.title').text();
  var $textLength = $title.length;

  var $textBefore = $title.substr(0,$highlightStart);
  var $textToWrap = $title.substr($highlightStart, $highlightEnd - $highlightStart);
  var $textAfter = $title.substr($highlightEnd, $textLength - $highlightEnd);

  var $result;
  $result = $textBefore + '<span>' + $textToWrap + '</span>' + $textAfter;

  // output result
  jQuery(this).parent().find('.output').text($result);
});

https://jsfiddle.net/sqd5gsz5/6/