Javascript works in IE but not in Chrome

2019-08-20 07:34发布

问题:

I'm trying to detect text, textarea and dropdown changes via javascript, so upon window unload, the browser will prompt that you have unsaved changes. My code works perfectly with IE but it is really unstable in Chrome. Here's my code.

var ctr = 1;
    var isFirstLoad = true;
    function propertyChangedByCode() {
        ctr = 0;
        propertyChanged()
    }
    function propertyChanged() {
        $('[id$=SaveButton]').removeAttr("disabled");
        $('[id$=SaveButton]').removeAttr("class");
        $('[id$=SaveButton]').addClass("btn btn-primary");
        warnMessage = 'Warning: You have unsaved changes.';

        window.onbeforeunload = function () {
            if (ctr == 0) {
                return warnMessage
            }
            else if (ctr == 1) {
                ctr = 0;
            }
        }
    }
    $("body").click(function (event) {
        console.log(event.target);
        if (event.target.type == "submit" && event.target.value != "Save" && event.target.value != "Cancel" && event.target.value != "Next") {
            ctr = 0;
            propertyChanged();
            console.log("BODY clicked");
        }
    });

    function pageLoad() {

        jQuery("input.datepicker").dp({
            dateFormat: 'M d, yy',
            altFormat: 'yy-mm-dd',
            buttonText: '<i class="icon icon-calendar"></i>',
            showOn: 'both'
        });

        $("button.ui-datepicker-trigger").addClass('btn right');

        console.log("PageOnLoad: " + ctr);

        var warnMessage = 'Warning: You have unsaved changes.';
        $('input[type="text"],select,textarea').each(function (k, v) {


            var elem = $(this);
            // Save current value of element
            elem.data('oldVal', elem.val());

            // Look for changes in the value
            elem.bind("change keyup input paste", function (event) {
                // If value has changed...
                if (elem.data('oldVal') != elem.val()) {
                    propertyChanged();
                }
            });
        });

        $('.btn').click(function (e) {
            console.log("whatever");
            ctr = 1;
        });

        //ui-datepicker-trigger
        $('.ui-datepicker-trigger').click(function (e) {
            console.log("date");
            ctr = 0;
        });

        if (isFirstLoad) {
            window.onbeforeunload = null;
            $('[id$=SaveButton]').attr("disabled", "disabled")
            ctr = 1;

            console.log("Disable");
            isFirstLoad = false;
        }
    }

I use a counter(ctr) and change it to 1 and 0 depending on the circumstances. But ultimately ctr = 0 triggers the notification while 1 is the opposite. Upon loading of the page, and I navigated away from the page, the browser prompts even if I don't have any changes. Again, this code works perfectly in IE. I can't using other solutions than this because I will have to update a lot of pages if I change my current procedure. Any ideas why Chrome won't run the js? Thanks!

EDIT:

After investigating the code, this line seems to be causing the problem

elem.bind("change keyup input paste", function (event) {
                ctr = 0;
                // If value has changed...
                if (elem.data('oldVal') != elem.val()) {
                    propertyChanged();
                }
            });

The if statement returns true at first load in Chrome, while false in IE. Which should be false upon first load since no changes is made on first load.