【问题标题】:onBlur event on composed component (input + Button)组合组件上的 onBlur 事件(输入 + 按钮)
【发布时间】:2015-05-27 22:29:48
【问题描述】:

我正在尝试制作一个由输入字段和按钮组成的“组合组件”。

我有以下 jsfiddle 作为示例:

http://jsfiddle.net/stt0waj0/

<div id="myComponent">
    <input type="text" onBlur="this.style.border='1px solid red';">
    <button type="button" onClick="alert('Hello World');">ClickMe</button>
</div>

我想要的行为是,当我离开输入字段而不写任何内容时,我得到一个验证错误(在这种情况下是红色边框)。这已经在小提琴中起作用了(内容验证不是问题的范围)。

但是,当我按下按钮离开输入字段时,我将打开一个对话框,允许为输入字段选择值,因此在这种情况下,我不希望运行验证。

那么,关于小提琴的具体问题:我可以单击输入字段,然后单击按钮并且没有红色边框吗?但是,如果我单击输入字段,然后单击其他位置,我想要红色边框(任何 onBlur,除非单击按钮时)。

如果没有肮脏的把戏,这可能吗?

我想避免的事情:

  • 在第一个事件上设置一个计时器以等待第二个事件(原因:性能)
  • 使 onClick 事件始终重置文本字段上的红色边框(原因:gui 故障)

只是为了说明我在寻找什么以及为什么这个问题很有趣:onBlur 事件在 onClick 事件之前触发。但是,我通常需要 onBlur 才能知道接下来是 onClick,这是不可能的。这就是问题的重点。

想象一个在空字段上验证的日期选择器,当该字段具有焦点并且您按下日历时,即使您正在选择一个日期,您也会收到验证错误。我想知道是否有一种优雅的方式来处理这种情况。

【问题讨论】:

  • 您的验证在哪里?无论输入是否为空,您都会看到红色边框。
  • @artm:这是一个简化的例子。
  • 正如我在问题中所写,验证不是问题的范围。我想知道如果我按下按钮,是否可以避免出现红色边框。这只是一个小(非常简单)的运行示例,可以显示我的期望。
  • 这取决于您的验证方式。你是在使用 jquery 验证,你是在使用模糊事件吗?
  • 我们正在使用另一个不支持这种行为的框架。但是,我首先想看看是否可以在“最低级别”(纯html/js)上完成,然后寻找一种方法让我们的组件工作。

标签: javascript html


【解决方案1】:

为了使这项工作正常进行,如果用户按下按钮,您可以推迟验证功能。

下面是示例代码和小提琴来说明我的意思。 *更新了小提琴以使用选择下拉菜单而不是按钮* Fiddle Demo

input.error {color: red; border: 1px solid red;}

<div id="myComponent">
<input id="btn" type="text" onBlur="inputBlur()">
<select type="button" data-btn="btn" onclick="inputButtonClick()" onchange="selectChange()" onblur="selectBlur()">
    <option value="">choose</option>
    <option value="item1">item1</option>
    <option value="item2">item2</option>
    <option value="item3">item3</option>
</select>
</div>

window.validate = function(input) {
    //do your validation
    var val;
    console.log("Validating");
    val = input.val();

    if ( !val || !val.length) {
        input.addClass("error");
        console.log("Something is invalid");
    } else {
        //all good
        console.log("All valid");
    }
    //clear error after x time to retry
    setTimeout(function() {
        $(".error").removeClass("error");
        $("input").removeAttr("data-btn-active") ;
    }, 3000);
}
window.selectBlur = function() {
    var input = $("#" + $(event.target).attr("data-btn"));
    validate(input);
}
window.selectChange = function() {
    var input = $("#" + $(event.target).attr("data-btn"));
    console.log("change", $(event.target).val() );
    input.val( $(event.target).val() );
    validate(input);
}
window.inputButtonClick = function() {
    var input = $("#" + $(event.target).attr("data-btn"));
    input.attr("data-btn-active", "true");
     console.log("inputButtonClick",input );
}
window.inputBlur = function() {
    var input = $(event.target);
    //give a bit of time for user to click on the button
    setTimeout(function() {
        if (!input.attr("data-btn-active" ) ) {validate(input);}
    }, 100);
}
$(document).ready(function() {

});

【讨论】:

  • 我试过这种方法,效果很好。然而,它做了我想要避免的事情:触发一个事件以等待另一个事件。为什么等待 100 毫秒而不是 10 或 70 或 330?这只是一种解决方案,让我认为它在某些(可能是极端的)条件下可能会失败......
  • 如果客户端验证失败,那也没关系,因为您也必须始终在服务器端进行验证。最坏的情况=输入被标记为无效一秒钟左右,而用户从下拉列表中选择了一些东西。我认为没有像这样使用 onblur 的好而优雅的方式。您可以尝试创建自己的“on blur”事件,改为购买“html”元素上的侦听点击(任何点击您的组件或其子元素以外的任何元素 = blur ),也(如果您的输入,tab key press = on blur是焦点)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-22
  • 1970-01-01
  • 1970-01-01
  • 2012-11-08
  • 2017-11-29
  • 2013-01-03
相关资源
最近更新 更多