您如何检测“搜索”HTML5 输入的清除?

Posted

技术标签:

【中文标题】您如何检测“搜索”HTML5 输入的清除?【英文标题】:How do you detect the clearing of a "search" HTML5 input? 【发布时间】:2011-02-27 22:53:45 【问题描述】:

html5 中,search 输入类型在右侧出现一个小 X,这将清除文本框(至少在 Chrome 中,也许在其他中)。有没有一种方法可以检测何时在 javascript 或 jQuery 中单击此 X,而不是检测何时单击该框或进行某种位置单击检测(x 位置/y 位置)?

【问题讨论】:

我对 HTML 5 了解不多,但它没有onchange 事件吗? 好吧,你可以确定搜索框是否被清除,但不能确定是否由于单击该按钮而不是选择和删除而发生 Is there any events available for the reset option for input search?的可能重复 可能的答案***.com/a/59389615/11973798检查是否有帮助 你应该添加 keyup 和搜索事件.. 【参考方案1】:

就我而言,我不想使用 JQuery,而且我的输入也是通用的,因此在某些情况下它可能是“搜索”类型,但并非总是如此。根据此处的其他答案之一,我能够稍微延迟地让它工作。基本上我想在单击输入时打开一个组件,但如果单击清除按钮则不是。

function onClick(e: React.MouseEvent<HTMLInputElement>) 
  const target = e.currentTarget;
  const oldValue = target.value;
  setTimeout(() => 
    const newValue = target.value;
    if (oldValue && !newValue) 
      // Clear was clicked so do something here on clear
      return;
    

    // Was a regular click so do something here
  , 50);
;

【讨论】:

【参考方案2】:

实际上,每当用户搜索或点击“x”时,都会触发一个“搜索”事件。这特别有用,因为它理解“增量”属性。

现在,话虽如此,我不确定您是否可以区分单击“x”和搜索之间的区别,除非您使用“onclick”黑客。不管怎样,希望这会有所帮助。

Dottoro web reference

【讨论】:

谢谢,除了单击“x”之外,无法确定search 事件何时发生。它似乎不会在keyupblur 或提交的表单上触发。但这值得被标记为答案。 search 事件应在用户按下 Enter 时触发。如果搜索框有incremental 属性,它也会在用户停止输入一秒钟时触发。 仅供参考:在撰写此评论时,这仅适用于 Chrome。 IE11 会触发input 事件,但不会触发search 事件。 “搜索”事件是非标准的。见this。我不建议在没有 poly-fill 的情况下使用它。【参考方案3】:

我想添加一个“迟到”的答案,因为我今天在changekeyupsearch 上苦苦挣扎,也许我最终发现的内容可能对其他人也有用。 基本上,我有一个 search-as-type 面板,我只是想对小 X 的按下做出适当的反应(在 Chrome 和 Opera 下,FF 没有实现它),并因此清除一个内容窗格。

我有这个代码:

 $(some-input).keyup(function()  
    // update panel
 );

 $(some-input).change(function()  
    // update panel
 );

 $(some-input).on("search", function()  
    // update panel
 );

(它们是分开的,因为我想检查每个调用的时间和情况)。

事实证明,Chrome 和 Firefox 的反应不同。 特别是,Firefox 将change 视为“对输入的每次更改”,而 Chrome 将其视为“当焦点丢失且内容发生更改时”。 因此,在 Chrome 上,“更新面板”功能被调用一次,在 FF 上,每次击键调用两次(keyup 一个,change 一个)

此外,清除带有小 X(FF 下不存在)的字段会触发 Chrome 下的 search 事件:没有 keyup,没有 change

