在HTML5中,搜索输入类型的右边会出现一个小X,这将清除文本框(至少在Chrome中,可能在其他浏览器中)。是否有一种方法来检测这个X在Javascript或jQuery中被点击,而不是检测盒子被点击或做一些位置点击检测(X -position/y-position)?
当前回答
最初的问题是“我能检测到点击‘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>
其他回答
我想补充一个“晚”的答案,因为我今天在改变、keyup和搜索方面很挣扎,也许我最后发现的东西对其他人也有用。 基本上,我有一个搜索类型面板,我只是想对小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将更改视为“对输入的每一次更改”,而Chrome则将其视为“当焦点丢失和内容更改时”。 因此,在Chrome上的“更新面板”函数被调用一次,在FF上的每一次击键都被调用两次(一次在keyup,一次在change)
此外,用小X清除字段(在FF下不存在)在Chrome下触发搜索事件:没有keyup,没有变化。
结论?使用input代替:
$(some-input).on("input", function() {
// update panel
}
在我测试的所有浏览器中,它都具有相同的行为,对输入内容的每一次更改都做出反应(包括使用鼠标复制粘贴、自动补全和“X”)。
搜索或onclick工作…但我发现的问题是旧的浏览器——搜索失败。很多插件(jquery ui autocomplete或fancytree filter)都有模糊和聚焦处理程序。将其添加到自动完成输入框对我来说很有效。Value == ""因为它的计算速度更快)。当你点击小“x”时,模糊然后聚焦将光标保持在方框中。
PropertyChange和input在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);
应该能够适应这为大多数用途。
实际上,每当用户搜索或单击“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];
}
});
你似乎不能在浏览器中访问它。搜索输入是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
}
});
推荐文章
- JSHint和jQuery: '$'没有定义
- 模仿JavaScript中的集合?
- 用JavaScript验证电话号码
- 如何在HTML5中改变视频的播放速度?
- 保留HTML字体大小时,iPhone的方向从纵向改变为横向
- 谷歌地图API v3:我可以setZoom后fitBounds?
- 用jQuery检查Internet连接是否存在?
- 如何使用滑动(或显示)函数在一个表行?
- ES6/2015中的null安全属性访问(和条件赋值)
- 与push()相反;
- 嵌套行与自举网格系统?
- JS字符串“+”vs concat方法
- AngularJS使用ng-class切换类
- 访问Handlebars.js每次循环范围之外的变量
- 如何用JavaScript截屏一个div ?