在HTML5中,搜索输入类型的右边会出现一个小X,这将清除文本框(至少在Chrome中,可能在其他浏览器中)。是否有一种方法来检测这个X在Javascript或jQuery中被点击,而不是检测盒子被点击或做一些位置点击检测(X -position/y-position)?


当前回答

我相信这是唯一的答案,只有当x被点击。

然而,这有点俗气,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的答案)来工作。

其他回答

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

There are many events firing at different times in the lifecycle of an input box of type search: input, change, search. Some of them overlap under certain circumstances. By default, "search" fires when you press Enter and when you press the 'x'; with the incremental attribute, it also fires when you add/remove any character, with a 500ms delay to capture multiple changes and avoid overwhelming the listener. The trouble is, search generates an ambiguous event with input.value == "", because there are three ways it could have turned empty: (1) "the user pressed the 'x'", (2) "the user pressed Enter on an input with no text", or (3) "the user edited the input (Backspace, cut, etc) till the input became empty, and eventually incremental triggered the search event for the empty input".

消除歧义的最佳方法是将Enter从等式中去掉,只在按下“x”时启动搜索。您可以通过完全压制Enter键来实现这一点。我知道这听起来很傻,但是您可以通过keydown事件(在这里您也可以进行压制)、输入事件或更改事件在更好的控制情况下恢复Enter行为。搜索唯一的独特之处就是点击“x”。

如果您不使用增量,这将消除歧义。如果您使用增量,那么您可以通过输入事件实现大多数增量行为(您只需要重新实现500ms的debounning逻辑)。因此,如果您可以删除增量(或可选地用输入模拟它),这个问题可以通过使用event.preventDefault()组合搜索和keydown来回答。如果你不能放弃增量,你将继续有上面描述的一些模糊性。

下面是演示这一点的代码片段:

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>

在这个简单的代码片段中,您已经将搜索变成了一个专门的事件,它只在您按下'x'时触发,并回答了最初发布的问题。你跟踪输入。值,并按下Enter键。

就我个人而言,我更喜欢在按Enter键时输入ev.target.blur()(模拟输入框失去焦点),并监视更改事件以跟踪输入。值(而不是监视输入。Value via keydown)。通过这种方式,您可以统一地跟踪输入。焦点变化的值,这可能是有用的。它适用于我,因为我只需要处理输入的事件。价值实际上已经改变了,但它可能并不适用于每个人。

下面是blur()行为的代码片段(现在即使您手动将焦点从输入框移开,也会收到消息,但请记住,只有在实际发生更改时才会看到更改消息):

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>

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

现在,话虽如此,我不确定你是否能说出点击“x”和搜索之间的区别,除非你使用“onclick”黑客。不管怎样,希望这对你有所帮助。

多托罗网络参考

看起来没有一个很好的答案,所以我想我会添加另一个可能的解决方案。

// 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];
}
});
const inputElement = document.getElementById("input");
let inputValue;
let isSearchCleared = false;
inputElement.addEventListener("input", function (event) {
    if (!event.target.value && inputValue) {
        //Search is cleared
        isSearchCleared = true;
    } else {
        isSearchCleared = false;
    }
    inputValue = event.target.value;
});

发现这篇文章,我意识到它有点老了,但我想我可能有一个答案。这处理点击十字,退格和按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 = "";
    }
  });
});