jQuery Datepicker - 悬停时获取日期

Posted

技术标签:

【中文标题】jQuery Datepicker - 悬停时获取日期【英文标题】:jQuery Datepicker - Get date on hover 【发布时间】:2014-07-09 11:48:34 【问题描述】:

我正在使用this jQuery datepicker,我试图在悬停时获取日期的值。我看到插件有一个参数:

eventName The desired event to trigger the date picker. Default: 'click'

由于文档非常有限,我想知道除了单击之外是否还有其他选项,如果没有,我该如何使用eventName 来获取悬停时的值。

【问题讨论】:

你想在鼠标悬停时获得值是什么意思?你想让日期选择器出现在鼠标悬停上吗 如果用户clicks 有两个日期,我可以使用onChange 回调获取选定的日期范围,但我还想在用户滚动每个日期时实时更新日期。 为什么不使用 jQuery 内置的日期选择器?这个看起来很可恶。 任何 jsfiddle 可以工作? @SSS 当然,jsfiddle.net/iaezzy/QgXNn 【参考方案1】:

eventName 选项仅用于将内部show 方法绑定到事件:

$(this).bind(options.eventName, show);

理论上,您可以使用hover 来显示日期选择器,但您必须为eventName 选项指定'mouseenter mouseleave',因为hover 是绑定到'mouseenter mouseleave' 的jQuery 快捷方式。

由于您已声明(在 cmets 中)您希望在 kayak.co.in 中找到行为,您可以通过在 .DatePicker 调用之后链接 mouseenter 处理程序来模仿这一点(无需更改任何其他内容):

$('#date').DatePicker(
    // options...
).on('mouseenter', '.datepickerDays td:not(.datepickerDisabled, .datepickerNotInMonth)', function (e)  // delegating on the mouseenter event which jQuery patches to be a cross-browser event, and only targeting clickable dates
    var target = $(this).children('a'), // cache lookup
        options = target.parents('.datepicker').data('datepicker'), // get DatePicker options
        current = new Date(options.current), // grab the current month/year
        val = parseInt(target.text(), 10), // grab the target date
        hoverVal = new Date(current.getFullYear(), current.getMonth(), val), // make into an actual date
        hoverDay = hoverVal.getDayName(), // get the short day name
        hoverM = hoverVal.getMonth() + 1, // and month
        hoverD = hoverVal.getDate(), // and date
        hoverText = hoverDay + ' ' + (hoverD < 10 ? '0' + hoverD : hoverD) + '/' + hoverM, // for a formatted text value
        selectedVal = new Date(options.date[0]), // get the selected date (which may just be the initial date without an actual selection or an actual selected date, hereafter "selected")
        selectedDay = selectedVal.getDayName(), // get the short day name
        selectedM = selectedVal.getMonth() + 1, // and month
        selectedD = selectedVal.getDate(), // and date
        selText = selectedDay + ' ' + (selectedD < 10 ? '0' + selectedD : selectedD) + '/' + selectedM, // for a formatted text value
        startDate = $('#startDate').data('lastHovered') || new Date(hoverVal) || selectedVal, // default to: last hovered, current hover, or "selected" date (in that order)
        endDate = $('#endDate').data('lastHovered') || new Date(options.date[1]) || startDate, // default to: last hovered, actual selected date, or "selected" date (in that order)
        startDateSelected = $('#startDate').data('startDateSelected') || $('.datepickerDays .datepickerSelected.first').length > 0, // test whether an actual date was selected
        endDateSelected = !isNaN(options.date[1]) && (options.date[1] - options.date[0] > 86400000), // test whether an end date was selected. end date is set in options when start date is actually selected and is the same day as the selected start date but the time is set to 23:59:59
        selector; // variable to store a selector string
    // no end date has been selectd AND if no start date has been selected, or if it has and the user is hovering over an earlier date, or if the user hasn't selected a date yet
    if (!endDateSelected && (!startDateSelected || (startDateSelected && hoverVal < selectedVal) || hoverVal <= startDate)) 
        selector = '#startDate'; // use the startDate input
        $('#endDate').val(''); // since using startDate, endDate has not been selected. make sure the input is cleared.
     else if (!endDateSelected) // otherwise, as long as no end date has been selected
        selector = '#endDate'; // use the endDate input
        $('#startDate').val(selText); // and set the value of startDate back to the actual selected date value
    
    if (!endDateSelected)  // if the user hasn't picked an end date (which cannot be picked without a start date)
        $(selector).data( // persist the last hovered date and whether a start date has been selected
            "lastHovered": hoverVal,
            "startDateSelected": startDateSelected // this is necessary as the plugin routinely destroys and recreates the tables that make up the calendars while navigating the calendars
        ).val(hoverText); // set the value of the input to the hovered date
    
);

工作演示:http://jsfiddle.net/QgXNn/5/

【讨论】:

非常好,除了一件小事外,效果很好……如果我选择第一个和第二个日期一次,第一个日期在悬停时停止更新。第二个仍然可以正常更新。【参考方案2】:

