문제

일부 JavaScript 코드에 이상한 문제가 있습니다 (다시, JS 코드 디버깅을 싫어합니다). 나는 JSON 통화에서 채우는 일반 테이블에서 작업하고 있으며, 일부 페이징 (2x 페이징은 당신이 호출 할 수 있다고 생각합니다), 정렬 및 일부 행 선택을 지원했습니다. 모든 것이 잘 작동합니다. 그러나 행이 선택 제거되고 (및 선택되지 않은 경우) 내 add_navigate 이벤트가 두 번 발사되어 필요하지 않은 데이터를 약간 다시로드하고 필요하지 않은로드의 표시를 나타냅니다.

먼저 여기 내 JS 코드가 있습니다.

var customerType;
var selYear;
var selMonth;
var sdir;
var sort;
var page;
var noteId;
var hasDoneCall;
var customerId;

var customerIdChanged = false;


function initValues() {
    customerType = "Publisher";
    selYear = new Date().getFullYear();
    selMonth = new Date().getMonth()+1;
    sdir = false;
    sort = "CustomerName";
    page = 1;
    noteId = false;
    customerId = 0;

    hasDoneCall = location.href.indexOf('#') > 0;

}
function flash(elm, color, duration) {

    var current = elm.css('backgroundColor');

    elm.animate({ backgroundColor: 'rgb(' + color + ')' }, duration / 2).animate({ backgroundColor: current }, duration / 2);

}

function createNotes(elm) {
    var btn = jQuery(elm);
    btn.attr('disabled', 'disabled');
    bulkCreditOption('true', '', function(changeSet) {
        var i = 0;
        while (i < changeSet.length) {
            var selector = "input[type=checkbox][value=" + changeSet[i] + "].check:checked";
            var row = jQuery(selector).parent().parent();
            var cell = row.find("td:nth-child(2)");

            cell.html("<a href=\"javascript:showNotes('" + changeSet[i] + "')\">" + cell.html() + "</a>");
            flash(row, '60, 130, 200', 500);
            i++;
        }
        btn.removeAttr('disabled');
    });
}

function deleteNotes(elm) {
    var btn = jQuery(elm);
    btn.attr('disabled', 'disabled');
    bulkCreditOption('', 'true', function(changeSet) {
        var i = 0;
        while (i < changeSet.length) {
            var selector = "input[type=checkbox][value=" + changeSet[i] + "].check:checked";
            var row = jQuery(selector).parent().parent();
            var cell = row.find("td:nth-child(2)");

            cell.html(cell.text());
            flash(row, '60, 130, 200', 500);
            i++;
        }
        btn.removeAttr('disabled');
    });
}

function bulkCreditOption(createNotes, deleteNotes, callback) {
    var path = "/BulkCredit";
    var data = "";
    var checked = jQuery("input[type=checkbox].check:checked");
    checked.each(function(chk) {
        data += "&ids=" + urlencode(jQuery(this).val());

    });
    jQuery.ajax({
        type: 'POST',
        url: path,
        dataType: 'json',
        data: "createNotes=" + urlencode(createNotes) + data + "&deleteNotes=" + urlencode(deleteNotes),
        success: function(msg) {
            callback(msg);
        }
    });
}

initValues();

Sys.Application.add_init(function() {
    Sys.Application.add_navigate(function(sender, e) {
        var reinstate = e.get_state();
        if (typeof (reinstate) != 'undefined' && typeof (reinstate.customerType) != 'undefined') {
            customerType = reinstate.customerType;
            selYear = reinstate.selYear;
            selMonth = reinstate.selMonth;
            sdir = reinstate.sdir;
            sort = reinstate.sort;
            page = reinstate.page;
            noteId = reinstate.noteId;
            customerId = reinstate.customerId;

        } else {
            initValues();
        }

        if (!customerIdChanged) {

            jQuery("#customerTypeChanger").val(customerType);

            jQuery("#customerFilter").val(customerId);

            jQuery("#monthPicker").empty();

            makeMonthPicker();

            if (noteId != false && noteId != 'false') {
                doShowNotes();
            } else {
                jQuery("#notesContent").hide();
                jQuery("#tableContent").show();
                doAjaxCall();
            }
        } else {
            //logic to fetch customer specific stuff here, TODO
            customerIdChanged = false;
        }
    });
    Sys.Application.set_enableHistory(true);


    jQuery(document).ready(function() {
        origColor = jQuery("#dataTable > thead > tr > th").css('backgroundColor');

        makeMonthPicker();

        jQuery("#customerTypeChanger").val(customerType);
        jQuery("#customerTypeChanger").change(function() {
            customerType = jQuery(this).val();
            iqSetHistory();
        });

        jQuery("#customerFilter").change(function() {
            customerId = jQuery(this).val();
            var tableBody = jQuery("#dataTable > tbody");
            tableBody.find("tr").removeClass("selected");
            tableBody.find("tr[rel=" + customerId + "]").addClass("selected");
            customerIdChanged = true;
            iqSetHistory();
        });

        jQuery(".checkAll").click(function() {
            var elm = jQuery(this);
            if (elm.is(':checked')) {
                jQuery(".check").attr('checked', 'checked');
            } else {
                jQuery(".check").removeAttr('checked');
            }
        });

        if (!hasDoneCall) {
            if (noteId == false) {
                doAjaxCall();
            } else {
                doShowNotes();
            }
        }

    });
});