结论?请改用input

 $(some-input).on("input", function()  
    // update panel
 

它在我测试的所有浏览器下都具有相同的行为,对输入内容的每一次变化做出反应(用鼠标复制粘贴,自动完成和“X”包括在内)。

【讨论】:

谢谢洛伦佐...这很有帮助。 太棒了,简直太棒了。非常感谢为我节省了试图弄清楚这一点的时间。 似乎 Firefox 从那以后改变了它的行为?我使用 Firefox 42.0 进行了测试,它处理 change 事件就像 Chrome 一样,仅在 Enter 或焦点丢失时触发。 我喜欢 on input 选项...不错!【参考方案4】:

简单易读的简短解决方案

哇,对于一个非常简单的问题,这里有一些非常复杂的答案。

只需在您的搜索输入中添加'input' 的侦听器,当用户在输入中键入内容点击清除图标时,该侦听器将捕获。

document.getElementById('searchInput').addEventListener('input', (e) => 
  console.log(`Input value: "$e.currentTarget.value"`);
)
&lt;input id="searchInput" type="search" placeholder="Search" /&gt;

如果你不能使用 ES6+,那么这里是为你转换的代码:

document.getElementById('searchInput').addEventListener('input', function(e)  
  // Yay! You make it in here when a user types or clicks the clear icon
)` 

【讨论】:

感谢您,但它实际上并没有回答问题!是的,您可以使用您的方法来确定input 之后的值是否为空字符串,但您不一定确定有人点击了 X。如果您想在用户特别时执行某些操作点击X,你的答案没有解决它:) @Jason 确实如此。当有人单击 X 时,该值为空,因此只需检查长度。 document.getElementById('searchInput').addEventListener('input', function (e) let length = $(this).val().length; );【参考方案5】:

似乎没有一个好的答案,所以我想我会添加另一个可能的解决方案。

// Get the width of the input search field
const inputWidth = $event.path[0].clientWidth;
// If the input has content and the click is within 17px of the end of the search you must have clicked the cross
if ($event.target.value.length && ($event.offsetX < inputWidth && $event.offsetX > inputWidth - 17)) 
    this.tableRows = [...this.temp_rows];

更新

const searchElement = document.querySelector('.searchField');
searchElement.addEventListener('click', event => 
  // Get the width of the input search field
  const inputWidth = $event.path[0].clientWidth;
  // If the input has content and the click is within 17px of the end of the search you must have clicked the cross
  if ($event.target.value.length && ($event.offsetX < inputWidth && $event.offsetX > inputWidth - 17)) 
    this.tableRows = [...this.temp_rows];

);

【讨论】:

你能给这个sn-p提供一些代码上下文吗? $event 指的是什么?还是if里面的代码?我认为您的解决方案可能会起作用,尽管我认为依赖浏览器特定的布局(即“X”在搜索框中的位置)存在脆弱性。 嗨,马克,我已经用事件监听器更新了 sn-p。是的,这在浏览器中可能很脆弱/脆弱,但就像我说的那样,没有一个“好的”答案,这只是另一种方法。我个人认为这是需要上级解决的问题,例如在事件中添加对 clear 的引用。【参考方案6】:

最初的问题是“我可以检测到点击‘x’吗?”。 这可以通过在search 事件中“牺牲” Enter 来实现。

在输入框生命周期的不同时间触发了许多事件 类型搜索:inputchangesearch。其中一些在某些情况下重叠。默认情况下,“搜索”会在您按 Enter 和按“x”时触发;使用incremental 属性,它也会在您添加/删除任何字符时触发,并以 500 毫秒的延迟捕获多个更改并避免压倒听众。 问题是,search 生成了一个带有 input.value == "" 的模棱两可的事件,因为它可以通过三种方式变为空:(1)“用户按下了‘x’”,(2)“用户按下了 Enter 键没有文本的输入”,或 (3) “用户编辑输入(退格、剪切等)直到输入变为空,最终incremental 触发了空输入的search 事件”。

消除歧义的最佳方法是将 Enter 排除在等式之外,并且仅在按下“x”时才触发search。您可以通过完全抑制 Enter 按键来实现这一点。我知道这听起来很傻,但是您可以通过keydown 事件(您也可以在其中进行抑制)、input 事件或change 事件在更好的受控情况下恢复 Enter 行为。 search 唯一的独特之处是“x”点击。

如果您不使用incremental,这将消除歧义。如果您使用incremental,问题是,您可以通过input 事件实现大部分incremental 行为(您只需要重新实现500ms 去抖动逻辑)。因此,如果您可以删除incremental(或可选地使用input 模拟它),则此问题由searchkeydownevent.preventDefault() 的组合来回答。如果您不能删除incremental,您将继续存在上述一些歧义。

这里有一段代码 sn-p 展示了这一点:

inpEl = document.getElementById("inp");
monitor = document.getElementById("monitor");

function print(msg) 
  monitor.value += msg + "\n";


function searchEventCb(ev) 
  print(`You clicked the 'x'. Input value: "$ev.target.value"`);


function keydownEventCb(ev) 
    if(ev.key == "Enter") 
    print(`Enter pressed, input value: "$ev.target.value"`);
        ev.preventDefault();
    


inpEl.addEventListener("search", searchEventCb, true);
inpEl.addEventListener("keydown", keydownEventCb, true);
<input type="search" id="inp" placeholder="Type something">

<textarea id="monitor" rows="10" cols="50">
</textarea>

在这个简单的 sn-p 中,您已将 search 变成了一个专用事件,该事件仅在您按“x”时触发,并回答了最初发布的问题。您可以使用 keydown 跟踪 input.value 以输入。

我个人更喜欢在按下回车键的时候放一个ev.target.blur()(模拟输入框失去焦点),并监控change事件来跟踪input.value(而不是监控input.value通过keydown)。通过这种方式,您可以统一跟踪 input.value 的焦点变化,这很有用。它对我有用,因为只有在 input.value 实际发生变化时我才需要处理该事件,但它可能不适用于所有人。

这是带有blur() 行为的 sn-p(现在即使您手动将焦点从输入框移开,您也会收到一条消息,但请记住,只有在实际发生更改时才会看到更改消息):

inpEl = document.getElementById("inp");
monitor = document.getElementById("monitor");

function print(msg) 
  monitor.value += msg + "\n";


function searchEventCb(ev) 
  print(`You clicked the 'x'. Input value: "$ev.target.value"`);


function changeEventCb(ev) 
  print(`Change fired, input value: "$ev.target.value"`);


function keydownEventCb(ev) 
    if(ev.key == "Enter") 
        ev.target.blur();
        ev.preventDefault();
    


inpEl.addEventListener("search", searchEventCb, true);
inpEl.addEventListener("change", changeEventCb, true);
inpEl.addEventListener("keydown", keydownEventCb, true);
<input type="search" id="inp" placeholder="Type something">

<textarea id="monitor" rows="10" cols="50">
</textarea>

【讨论】:

【参考方案7】:

我的解决方案基于onclick 事件,我在事件触发的确切时间检查输入的值(确保它不为空),然后等待 1 毫秒并再次检查该值;如果它为空,则表示已单击清除按钮,而不仅仅是输入字段。

这是一个使用 Vue 函数的示例:

HTML

<input
  id="searchBar"
  class="form-input col-span-4"
  type="search"
  placeholder="Search..."
  @click="clearFilter($event)"
/>

JS

clearFilter: function ($event) 
  if (event.target.value !== "") 
    setTimeout(function () 
      if (document.getElementById("searchBar").value === "")
        console.log("Clear button is clicked!");
    , 1);
  
  console.log("Search bar is clicked but not the clear button.");
,

【讨论】:

不错的方法,但它不起作用,按预期触发清除按钮【参考方案8】:

对我来说,单击 X 应该算作更改事件是有道理的。我已经设置了 onChange 事件来做我需要做的事情。所以对我来说,解决方法是简单地做这个 jQuery 行:

$('#search').click(function() $(this).change(); );

【讨论】:

如果您希望在按下清除按钮时触发此功能,您还可以添加对输入值的检查,下面是 Jannis 的评论:***.com/questions/2977023/…if (this.value === "") ... 【参考方案9】:
document.querySelectorAll('input[type=search]').forEach(function (input) 
   input.addEventListener('mouseup', function (e) 
                if (input.value.length > 0) 
                    setTimeout(function () 
                        if (input.value.length === 0) 
                            //do reset action here
                        
                    , 5);
                
            );

ECMASCRIPT 2016

【讨论】:

【参考方案10】:

这是实现这一目标的一种方法。您需要在 html 中添加增量属性,否则它将不起作用。

window.onload = function() 
  var tf = document.getElementById('textField');
  var button = document.getElementById('b');
  button.disabled = true;
  var onKeyChange = function textChange() 
    button.disabled = (tf.value === "") ? true : false;
  
  tf.addEventListener('keyup', onKeyChange);
  tf.addEventListener('search', onKeyChange);

<input id="textField" type="search" placeholder="search" incremental="incremental">
<button id="b">Go!</button>

【讨论】:

【参考方案11】:

基于js的事件循环,清除按钮上的click会触发输入上的search事件,所以下面的代码将按预期工作:

input.onclick = function(e)
  this._cleared = true
  setTimeout(()=>
    this._cleared = false
  )

input.onsearch = function(e)
  if(this._cleared) 
    console.log('clear button clicked!')
  

上面的代码,onclick事件预定了一个this._cleared = false事件循环,但是事件总是在onsearch事件之后运行,所以可以稳定的查看this._cleared 状态判断用户是否刚刚点击了X 按钮,然后触发了onsearch 事件。

这几乎适用于所有条件粘贴文本,具有增量属性,ENTER/ESC键按等。

【讨论】:

【参考方案12】:

我知道这是一个老问题,但我一直在寻找类似的东西。确定何时单击“X”以清除搜索框。这里的答案都没有帮助我。一个很接近,但当用户点击“输入”按钮时也会受到影响,它会触发与单击“X”相同的结果。

我在另一篇文章中找到了这个答案,它对我来说很完美,只有在用户清除搜索框时才会触发。

$("input").bind("mouseup", function(e)
   var $input = $(this),
   oldValue = $input.val();

   if (oldValue == "") return;

   // When this event is fired after clicking on the clear button
   // the value is not cleared yet. We have to wait for it.
   setTimeout(function()
     var newValue = $input.val();

      if (newValue == "")
         // capture the clear
         $input.trigger("cleared");
      
    , 1);
);

【讨论】:

【参考方案13】:

点击TextField cross button(X) onmousemove() 被触发,我们可以使用这个事件来调用任何函数。

<input type="search" class="actInput" id="ruleContact" onkeyup="ruleAdvanceSearch()" placeholder="Search..." onmousemove="ruleAdvanceSearch()"/>

【讨论】:

【参考方案14】:

完整的解决方案在这里

这将在单击搜索 x 时清除搜索。 要么 当用户按回车时,将调用搜索 API。 可以使用额外的 esc keyup 事件匹配器进一步扩展此代码。但这应该可以做到。

document.getElementById("userSearch").addEventListener("search", 
function(event)
  if(event.type === "search")
    if(event.currentTarget.value !== "")
      hitSearchAjax(event.currentTarget.value);
    else 
      clearSearchData();  
    
  
);

干杯。

【讨论】:

【参考方案15】:

我相信这是唯一只有在单击 x 时才会触发的答案。

但是,这有点 hacky,ggutenberg 的答案对大多数人都有效。

$('#search-field').on('click', function()
  $('#search-field').on('search', function()
    if(!this.value)
      console.log("clicked x");
      // Put code you want to run on clear here
    
  );
  setTimeout(function() 
    $('#search-field').off('search');
  , 1);
);

'#search-field' 是用于输入的 jQuery 选择器。使用'input[type=search]' 选择所有搜索输入。通过单击该字段后立即检查搜索事件(Pauan 的答案)来工作。

【讨论】:

【参考方案16】:

试试这个,希望对你有帮助

$("input[name=search-mini]").on("search", function() 
  //do something for search
);

【讨论】:

【参考方案17】:

搜索或 onclick 有效...但我发现的问题与旧版浏览器有关 - 搜索失败。许多插件(jquery ui 自动完成或花式树过滤器)都有模糊和焦点处理程序。将此添加到自动完成输入框中对我有用(使用 this.value == "" 因为它评估速度更快)。当您点击小“x”时,模糊然后焦点将光标保持在框中。

PropertyChange 和输入适用于 IE 10 和 IE 8 以及其他浏览器:

$("#INPUTID").on("propertychange input", function(e)  
    if (this.value == "") $(this).blur().focus(); 
);

对于 FancyTree 过滤器扩展,您可以使用重置按钮并强制其点击事件,如下所示:

var TheFancyTree = $("#FancyTreeID").fancytree("getTree");

$("input[name=FT_FilterINPUT]").on("propertychange input", function (e) 
    var n,
    leavesOnly = false,
    match = $(this).val();
    // check for the escape key or empty filter
    if (e && e.which === $.ui.keyCode.ESCAPE || $.trim(match) === "") 
        $("button#btnResetSearch").click();
        return;
    

    n = SiteNavTree.filterNodes(function (node) 
        return MatchContainsAll(CleanDiacriticsString(node.title.toLowerCase()), match);
        , leavesOnly);

    $("button#btnResetSearch").attr("disabled", false);
    $("span#SiteNavMatches").text("(" + n + " matches)");
).focus();

// handle the reset and check for empty filter field... 
// set the value to trigger the change
$("button#btnResetSearch").click(function (e) 
    if ($("input[name=FT_FilterINPUT]").val() != "")
        $("input[name=FT_FilterINPUT]").val("");
    $("span#SiteNavMatches").text("");
    SiteNavTree.clearFilter();
).attr("disabled", true);

应该能够适应大多数用途。

【讨论】:

【参考方案18】:

绑定search-事件搜索框如下-

$('input[type=search]').on('search', function () 
    // search logic here
    // this function will be executed on click of X (clear button)
);

【讨论】:

这对于那些不确定的人来说是正确的答案 很高兴知道 Chrome 支持搜索事件,但 IE 或 FF 不支持,根据 MDN,它是非标准功能,不在标准轨道上。 developer.mozilla.org/en-US/docs/Web/Events/search【参考方案19】:

发现这篇文章,我意识到它有点旧,但我认为我可能会有答案。这将处理单击十字、退格和按 ESC 键。我相信它可能会写得更好——我对 javascript 还是比较陌生。这是我最终做的 - 我使用的是 jQuery (v1.6.4):

var searchVal = ""; //create a global var to capture the value in the search box, for comparison later
$(document).ready(function() 
  $("input[type=search]").keyup(function(e) 
    if (e.which == 27)   // catch ESC key and clear input
      $(this).val('');
    
    if (($(this).val() === "" && searchVal != "") || e.which == 27) 
      // do something
      searchVal = "";
    
    searchVal = $(this).val();
  );
  $("input[type=search]").click(function() 
    if ($(this).val() != filterVal) 
      // do something
      searchVal = "";
    
  );
);

【讨论】:

看起来 filterVal 没有定义【参考方案20】:

根据 Pauan 的回答,这很有可能。例如。

<head>
    <script type="text/javascript">
        function OnSearch(input) 
            if(input.value == "") 
                alert("You either clicked the X or you searched for nothing.");
            
            else 
                alert("You searched for " + input.value);
            
        
    </script>
</head>
<body>
    Please specify the text you want to find and press ENTER!
    <input type="search" name="search" onsearch="OnSearch(this)"/>
</body>

【讨论】:

对我来说,change 事件基本上直到blur 才会触发。只需在 Chrome 的搜索字段中单击 (x) 似乎不会触发任何事件。经过进一步调查(并阅读下面的 cmets),我得到了 click 为我工作。所以$("input[type='search']").bind('click', function(e) if ( this.value=="") //this just cleared! ); 对我有用 但是$("input[type='search']").bind('click', function(e) if ( this.value=="") //this just cleared! );也会在用户点击输入框时触发。【参考方案21】:

您似乎无法在浏览器中访问此内容。搜索输入是 Cocoa NSSearchField 的 Webkit HTML 包装器。取消按钮似乎包含在浏览器客户端代码中,而包装器中没有可用的外部引用。

来源:

http://weblogs.mozillazine.org/hyatt/archives/2004_07.html#005890 http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#text-state-and-search-state http://dev.w3.org/html5/markup/input.search.html#input.search

看起来你必须通过点击鼠标位置来解决这个问题:

$('input[type=search]').bind('click', function(e) 
  var $earch = $(this);
  var offset = $earch.offset();

  if (e.pageX > offset.left + $earch.width() - 16)  // X button 16px wide?
    // your code here
  
);

【讨论】:

好吧,这很糟糕。也许我会选择 B 计划,如果输入现在为空,它会在 onClick 上运行一个事件......也许把它放在一个 25 毫秒的计时器上 @Jason 是的,您可以使用我在上面放置的代码仅在单击发生在 X 所在的区域时运行它。除了像你说的那样检查输入是否为空之外就足够了

以上是关于您如何检测“搜索”HTML5 输入的清除?的主要内容,如果未能解决你的问题,请参考以下文章

如何从html中的文本框中清除搜索输入? [复制]

使用 HTML5 视频检测帧精确搜索

Bootstrap表格过滤器控制搜索使用后如何清除输入框

如何在数据表中的搜索框中输入值

选择下拉列表中的复选框后如何清除 v-autocomplete(多个)搜索输入?

如何在jquery-mobile中获取搜索框的清除事件