试试这个方法:

为悬停目标创建一个 Div

<div id="content">
    <div id="test">Hover Me</div>
    <div id="datePicker"></div>
</div>

准备就绪后,初始化并绑定到悬停事件以打开

$(function () 
    $('#datePicker').datepicker();
    $('#datePicker').hide();

    $('#content').hover(function () 
        $('#datePicker').fadeIn('fast');
    , function () 
        $('#datePicker').fadeOut('fast');
    );

);

Fiddle(无法引用您的选择器,所以我使用了 JQuery UI)


更新:查看新的 Fiddle

我将我的方法应用于您的 Fiddle。现在,当您将鼠标悬停在“悬停我”上时,您的 DatePicker 会出现,而当光标离开时会消失。我补充说:

$(function () 
    $('#date').hide();
    $('#test').hover(function () 
        $('#date').show();
    , function () 
        $('#date').hide();
    );

);

-

顺便说一句,我让 DatePicker 对话框在非悬停时消失只是为了效果。这可以通过删除相邻的

轻松更改
, function () 
    $('#date').hide();

【讨论】:

抱歉,现阶段无法更改插件。我的小提琴:jsfiddle.net/iaezzy/QgXNn @Nimbuz,我并不是要建议您更改插件。只有同样的逻辑应该适用。我会看看你的小提琴 @Nimbuz 我调整了你的小提琴来使用我的方法。我想这就是你想要的。【参考方案3】:

查看已编辑 working fiddle here,从你的分叉而来。

// setting the value of the input field to hovered date
// Note that we're not triggering the "click" event bec. 
// it will cause the onChange event of the datepicker to be fired. 
// Instead, we're setting and resetting the input field value 
$("body").on("mouseover", ".datepickerDays td", function (e) 
    var d = parseInt($(this).text(), 10),
        my = $(this).closest('table').find('.datepickerMonth span').html().split(', '),
        m = $.inArray(my[0], MONTH_NAMES),
        y = parseInt(my[1], 10),
        date = new Date(y, m, d),
        textbox = $('#startDate').hasClass('focus') ? $('#endDate') : $('#startDate');
    textbox.val(getFormattedDate(date));
);

// We set back the input field back to its original value on mouseout
$("body").on("mouseout", ".datepickerDays td", function (e) 
    var fd = $('#date').DatePickerGetDate(false),
        start = getFormattedDate(fd[0]),
        end = getFormattedDate(fd[1]);
    $('#startDate').val(start);
    $('#endDate').val(end);
);

// ----------------------------------------
// HELPER FUNCTIONS & VARS
// ----------------------------------------

var MONTH_NAMES = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
function pad0(num)  return num < 10 ? '0' + num : num; 
function getFormattedDate(date) 
    if (isNaN(date.getTime()))  return ''; 
    var wd = WEEKDAYS[date.getDay()].substr(0, 3);
    return wd + ' ' + pad0(date.getDate()) + '/' + pad0(date.getMonth() + 1);

【讨论】:

哇,除了一个问题,几乎完美...我选择了一个日期范围,当我再次尝试选择日期范围时,它直接选择了结束日期。 我实际上没有做任何选择。我只在鼠标悬停/移出时重置输入值。检查你自己的小提琴。选择范围后;下次单击时,它将设置开始日期和结束日期。我的叉子也一样。你确定是这段代码导致的吗? @OnurYıldırım 请不要使用&lt;kbd&gt; 标签来设置答案中的链接样式。这些标签用于表示用户输入,而不是超链接。【参考方案4】:

由于插件已经在click 上绑定了change 函数,我们可以通过为hover 附加一个事件并简单地触发它来使用它。所以像:

function make_hover()
    $(".datepickerDays td span").hover(function(e)
        $(this).trigger("click")
    )
    $(".datepickerDays td").mouseup(function(e)
        $('#inputDate').DatePickerHide(); //hide it when click actually occurs
    )
    $(".datepickerContainer").mouseup(function(e)
        setTimeout(function()
          make_hover()
        ,0) //have to run this with setTimeout to force it to run after DOM changes
    )


var date=$('#inputDate').DatePicker(
    format:'m/d/Y', 
    date: $('#inputDate').val(),
    current: $('#inputDate').val(),
    eventName: 'mouseenter',
    onBeforeShow: function()
        $('#inputDate').DatePickerSetDate($('#inputDate').val(), true);
        make_hover()
    ,
    onChange: function(formated, dates)
        $('#inputDate').val(formated);
        make_hover()
    
)

Example

【讨论】:

谢谢,它可以工作,但只有在日历更改为一年中的另一个月份,然后悬停停止工作。 中的插件不断改变 DOM,所以我们需要继续运行 make_hover。认为我对一个日历有一个修复,但是修改你的小提琴使它有点不可预测。我会更新我的答案,但我会稍微研究一下你的小提琴。【参考方案5】:

对于您的问题。我猜您不希望在悬停时显示日期选择器,但希望在悬停时在输入框中显示值或日期。 如果您希望在悬停时显示日期选择器,请尝试使用 'mouseover' 作为插件的 eventName 属性 像这样