function makeMonthPicker() {
    var selDate = new Date();
    selDate.setFullYear(selYear);
    selDate.setMonth(selMonth-1);
    jQuery("#monthPicker").monthPicker(function(year, month) {
        selYear = year;
        selMonth = month;
        iqSetHistory();
    }, selDate);
}

var origColor;
var notesPath = "/ShowNotes";


function fadeOut(elm) {
    elm.animate({ backgroundColor: 'rgb(180, 180, 180)' }, 250);
}
function fadeIn(elm) {
    elm.animate({ backgroundColor: origColor }, 250);
}

function iqSetHistory() {
    var state = { 'customerType': customerType, 'selYear': selYear, 'selMonth': selMonth, 'sdir': sdir, 'sort': sort, 'page': page, 'noteId': noteId, 'customerId':customerId };

    Sys.Application.addHistoryPoint(state);
}
var ajaxPath = "/GetCreditListMonth";
function doAjaxCall() {

    fadeOut(jQuery("#dataTable > thead > tr > th"));
    jQuery.ajax({
        type: "POST",
        url: ajaxPath,
        dataType: "json",
        data: "month=" + selMonth + "&year=" + selYear + "&custType=" + customerType + "&sort=" + sort + "&sdir=" + sdir + "&page=" + page + "&asCsv=false",
        success: function(msg) {
            var table = jQuery("#dataTable");

            var tableBody = table.find("tbody");


            tableBody.empty();

            var i = 0;
            while (i < msg.Rows.length) {
                var data = msg.Rows[i];
                var row = jQuery("<tr rel=\"" + data.CustomerId + "\"></tr>");

                if (data.CustomerId == customerId) {
                    row.addClass("selected");
                }

                if (i % 2 == 1) {
                    row.addClass("alternatetablerow");
                }

                var custName = data.CustomerName;
                if (data.PaymentCreated) {
                    custName = "<a href=\"javascript:showNotes('" + getCreditId(data.CustomerId) + "')\">" + custName + "</a>";
                }
                row.append("<td><input type=\"checkbox\" class=\"check\" name=\"ids\" value=\"" + getCreditId(data.CustomerId) + "\" /></td>");
                row.append("<td>" + custName + "</td>");
                row.append("<td>" + data.AmountExcludingTaxes + "</td>");
                row.append("<td>" + data.BonusAmount + "</td>");
                row.append("<td>" + data.Amount + "</td>");

                row.appendTo(tableBody);
                i++;
            }


            tableBody.find("input, a").click(function(event){ //Stop clicks from falling through to the table row event
                event.stopPropagation();
                return true;
            });
            tableBody.find("tr").click(function(event){
                var row = jQuery(this);
                if (row.hasClass("selected")) { //Deselect
                    jQuery("#customerFilter").val(0);
                } else {
                    jQuery("#customerFilter").val(jQuery(this).attr('rel'));
                }
                jQuery("#customerFilter").triggerHandler("change");
            });



            createPager(msg.Pages, jQuery("#pager"));
            jQuery(".checkAll").triggerHandler('click');

            fadeIn(table.find('thead > tr > th'));
        }
    });
}

function downloadListAsCsv() {
    window.location.href = ajaxPath + "?month=" + selMonth + "&year=" + selYear + "&custType=" + customerType + "&sort=" + sort + "&sdir=" + sdir + "&page=0&asCsv=true";
}

