在jQuery datepicker中发出绑定click事件

时间:2014-10-02 10:47:57

标签: javascript jquery jquery-ui datepicker

我试图在呈现jQuery datepicker之后将click事件绑定到.ui-state-default(我不能控制创建datepicker的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()?

我哪里错了?

6 个答案:

答案 0 :(得分:4)

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

  

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

jQuery.bind()也适用于现有元素。因此它适用于附加到DOM的第一个,但不会动态附加其余的。

解决方法是使用MutationObserver来监听DOM更改并允许您做出相应的反应。有一个很好的jQuery插件名为' Live Query'这简化了为DOM中的特定元素创建Mutation Observers的过程。

例如,使用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');
        });
    }
);

它将听取DOM中的<body> <table> <td data-handler="selectDay"] <a class="ui-state-default">更改,然后根据点击元素采取相应措施。

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

&#13;
&#13;
/**
 * 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();
});
&#13;
.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;
}
}
&#13;
<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>
&#13;
&#13;
&#13;

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

答案 1 :(得分:3)

很容易!

Datepicker(jQuery-UI)

  • 当您选择日期时(点击事件添加到包含td的{​​{1}},它会触发名为a.ui-state-default的方法。
  • datepicker插件使用名为_selectDay的附加方法附加方法,该附加方法将_attachHandlers附加到具有属性_selctDay的元素,并在其后添加data-handler=selectDay以防止默认值和传播(与return falseevent.preventDefault()相同)。

所以问题是在插件的event.stopPropagation();方法中添加了return false。 我将其删除并将其保存到git(整个jQuery-UI包含所有内容),但您也可以通过搜索方法并在_attachHandlers附件后删除return false来自行删除它。

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

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

代码测试:

selectDay

答案 2 :(得分:2)

使用&#34; 绑定更改事件&#34;相反&#34; 绑定点击事件&#34;

示例:

    $('[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 () {});

这对你有用。

答案 3 :(得分:1)

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

    $("#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');
        }
    });

有关详细信息,请查看documentation

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

答案 4 :(得分:0)

您需要先检查页面是否已准备就绪:

$( document ).ready(function() {

});

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

答案 5 :(得分:0)

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

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