$('.inputDate').DatePicker(
    eventName:'mouseover', // This is the event to fire.
    format:'m/d/Y',
    date: $('#inputDate').val(),
    current: $('#inputDate').val(),
    starts: 1,
    position: 'right');

它没有处理悬停的jquery事件。

现在用于在日期选择器元素悬停时在输入标签中显示新日期。您可能需要调整插件本身尝试找到这行 734。代码是

var cal = $(tpl.wrapper).attr('id', id).bind('click', click).data('datepicker', options);

改成

var cal = $(tpl.wrapper).attr('id', id).bind('mouseover', click).data('datepicker', options);

如您所见,我使用了旧的 mouseover 事件,而不是 jquery 'Hover' 关键字。 如果这可行,您还可以尝试在插件中添加一个新的选项参数,比如“callon:click”,并在调用时设置此选项并将其传递到第 734 行。

var cal = $(tpl.wrapper).attr('id', id).bind(options.callon, click).data('datepicker', options);

使用它,您可以设置自己的事件来调用更新文本框的值。 它肯定适用于单个日期选择器。请尝试并对此发表评论。但是您可能还需要进行更多操作来设置点击日期。

【讨论】:

试过了,但它似乎不适用于我想要的日期范围日历:jsfiddle.net/iaezzy/QgXNn @Nimbuz 当我阅读插件时。他们在一个函数调用中管理了所有点击事件。因此,如果您将鼠标悬停应用到许多元素上。 只是想知道。您打算如何在悬停时显示范围。范围通常与点击事件相关。如果我悬停并更改输入框,那么它必然会调用 onChange 函数。相反,如果您将鼠标悬停,则应在查找范围时禁用此事件。此外,根据我的 anwser,我看到许多答案出现在类似的行中。太令人惊讶了 我需要输入字段中的日期在悬停时更改。请查看 kayak.co.in .. 如果您将鼠标悬停在输入字段中更新的日期上。 那你为什么不用同样的js呢?【参考方案6】:

通过使用 jQuery 和 jQuery UI:

<div id="date_div">
     <input type="text" id="test" placeholder="Hover Me"/>
    <div id="datePicker"></div>
</div>

<script>
jQuery(function($) 
    $('#datePicker').datepicker(
       onSelect: function(dat)
          $('#test').val(dat);
       
    );
    $('#datePicker').hide();

    $('#date_div').hover(function()
         $('#datePicker').fadeIn(200);
    , function() 
         $('#datePicker').fadeOut(200);
    );
);
</script>

查看演示@:http://jsfiddle.net/renishar/ZVf48/4/

还包括 jQuery 和 jQuery UI 库..

【讨论】:

【参考方案7】:

您可以在悬停日期元素时使用委托,如果是这样,请强制单击元素本身。

代码:

$("body").delegate(".datepickerDays td span","hover",function(e)
    $(this).click();
)

由于我不能让插件在较新版本的 jQuery 上运行,我必须使用 delegate

演示:http://jsfiddle.net/IrvinDominin/fFc7h/

【讨论】:

那 (delegate) 是我需要添加的唯一代码块吗?因为它对我不起作用,我还缺少任何其他更改吗? @Nimbuz 检查小提琴,它有效;你用的是什么 jQuery 和插件版本? @Nimbuz 我正在检查它 @IrvinDomininakaEdward @Nimbuzz 当我使用 jQuery 1.10.x 时插件坏了。这就是我使用 1.3.x 的原因,但经过调查发现,插件使用的是 $.curCss,它在 1.8 中已被弃用。因此使用 1.7.x 无需更改插件即可工作,它应该有 delegate 甚至 on。嗯。应该更新我的答案。 @Nimbuz 我必须知道你想做什么;单击两个元素后,插件获取一个范围,第三次单击表示一个新的范围开始。这段代码中也发生了同样的情况:jsfiddle.net/IrvinDominin/zkKpY,因为悬停表示点击。那么悬停的期望效果是什么?总是扩大/限制范围?【参考方案8】:

使用 eventName 'mouseover' 而不是 'hover'

【讨论】:

【参考方案9】:

正如我在 DatePicker 插件给出的可选参数中看到的那样,该插件没有 onHover 函数。

但是,如果您有生成 DatePicker 的代码副本,您实际上可以在插件中添加自己的 jquery .hover() 方法,以在鼠标进入元素/插件时触发。

这是 .hover() 方法的文档。

http://api.jquery.com/hover/

【讨论】:

以上是关于jQuery Datepicker - 悬停时获取日期的主要内容,如果未能解决你的问题,请参考以下文章

jQuery ajax 提交表单并从 datepicker、按钮获取值

如何使用 jQuery 在鼠标悬停时找到当前元素?

JQuery UI datepicker onChangeMonthYear 获取 td

JQuery Datepicker 获取选定日期

Datepicker JQUERY 不选择输入日期

使用 jQuery 在页面加载时检测鼠标悬停