function doShowNotes(){
    jQuery.ajax({
        type: "GET",
        url: notesPath + "/" + noteId,
        success: function(msg) {
            jQuery("#tableContent").hide();
            jQuery("#notesContent").html(msg).show();

        }

    });
}

function showNotes(id) {
    noteId = id;
    iqSetHistory();
}

function showTable() {
    noteId = false;
    iqSetHistory();
}

function getCreditId(custId) {
    return selYear + "-" + selMonth + "-" + custId;
}

function sortDataTable(col) {
    if (col == sort) {
        sdir = !sdir;
    } else {
        sdir = false;
    }

    page = 1

    sort = col;
    iqSetHistory();
}

function createPager(totalPages, elm) {
    elm.empty();
    if (totalPages > 1)
        {
            var builder = "";


            var numDirections = 2;

            if (page > 1)
            {
                if (page - numDirections - 1 > 0)
                {
                    builder += CreatePageLinkStatic(1, "&laquo;");
                    builder += " ";
                }

                builder += CreatePageLinkStatic(page - 1, "&lt;");
                builder += " ";
            }

            var n = page - numDirections;
            while (n < page)
            {
                if (n > 0)
                {
                    builder += CreatePageLinkStatic(n, n);
                    builder += " ";
                }
                n++;
            }

            builder += page;
            builder += " ";

            n = page + 1;

            while (n <= page + numDirections && n <= totalPages)
            {
                builder += CreatePageLinkStatic(n, n);
                builder +=" ";
                n++;
            }

            if (page < totalPages)
            {
                builder += CreatePageLinkStatic(page + 1, "&gt;");
                builder += " ";
                if (page + numDirections < totalPages)
                {
                    builder += CreatePageLinkStatic(totalPages, "&raquo;");
                }
            }

            builder;

            elm.append(builder);
        }

}
function CreatePageLinkStatic(page, str){
    return "<a href=\"javascript:pageDataTable(" + page + ")\">" + str + "</a>";
}

function pageDataTable(newPage){
    page = newPage;
    iqSetHistory();
}

그리고 마크 업 :

<div id="tableContent">
<select id="customerTypeChanger">
    <option selected="selected" value="Publisher">Publisher</option>
    <option value="Advertiser">Advertiser</option>
</select>
<select id="customerFilter"><option value="0">Choose Customer</option><option value="1">Customer 1</option><option value="1">Customer 2</option>...</select>
<div id="monthPicker"></div>
<div><a href="javascript:downloadListAsCsv()">DownloadAsCSV</a></div>
    <table id="dataTable" class="grid">
        <thead>
            <tr>
                <th style="text-align: left"><input type="checkbox" name="toggleCheckBox" class="checkAll" value="dummy" /></th>
                <th><a href="javascript:sortDataTable('CustomerName')">Customer name</a></th>
                <th><a href="javascript:sortDataTable('AmountExcludingTaxes')">Amount</th>
                <th><a href="javascript:sortDataTable('BonusAmount')">Bonus amount</a></th>
                <th><a href="javascript:sortDataTable('Amount')">Amount including VAT</a></th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    <div class="pagination" id="pager"></div>
    <div>With the selected rows</div>
<input id="createNotes" type="button" value="Create notes" onclick="javascript:createNotes(this)" /> <input id="deleteNotes" value="Delete notes" type="submit" onclick="javascript:deleteNotes(this)" />

</div>
<div id="notesContent"></div>

