如果所选文本在输入

时间:2017-07-28 19:30:20

标签: javascript jquery

built a page 您可以通过在输入框中输入来过滤结果。

基本机制是:

  • 开始输入,触发输入事件,没有匹配文本的元素开始隐藏
  • 如果输入变空(或者单击重置按钮),则会再次显示所有元素

但是,在突出显示文字时,我注意到了一个问题。说我打字" apple"进入输入。然后我突出显示它,然后键入" orange。"

如果页面上包含" orange,"但它已经被隐藏了,因为我过滤了#34; apple,"它没有显示出来。我收集到这是因为输入从未真正排空;相反,我只是替换" apple"用" o"在继续使用" r-a-n-g-e之前从橙色开始。"这意味着我得到了一个" apple"结果包含"橙色,"好像我输入了#apple;苹果橙。"

我真正想要做的是清除我对" o"的按键输入。 in" orange"在隐藏不匹配的元素之前,我有效地在整个页面中搜索" orange。"

到目前为止我尝试了什么

1:在''事件上将输入值设置为select

$('.myinput').on('select', function(){
  $(this).val('');
});

这不起作用,因为它只是删除了我突出显示的文本,这是意料之外的。我只想重点突出显示按键上的输入。

2:在我的输入事件中包含一个if语句,用于检查输入中是否有选择:

$('.myinput').on('input', function(){
  var highlightedText = window.getSelection();

  if($(highlightedText).parent('.myinput')) {
    //reset my input
  }
});

这不起作用,因为它似乎会在每个按键上触发,无论是否有任何实际选择。 (用户输入是否始终被视为已选择?)

3:向input元素添加一个select事件监听器,如果有选择则将变量设置为true。然后,在我的输入事件中,检查keypress上的变量是否为真。

$(function(){
  var highlightedText = false;

  $('.myinput').on('input', function(){
    if(highlightedText = true) {
      //reset my input
    }

    //do stuff

    highlightedText = false;
  });

  $('.myinput').on('select', function(){
    highlightedText = true;
  });
});

我真的认为这个会工作,因为select函数中的基本控制台日志只在我想要它时才会触发 - 当输入中的文本被突出显示时,但是当其他文本被突出显示而不是当文本是进入输入。但是,当我将其更改为变量切换时,它似乎再次触发每个按键。

所以问题是:只有当我的输入中的文本突出显示时,如何才能在输入上触发函数?

我发现this question建议绑定到mouseup事件,但是当我只担心一个非常特殊的情况时,检查每一次点击似乎有点过分。此外,该解决方案依赖window.getSelection(),到目前为止还没有为我工作。

我还发现another question建议使用window.selectionEnd代替window.getSelection(),因为我正在使用文字输入。我尝试将其合并到上面的选项2中,但它似乎也会触发每个按键,而不是突出显示。

2 个答案:

答案 0 :(得分:1)

这个答案根本不是文字选择。

但是当使用新输入替换突出显示的文本时,仍然可以解决您重新过滤文本的问题。



var input = document.getElementById('ok');
var character = document.getElementById('char');
var previousCount = 0;
var currentCount = 0;

input.addEventListener('input', function(){
    currentCount = this.value.length;
    if (currentCount <= previousCount){
        /*
            This will detect if you replace the highlighted text into new text.
            You can redo the filter here.
        */
        console.log('Highlighted text replaced with: ' + this.value);
    }
    previousCount = currentCount;
    char.innerHTML = this.value;
});
&#13;
<input type="text" id="ok">

<div id="char"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我同意其他人的意见,如果您更改过滤策略,您将省去一些麻烦 - 我说您应该在每个按键时从头开始过滤所有内容,而不是连续过滤内容仍然存在。

无论如何,为了解决您的直接问题,我认为您可以选择并查看它是否为空。您可以修改第二次尝试:

$('.myinput').on('input', function(){
  // get the string representation of the selection
  var highlightedText = window.getSelection().toString();

  if(highlightedText.length) {
    //reset my input
  }
});

修改

由于这个解决方案似乎有各种各样的问题,我可以根据@ Bee157的评论提出另一个问题。您可以保存旧的搜索字符串并检查新的搜索字符串是否具有旧字符串(如果没有,则重置显示)。

var oldSearch = '';
$('.myinput').on('input', function(){
  var newSearch = $('.myinput').val();
  if (newSearch.indexOf(oldSearch) == -1) {
    // reset the display
    console.log('RESET');
  }
  oldSearch = newSearch;
  // filter the results...
});    

此方法的另一个好处是,当您退格时,旧结果将重新出现。我在你的codepen中尝试过,我能够记录下来&#39; RESET&#39;在所有适当的时刻。