【问题标题】:The simplest solution to hide calendar on blur or click在模糊或单击时隐藏日历的最简单解决方案
【发布时间】:2012-03-30 03:24:17
【问题描述】:

http://jsfiddle.net/SXrAb/

在 jsfiddle 链接之后,有一个我需要的简化示例。目前它在按钮单击时显示日历,并在输入模糊时隐藏它。

我不能另外实现的是在按钮单击时隐藏日历。

所以 - 日历应该:

  1. 如果隐藏则点击按钮打开(完成)
  2. 在模糊时隐藏(完成)
  3. 如果打开按钮点击隐藏(这是我一直坚持的,因为模糊是在按钮点击事件之前触发的,所以我没有机会正确处理它)

UPD

该解决方案预计在所有情况下都能正常工作,例如“鼠标按下按钮,向下拖动,鼠标向上”(否则我不会问它;-)

【问题讨论】:

  • stackoverflow.com/questions/4451115/jquery-priority-execution ;我现在正在写一个 jsfiddle :) 希望这个链接有帮助,干杯!
  • @Gabriel Santos:输入焦点,按下按钮,按下制表符
  • @Tats_innit:呵呵,是的,超时是我想避免的另一件事,但让我们看看 ;-)
  • @zerkms lmao :D - 你是对的 settimeout 很糟糕,因为......(经验会谈)请试试这个:jsfiddle.net/SXrAb/50 如果它确实根据你的需要工作,我应该将它设置为其中之一答案也是?干杯!
  • @Tats_innit:你应该把它作为答案,我尊重甚至尝试

标签: javascript jquery


【解决方案1】:

试试这个:

var $calendar = $('#calendar');
var mousedown = false;

$('#calendar-input').blur(function() {
    if (!mousedown)
        $calendar.hide();
});

$('#calendar-button').mousedown(function() {
    mousedown = true;
});

$('#calendar-button').mouseup(function() {
    mousedown = false;
});

$('#calendar-button').click(function() {
    if ($calendar.is(':visible')) {
         $calendar.hide();
    }
    else {
        $calendar.show();
        $('#calendar-input').focus();
    }
});

在这里演示:http://jsfiddle.net/Tz73k/

更新:好的,我将 mouseup 事件移至文档级别。我不认为现在可以通过在释放鼠标之前拖动鼠标来欺骗鼠​​标状态:

var $calendar = $('#calendar');
var mousedown = false;

$('#calendar-input').blur(function() {
    if (!mousedown)
        $calendar.hide();
});

$('#calendar-button').mousedown(function() {
    mousedown = true;
});

$(document).mouseup(function() {
    mousedown = false;
});

$('#calendar-button').click(function() {
    if ($calendar.is(':visible')) {
         $calendar.hide();
    }
    else {
        $calendar.show();
        $('#calendar-input').focus();
    }
});

更新小提琴:http://jsfiddle.net/yQ5CT/

【讨论】:

  • 是的,我实现了类似的东西,但它仍然可以通过简单的方式被愚弄: 1. 按下按钮 2. 鼠标按下按钮,向下拖动(超出按钮),释放鼠标按钮 3 . 关注输入 4. 按 Tab。并且日历没有隐藏,因为mousedown标志在true
  • 啊啊啊是的。我的论点无效。
  • @zerkms 我将 mouseup 事件移至文档级别...我希望它现在不会被鼠标拖动所欺骗。查看我更新的解决方案。
【解决方案2】:

将日历和按钮视为一个集合会很有帮助,您只有在集合中的所有内容都变得模糊时才隐藏日历。为此,您需要一个可以在日历和按钮之间“传递”焦点而不触发隐藏功能的系统。为此,您需要在日历和按钮上都有一个焦点和模糊处理程序,以及 isFocused 的状态变量。

var isFocused;

jQuery('#calendar,#calendar-button,#calendar-input').blur(function(){
  isFocused = false;
  setTimeout(function() {
    if (!isFocused) { hide(); }
  }, 0);
});

jQuery('#calendar,#calendar-button,#calendar-input').focus(function(){
  isFocused = true;
});

setTimeout 是因为,当您单击按钮时,日历上的焦点在获得按钮之前就丢失了,因此暂时没有焦点。

编辑

我猜这个集合中实际上包含三个元素,按钮、文本框和日历。我更新了这个例子。这也解决了在您的示例中,您无法在日历和文本框之间单击而不隐藏日历的问题。想必真正的日历可以通过点击来操控。

编辑 2

为此,您需要通过给它一个 tabindex 来使您的日历具有焦点。

<span id="calendar" tabindex="-1">I'm a calendar ;-)</span>

【讨论】:

  • 是的,(我的意思是“blur-click-0timeout”的顺序)实际上是有效的。但它有任何标准保证吗?
【解决方案3】:

Demo here http://jsfiddle.net/SXrAb/50/ -- (非警报版本)http://jsfiddle.net/SXrAb/51/

感谢 zerkms!

JQuery 代码

var $calendar = $('#calendar');
$calendar.hide();

var isBlurEventInvoked = true;
var calendarShow = false;

$('#calendar-input').blur(function() {
    alert(isBlurEventInvoked + " ==== " + calendarShow);
    if (isBlurEventInvoked && calendarShow){
        $calendar.hide();
        isBlurEventInvoked = true;
    } 

});

$('#calendar-button').click(function() {

    if (!$calendar.is(':visible') && isBlurEventInvoked){
       $calendar.show();
       $('#calendar-input').focus();
       calendarShow =  true;
       isBlurEventInvoked = true;
    }else if ($calendar.is(':visible')) {
        $calendar.hide();
        isBlurEventInvoked = false;
        calendarShow = false;
    }

});


​

【讨论】:

    猜你喜欢
    • 2010-11-28
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多