在jQuery日期选择器中发出绑定单击事件

Issue binding click event in jQuery datepicker

本文关键字:绑定 单击 事件 jQuery 日期 选择器      更新时间:2023-09-26

我试图在呈现jQuery日期选择器后将click事件绑定到.ui默认状态(我对创建日期选择器的html没有任何控制权,因此我不能使用任何日期选择器特定的事件),并且它使用$.bind()很好,但不使用$.on()。

在控制台中工作的$.bind():

$('[data-handler=selectDay] a.ui-state-default').bind('click', function(){
        if($(this).hasClass('ui-state-active')) return;
        alert('changed date');
        $("button.checkout").addClass('disabled');
        $("button.checkout span").html('Choose Your Payment Method');
        $(".stage3").html(tmpl('stage3_tpl')).removeClass('noBg');
});

$.on()在页面上不起作用:

$(document.body).on('click', '[data-handler=selectDay] a.ui-state-default', function(){
        if($(this).hasClass('ui-state-active')) return;
        alert('changed date');
        $("button.checkout").addClass('disabled');
        $("button.checkout span").html('Choose Your Payment Method');
        $(".stage3").html(tmpl('stage3_tpl')).removeClass('noBg');
});

日期选择器并不总是在页面上,所以我不相信我可以使用$.bind()?

我哪里错了?

这与DOM更改有关。jQuery.on()方法绑定到现有的DOM元素,这就是为什么它不适用于动态添加的日期选择器元素。

jQuery文档:事件处理程序仅绑定到当前选择的元素;它们必须存在于当时的页面上您的代码调用.on()

CCD_ 4同样适用于已有的元素。因此,它将适用于连接到DOM的第一个,但不适用于动态连接的其余部分。

解决方案是使用MutationObserver来监听DOM的变化,并允许您做出相应的反应。有一个很好的jQuery插件叫做"实时查询",它简化了为DOM中的特定元素创建突变观测器的过程。

例如,使用jQuery.livequery()的代码如下所示:

$('body').livequery(
    'table td[data-handler=selectDay] a.ui-state-default',
    function(elem){
        if( jQuery(elem).hasClass('ui-state-active') ) return;
        jQuery(elem).on('click', function(){
            $("button.checkout").attr('disabled','disabled').addClass('disabled');
            $("button.checkout span").html('Choose Your Payment Method');
        });
    }
);

它将监听<body> <table> <td data-handler="selectDay"] <a class="ui-state-default">DOM的变化,然后在单击某个元素时采取相应的行动。

以下是一个工作示例:http://jsfiddle.net/laelitenetwork/ej96f7m5/

/**
 * Livequery listen for DOM mutation events
 * this allows to keep listening date picker
 * events, even after being dynamically appended to
 * DOM
 */
$('body').livequery(
    'table td[data-handler=selectDay] a.ui-state-default',
    function(elem){
        if( jQuery(elem).hasClass('ui-state-active') ) return;
        jQuery(elem).on('click', function(){
            $("button.checkout").attr('disabled','disabled').addClass('disabled');
            $("button.checkout span").html('Choose Your Payment Method');
        });
    }
);
$('.clean').on('click', function(){
    /** 
     * Reset testing playground
     * This simulates dynamic DOM Mutation
     */
    jQuery('.wrap').empty();
    jQuery('.wrap').append('<input type="text" class="date-picker"/>');
    jQuery('button.checkout').attr('disabled',false);
    jQuery('button.checkout span').html('Checkout');
    $(function() {
        $( ".date-picker" ).datepicker();
    });
});
// Run datepicker
$(function() {    
    $( ".date-picker" ).datepicker();
});
.wrap {
    border: 1px solid #fefefe;
    background: #fafafa;
    text-align: center;
}
.wrap input {
    border: 1px solid #fcfcfc;
    padding: .5em;
    font-size: 1.1em;
    text-align: center;
    background: #f1f1f1;
}
.buttons {
    text-align: center;
    background: #fbfbfb;
}
.checkout {
    background: #ee5555;
    color: #fff;
    border: 0;
}
button:disabled {
    background: #efefef;
    color: #999;
    border: 1px solid #ccc;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://staticelite.info/elitenetwork/scripts/jquery.livequery.min.js"></script>
<link href="http://code.jquery.com/ui/1.11.1/themes/black-tie/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<div class="wrap">
    <input type="text" class="date-picker"/>
</div>
<div class="buttons">
    <button class="clean">Clean</button> | 
    <button class="checkout"><span>Checkout</span></button>
</div>

p.S:点击Clean将模拟一个动态附加到DOM的元素。

简单的一个!

日期选择器(jQuery UI):

  • 当您选择添加到包含a.ui-state-defaulttd中的日期(单击事件)时,它会激发一个名为_selectDay的方法
  • 日期选择器插件使用名为_attachHandlers的附加方法来附加方法,该方法将_selctDay附加到具有属性data-handler=selectDay的元素,并在其后面添加return false以防止默认值和传播(与event.preventDefault()event.stopPropagation();相同)

所以问题是在插件的_attachHandlers方法中添加了return false。我为您删除了它并将其保存到git中(整个jQuery UI都有),但您也可以通过搜索方法并删除selectDay附件后的return false来自己删除它。

Demo(外部资源-包括自定义jQuery UI):jsFiddle

GitHub-自定义jQuery UI,不返回false:GitHub

测试代码:

$(document.body).on('click', '[data-handler=selectDay] a.ui-state-default', function(){
    //This will be triggered after the handler of the jQuery UI: 
    if($(this).hasClass('ui-state-active')) return false;
    alert('changed date');
    /* Rest of your code */
    return false;
});
$(function() {    
    $( ".date-picker" ).datepicker();
});

使用"绑定更改事件"代替"bind-click事件"

示例:

    $('[data-handler=selectDay] a.ui-state-default').datepicker({
        dateFormat: "mm/dd/yy", 
        changeMonth: true, 
        changeYear: true, 
        yearRange: '-50:c', 
        maxDate: new Date,          
        showOn: "both", 
        buttonImage: "../../calender-icon.png", 
        buttonImageOnly: true, 
        beforeShow:   
        BeforeShowForDatePicker, 
        onClose: onCloseForDatePicker }).bind("change", function () {});

这对你有用。

最好使用内置事件。例如:

    $("#datepicker").datepicker({
        onSelect: function(dateText, inst) {
            alert('changed date');
            $("button.checkout").addClass('disabled');
            $("button.checkout span").html('Choose Your Payment Method');
            $(".stage3").html(tmpl('stage3_tpl')).removeClass('noBg');
        }
    });

有关更多信息,请查看文档。

值得注意的是,我会考虑的事件,如onSelect和onClose,都列在选项列表中,而不是事件列表中。

您需要先用检查页面是否准备好

$( document ).ready(function() {
});

如果我是对的。这为我解决了最后一次的问题。不知道你是否这样做?

接受的答案不正确,您可以使用事件委托将事件侦听器绑定到DOM中未包含的元素。正如其他人所说,真正的问题是jQueryUI杀死了冒泡的点击事件,所以只需将处理程序绑定到mouseup事件即可:

$(document).on('mouseup', 'a.ui-state-default', function() {
  // Stuff
});