필요한 경우, MonthPicker에 대해 내가 한 코드는 다음과 같습니다 (몇 달 사이에 앞뒤로 튕겨서 출력을 제공하는 매우 기본적인 DatePicker입니다.

<2009 년 4 월 2009 년 5 월 2009 년 6 월>

(Bold가 그 달 기간 만 볼 수 있도록 클릭 가능한 링크가있는 경우, 이탤릭체는 이미 선택된 것입니다. 실제 HTML 마크 업은 분명히 다릅니다)

JQuery UI의 DatePicker를 사용하여 현지화 된 달의 이름을 얻습니다.

(function($) {


    var selDate;

    $.fn.monthPicker = function(callback, selectedDate) {

        selDate = selectedDate;

        var elm = this;

        this.html("<span class=\"prevMonthButton\"><a href=\"\">&lt;</a></span><span class=\"prevMonth\"><a href=\"\"></a></span><span class=\"curMonth\"></span><span class=\"nextMonth\"><a href=\"\"></a></span><span class=\"nextMonthButton\"><a href=\"\">&gt;</a></span>");

        populateDates(this);

        var prevMonthFunc = function() {

            var month = selDate.getMonth() - 1;
            if (month < 0) {
                month = 11;
                selDate.setFullYear(selDate.getFullYear() - 1);
            }
            selDate.setMonth(month);

            populateDates(elm);
            callback(selDate.getFullYear(), selDate.getMonth() + 1);
            return false;
        }
        var nextMonthFunc = function() {
            var month = selDate.getMonth() + 1;
            if (month > 11) {
                month = 0;
                selDate.setFullYear(selDate.getFullYear() + 1);
            }
            selDate.setMonth(month);

            populateDates(elm);
            callback(selDate.getFullYear(), selDate.getMonth() + 1);
            return false;
        };

        this.find(".prevMonth > a").click(prevMonthFunc);
        this.find(".prevMonthButton > a").click(prevMonthFunc);
        this.find(".nextMonth > a").click(nextMonthFunc);
        this.find(".nextMonthButton > a").click(nextMonthFunc);
    }

    function populateDates(elm) {

        var months = jQuery.datepicker._defaults.monthNames;
        var selYear = selDate.getFullYear();
        var selMonth = selDate.getMonth();


        elm.find(".curMonth").text(months[selMonth] + " " + selYear);

        var prevMonth = selMonth - 1;
        var prevYear = selYear;
        if (prevMonth < 0) {
            prevMonth = 11;
            prevYear = prevYear - 1;
        }

        elm.find(".prevMonth > a").text(months[prevMonth] + " " + prevYear);

        var nextMonth = selMonth + 1;
        var nextYear = selYear;
        if (nextMonth > 11) {
            nextMonth = 0;
            nextYear = nextYear + 1;
        }

        elm.find(".nextMonth > a").text(months[nextMonth] + " " + nextYear);
    }
})(jQuery);

나는이 JavaScript 코드의 대부분을 알고 있습니다. 그러나 기본 부분의 경우 작업을 아주 잘 수행하는 것처럼 보이지만 행을 클릭하여 선택한 다음 클릭하여 선택 해제 및 붐을 클릭하고 add_navigate를 두 번 호출합니다. 내 JSON 서비스에 대한 추가 호출과 클라이언트 측의 시각적 깜박임 - 왜 그런 일이 발생하는지 (그리고 더 이상한 것, 그것이 선택된 것과 선택된 것도 아닌 경우에도 더 이상한 일을 할 수 없습니다).

도움이 되었습니까?

해결책

나는 시도 할 것이다

.unbind('click').click(function()

대신에

.click(function()

클릭 이벤트가 두 번 묶이지 않도록하기 위해.

다른 팁

문제는 이벤트가 동일한 요소에 대한 이벤트를 무의식적으로 바인딩하는 것이라고 생각합니다.

이것은 일반적으로 시나리오입니다.

(function($){
   var MyDocument = new Object({
       prepareBody : function(){

          //addClick Event
          $('div#updatedElement').click(MyDocument.ajaxCall());

          //adjusting the height of an updatedElement to an-otherElement
          $('div#updatedElement').css('height', $('div#otherElement').height());
       },
       ajaxCall : function(){

          //do your ajax Call
           $.getJSON('index.php',{param:1, param:2},function(response){

                //do something with your response
                $('div#updatedElement').html(response)

               //say if after your call you decide to update the body again
                MyDocument.prepareBody();

               //what that does is you will double bind click to the updateElement div.
               //The next time that it is click, the AjaxCall function will run twice
                //The next time it is clicked the MyDocument.ajaxCall function will be run four times

                //8 - 16 - 32 and by now, firefox would have crashed!

           },'json');
       }
   });
   $(document).ready(function(){
       MyDocument.prepareBody()
   });
})(jQuery);

Kclough가 조언 한 바와 같이, 한 번만 실행되도록 바인딩하기 전에 이벤트를 풀어주십시오! 슬픈 jQuery는 다른 프레임 워크처럼 그것들을 덮어 쓰지 않습니다!

이것이 다른 사람에 도움이되기를 바랍니다

오 미안 해요이 질문에 대해 완전히 잊어 버렸습니다.

이 후에 약간의 코드를 재구성했고 문제는 사라졌습니다. 나는 이것이 무엇을 원인했는지 정확히 알지 못한다.

Anyhoow, 문제는 해결되었으며, 어떻게 또는 이유를 알지 못하며, 여전히 약간 귀찮게하지만 다른 한편으로는 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top