Javascript - 单击按钮后代码停止工作

Javascript - Code stops working after click on button

我正在尝试创建某种日历应用程序。
当您单击空白框时,它会显示一个用于创建事件的表单。 您使用 "ANTERIOR" 或 "SIGUIENTE" 导航日历。
当您单击一个框时该表单会正确显示,直到您单击 "ANTERIOR" 或 "SIGUIENTE" 然后它停止工作。
这是完整的代码:

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="css/calendar.css">
    <title></title>
</head>
<body>
    <div id="calendar">
    </div>

    <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <script src="js/calendar.js"></script>
</body>
</html>

calendar.js

// function to add days to date
Date.prototype.addDays=function(d){return new Date(this.valueOf()+864E5*d);};
Date.prototype.subtractDays=function(d){return new Date(this.valueOf()-864E5*d);};

// set initial variables
var longDays = ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"];
var shortDays = ["Lun", "Mar", "Mie", "Jue", "Vie", "Sab"];
var months = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'];
var time = ['8<br>am', '9<br>am', '10<br>am', '11<br>am', '12<br>pm', '1<br>pm', '2<br>pm', '3<br>pm', '4<br>pm', '5<br>pm']
var weekStart = new Date();
weekStart = weekStart.subtractDays(weekStart.getDay() - 1);
var nav = '<div class="nav">\
    <button id="prev-week" class="nav-prev-btn"><< Anterior</button>\
    <button id="next-week" class="nav-next-btn">Siguiente >></button>\
    </div>';

function formatDate(date) {
    var month = date.getMonth();
    var date = date.getDate();
    return date.toString() + '/' + months[month];
}

function showCalendar(startDate) {

    var days = shortDays;
    if ($(window).width() > 640) {
        days = longDays;
    }

    var cal = document.createElement('div');
    cal.setAttribute('id', 'calendar-wrapper');

    var timeDiv = document.createElement('div');
    timeDiv.setAttribute('id', 'hours');
    timeDiv.className = "column time";
    var corner = document.createElement('div');
    corner.className = "box corner";
    timeDiv.appendChild(corner);
    for (i=0; i<10; i++) {
        var box = document.createElement('div');
        box.className = 'box';
        $(box).append("<p>" + time[i] + "</p>");
        timeDiv.appendChild(box);
    }
    $(cal).append(timeDiv);

    var tempDate = startDate;
    for (i=0; i<6; i++) {
        var dayContainer = document.createElement('div');
        dayContainer.className = "column day";
        var dayBox = document.createElement('div');
        dayBox.className = "box";
        var text = days[i] + "<br>" + formatDate(tempDate);
        $(dayBox).append(text);
        dayContainer.appendChild(dayBox);
        for (j=8; j<18; j++) {
            var box = document.createElement('div');
            box.className = "box available";
            box.setAttribute('data-year', tempDate.getFullYear());
            box.setAttribute('data-month', tempDate.getMonth());
            box.setAttribute('data-date', tempDate.getDate());
            box.setAttribute('data-hour', j);
            dayContainer.appendChild(box);
        }
        $(cal).append(dayContainer);
        tempDate = tempDate.addDays(1);
    }
    $('#calendar').append(cal);
}

function nextWeek() {
    $('#calendar-wrapper').remove();
    weekStart = weekStart.addDays(7);
    showCalendar(weekStart);
}
function prevWeek() {
    $('#calendar-wrapper').remove();
    weekStart = weekStart.subtractDays(7);
    showCalendar(weekStart);
}


function showAddEvent(data) {
    $('.new-event').remove();
    var date = data['date'] + '/' + (parseInt(data['month']) + 1) + '/' + data['year'];
    var time = data['hour'] + ':00';
    var form = '<form action="#" method="POST">\
        <label for="date">Fecha: <input type="text" name="date" value="' + date + '">\
        <label for="time">Hora: <input type="text" name="time" value="' + time + '">\
        <label for="comments">Observaciones: <textarea name="comments"></textarea>\
        <input class="submit-btn" type="submit" value="Enviar">\
        <button class="cancel-btn">Cancelar</button>\
        </form>';
    formWrapper = document.createElement('div');
    formWrapper.className = 'new-event';
    $(formWrapper).append(form);
    $('body').append(formWrapper);
}


$(document).ready(function() {

    $("#calendar").append(nav);
    // initiate the calendar
    showCalendar(weekStart);

    // previous week button handler
    $("#prev-week").click(function() {
        prevWeek();
    });

    // Next week button handler
    $("#next-week").click(function() {
        nextWeek();
    });

    $('.available').click(function() {
        var data = $(event.target).data();
        showAddEvent(data);
    });
});

问题是,当您点击 #prev-week#next-week 时,您实际上调用了删除现有 HTML 部分的函数,即 #calender-wrapper 然后创建一个新的日历包装器,其中包含带有 .availabe classes.

的元素

jQuery .click 事件绑定方法称为 直接绑定方法 ,当您删除 #calender-wrapper jQuery 将 .availabe 元素视为新对象,即使它们具有相同的 class 和相同的名称。

或者,使用委托事件来附加事件处理程序。喜欢...

$( document ).on( "event-name", ".dynamic-element-selector", function() {
    ##code;
});

看,我没有完全理解这件事,为什么会这样,但这是真的。

Event handlers are bound only to the currently selected elements; they must exist at the time your code makes the call to .on(). To ensure the elements are present and can be selected, place scripts after the elements in the HTML markup or perform event binding inside a document ready handler. Alternatively, use delegated events to attach event handlers.

Source - jQuery .on() documentation

更新:

请将您脚本的这一部分替换为:

    $(document).ready(function() {

        $("#calendar").append(nav);
        // initiate the calendar
        showCalendar(weekStart);

        // previous week button handler
        $("#prev-week").click(function() {
            prevWeek();
        });

        // Next week button handler
        $("#next-week").click(function() {
            nextWeek();
        });

        $('.available').click(function() {
            var data = $(event.target).data();
            showAddEvent(data);
        });
    });

收件人:

    $(document).ready(function() {

        $("#calendar").append(nav);
        // initiate the calendar
        showCalendar(weekStart);

        // previous week button handler
        $("#prev-week").click(function() {
            prevWeek();
        });

        // Next week button handler
        $("#next-week").click(function() {
            nextWeek();
        });

        $(document).on('click', '.available', function() {
            var data = $(this).data();
            showAddEvent(data);
        });
    });