【问题标题】:JQuery click function not working after removing and adding back elements删除和添加元素后,JQuery单击功能不起作用
【发布时间】:2013-07-31 12:10:58
【问题描述】:

这是我的点击功能

$('.cal table tbody td').on('click', function () {
    if($(this).hasClass('available'))
    {
        alert('asd');
    }
});

我遇到的问题是切换到下个月或上个月后,我在日历上的点击功能不起作用。

例如在我的 JSFIDDLE 中,如果你移动到上个月然后返回到当前月并执行点击功能,它就不再起作用了。

编辑:我正在使用一个名为 date.js 的外部库,请查看我的 jsfiddle 以更清楚地了解发生了什么。

编辑 2:更新 jsfiddle 链接

jsfiddle

【问题讨论】:

  • [object Date] 没有方法'isAfter'
  • 查看我的 jsfiddle,我使用了一个名为 date.js 的外部库,我忘了在我的帖子中提及。
  • 您对动态创建的元素使用了不正确的 on 变体。看看我的回答

标签: javascript jquery html css calendar


【解决方案1】:

您可以查看工作版本here。或者看看下面更新的 jQuery。

var firstday = new Date();
var lastday = new Date();
var calendarmonth = new Date();
var CCheck;

$(document).ready(function () {
    Date.today();

    firstday.setMonth(Date.today().getMonth(), 1);
    lastday.setMonth(Date.today().getMonth() + 1, 0);
    calendarmonth.setMonth(Date.today().getMonth());

    calendarInit();

    $('#calendar-prev').on('click', function () {
        if (CCheck > 35) {
            //render 6 rows
            for (i = 1; i < 7; i++) {
                $('#row' + i).remove();
            }
        } else {
            //render 5 rows
            for (i = 1; i < 6; i++) {
                $('#row' + i).remove();
            }
        }
        $("#month").empty();
        calendarmonth.addMonths(-1);
        firstday.addMonths(-1);
        lastday.setMonth(firstday.getMonth() + 1, 0);
        calendarInit();
    });

    $('#calendar-next').on('click', function () {
        if (CCheck > 35) {
            //render 6 rows
            for (i = 1; i < 7; i++) {
                $('#row' + i).remove();
            }
        } else {
            //render 5 rows
            for (i = 1; i < 6; i++) {
                $('#row' + i).remove();
            }
        }
        $("#month").empty();
        calendarmonth.addMonths(1);
        firstday.addMonths(1);
        lastday.setMonth(firstday.getMonth() + 1, 0);
        calendarInit();
    });
    addRemoveClickTrigger();

});

function calendarInit() {
    CCheck = lastday.getDate() + firstday.getDay();
    var i;
    var colNo;
    var a = 1;
    var days = new Array();
    $("#month").append("Month: " + calendarmonth.toString("MMMM, yyyy"));
    if (CCheck > 35) {
        //render 6 rows
        for (i = 1; i < 7; i++) {
            $('#calendar tbody').append('<tr id = row' + i + '></tr>');
            colNo = a + 6;
            for (a; a <= colNo; a++) {
                var datenum = a - firstday.getDay();
                if (datenum < 1) {
                    $('#row' + i).append('<td></td>');
                } else if (datenum > lastday.getDate()) {
                    $('#row' + i).append('<td></td>');
                } else {
                    $('#row' + i).append('<td id = Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + datenum + '>' + datenum + '</td>');
                    days[datenum] = new Date();
                    days[datenum].set({
                        month: calendarmonth.getMonth(),
                        day: datenum,
                        year: calendarmonth.getFullYear()
                    });
                }
            }
        }
    } else {
        //render 5 rows
        for (i = 1; i < 6; i++) {
            $('#calendar tbody').append('<tr id = row' + i + '></tr>');
            colNo = a + 6;
            for (a; a <= colNo; a++) {
                var datenum = a - firstday.getDay();
                if (datenum < 1) {
                    $('#row' + i).append('<td></td>');
                } else if (datenum > lastday.getDate()) {
                    $('#row' + i).append('<td></td>');
                } else {
                    $('#row' + i).append('<td id = Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + datenum + '>' + datenum + '</td>');
                    days[datenum] = new Date();
                    days[datenum].set({
                        month: calendarmonth.getMonth(),
                        day: datenum,
                        year: calendarmonth.getFullYear()
                    });
                }
            }
        }
    }
    /*alert(Date.today().getMonth());
    alert(calendarmonth.getMonth());*/
    if (Date.today().getMonth() == calendarmonth.getMonth() && Date.today().getFullYear() == calendarmonth.getFullYear()) {
        for (i = 1; i <= lastday.getDate(); i++) //Date highlight
        {
            if (Date.today().getDate() == i) //highlight today's date
            {
                $('#Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + i).addClass("today");
            } else if (Date.today().getDate() > i) //highlight unavailable dates
            {
                $('#Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + i).addClass("unavailable");
            } else if (Date.today().getDate() < i) {
                $('#Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + i).addClass("available");
            }
        }
    } else if (Date.today() > calendarmonth) {
        for (i = 1; i <= lastday.getDate(); i++) //Highlight dates before today to unavailable
        {
            $('#Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + i).addClass("unavailable");
        }
    } else {
        for (i = 1; i <= lastday.getDate(); i++) //Condition highlighting
        {
            $('#Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + i).addClass("available");
            if (days[i].getDay() == 0 || days[i].getDay() == 6) // set weekends to unavailable
            {
                $('#Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + i).removeClass("available");
                $('#Y' + calendarmonth.getFullYear() + 'M' + calendarmonth.getMonth() + 'Day' + i).addClass("unavailable");
            }
        }
    }
    addRemoveClickTrigger();
} //calendarInit()

function addRemoveClickTrigger()
{
    $('.cal table tbody td').off();
    $('.cal table tbody td').on({
        'click':
        function () 
        {
            alert(jQuery(this).prop('class'));
            if ($(this).hasClass('available')) 
            {
                alert('asd');
            }
        }
    });        
} //addRemoveClickTrigger()

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    使用这个

    $(document).on('click','.cal table tbody td', function () {
            if ($(this).hasClass('available')) {
                alert('asd');
            }
    });
    

    而不是这个

    $('.cal table tbody td').on('click', function () {
            if ($(this).hasClass('available')) {
                alert('asd');
            }
        });
    

    前者是delegate的正确替代品

    【讨论】:

    • 我是否也应该使用.on() 更改我的其他功能?
    • 其他都是静态元素所以没有必要但是这个形式是首选see why
    【解决方案3】:

    您的上一个和下一个事件处理程序正在重新创建用于呈现日历的 DOM 元素。但是,您的点击处理程序仅附加到在注册处理程序时存在于 DOM 中的元素。 on() 的文档指出:

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

    您可能需要将该点击处理程序重新注册为您的calendarInit() 函数的一部分日历中的新行 - 新元素 - 被渲染之后。

    【讨论】:

      【解决方案4】:

      我立即注意到的一件事是,当您执行以下操作时:

      $('#calendar tbody').append('<tr id = row'+i+'></tr>'); 
      

      您需要记住,当您想为元素提供 ID 时,ID 的“值”部分应该用引号括起来。

      因此您需要对字符串进行转义以包含它们,以便您的浏览器可以正确解释 html。

      $('#calendar tbody').append('<tr id = \"row'+i+'\"></tr>');
      

      这样你的输出看起来像:

      <tr id="rowx"></tr>
      

      代替:

      <tr id=rowx></tr>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多