Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Срабатывает 2 раза подряд одно событие (https://javascript.ru/forum/jquery/77706-srabatyvaet-2-raza-podryad-odno-sobytie.html)

alex-romanov 08.06.2019 21:22

Срабатывает 2 раза подряд одно событие
 
/*выборка нескольких строк, для удаления или обновления данных;
        * если был щелчок по строке, тогда идет анализ
        * строк, на предмет того, выделена ли хоть одна строка,
        * или выделение со строки было снято*/
        function fetchRows(table) {
            /*создание контейнера для кнопок в контейнере divMessage*/
            createContainerForButtons(divMessage);

            var tableContext;

            if (options.isUsedDataTables) {
                tableContext = table;
            } else {
                tableContext = $(table);
            }

            /*отслеживание редактирования ячейки;
            * если контейнер с кнопкой `обновить` отстуствует, тогда
            * создаем его*/
            tableContext.on('dblclick', 'tr', function () {

                var selectorUpdate = '.' + selectorButtonDivFlexUpdate;
                var divFlexUpdate = isElem(selectorUpdate);

                var selectorDelete = '.' + selectorButtonDivFlexDelete;
                var divFlexDelete = isElem(selectorDelete);

                /*если блока кнопки `update` нет тогда создаем, если
                * блок `delete` есть, удаляем*/

                if (divFlexDelete) {
                    $(selectorDelete).remove();
                }

                if (!divFlexUpdate) {
                    createContainerForButtonUpdate(selectorButtonFlex, tableContext);
                }
            });

            tableContext.on('click', 'tr', function (event) {

                event.preventDefault();

                /*проверяем, назначен ли указанный селектор, для текущей строки*/
                var isSelector = $(this).hasClass(selectorSelectedRow);

                /*если текущая строка выделена, значит удаляем с нее стиль*/
                if (isSelector) {
                    $(this).attr('style', '');
                }

                if (!isSelector) {/*если не назначен, добавляем селектор*/

                    /*добавили атрибут класс, со значением*/
                    $(this).addClass(selectorSelectedRow);

                    /*так как текущая строка не выделена, тогда назначаем фон*/
                    applyStyle(this, {
                        'background': '#FFFF66'
                    });

                    var selectorUpdate = '.' + selectorButtonDivFlexUpdate;
                    var divFlexUpdate = isElem(selectorUpdate);

                    var selectorDelete = '.' + selectorButtonDivFlexDelete;
                    var divFlexDelete = isElem(selectorDelete);

                    /*проверяем, создана ли кнопка `delete`, если нет, тогда
                    * создаем, если есть тогда показываем */
                    if (divFlexUpdate) {
                        $(selectorUpdate).remove();
                    }

                    if (!divFlexDelete) {
                        /*создание кнопки для удаления данных*/
                        createContainerForButtonDelete(selectorButtonFlex, tableContext);
                    }

                } else {

                    /*если класс был выделен, значит по данной строке был второй щелчок,
                    * тогда удаляем значение указанного класса из текущей точки*/
                    $(this).removeClass(selectorSelectedRow);

                    /*проверяем, есть ли выделенные строки в таблице*/
                    var isSelectedRow = parseSelectedRow(tableContext);

                    /*если выделенных строк нет, тогда удаляем кнопку 'delete'*/
                    if (!isSelectedRow) {
                        $('.' + selectorButtonDivFlexDelete).remove();
                    }
                }

            });
        }

        /*проверяет, есть ли указанный элемент на текущей странице,
        * елси элемнета нет, тогда возвращаем false,
        * если элемент есть, тогда вернем true*/
        function isElem(selector) {
            /*получаем длину элемента, по указанному селектору*/
            var lengthElem = $(selector).length;

            /*проверяем, существует ли указанный селектор*/
            return lengthElem > 0;

        }

        /*проверка выделенных строк, есть ли они*/
        function parseSelectedRow(table) {

            /*проверяю есть ли указанный класс*/
            var isClassSelected;
            isClassSelected = searchRowsSelected(table);

            return isClassSelected;
        }

/*анализирует строки в таблице, и производит поиск строк
        * с классом 'selected';
        * если была найдена хоть одна выделенная строка, тогда в точку вызова вовращается
        * true*/
        function searchRowsSelected(table) {

            /*проверяю есть ли указанный класс*/
            var isClassSelected;

            var tableSelector;

            if (options.isUsedDataTables) {
                /*объект таблицы в DOM-структуре*/
                tableSelector = table.$('tbody > tr');
            } else {

                tableSelector = $(table).find('tbody > tr');
            }

            /*Массив json из значений таблицы*/
            var arrayJson = [];

            arrayJson = processingRowsSelected(tableSelector, arrayJson);

            /*если ничено не выделено очищаю переменную */
            if (arrayJson.length === 0) {

                arrayJson = null;
                isClassSelected = false;

            } else {
                isClassSelected = true;
            }
            console.log(arrayJson);

            return isClassSelected;
        }

        /*обработка данных из выделенных строк;
        * indexOf() - ищет по указанному шаблону подстроку в массиве строк*/
        function processingRowsSelected(tableSelector, arrayJson) {
            /*Внешний цикл, добавляет обработаные строки в массив arrayJson*/
            $.each(tableSelector, function (i, val) {

                /*получаем массив ячеек в текущей строке*/
                var tr = val.childNodes;

                /*получаю все значения атрибута class, для текущего тега 'tr'*/
                var classNameTr = val.getAttribute('class');

                var toLowerCaseClassNameTr = classNameTr.toLowerCase();

                /*проверяю есть ли указанный класс `selected`*/
                var isClass = toLowerCaseClassNameTr.indexOf(selectorSelectedRow) + 1;

                /*ассоциативный массив для текущей строки*/
                var arrFromRowCurrent = {};

                /*если текущая строка имеет указанный класс,
                * тогда строка собирается в массив*/
                if (isClass) {
                    var arr = fillArrAssociativeRowOnlyFirstColumn(tr, arrFromRowCurrent);

                    arrayJson.push(arr);
                    $(tr).removeAttr(selectorSelectedRow);
                }

            });

            return arrayJson;
        }



при первой загрузке строки по щелчку выделяются и отменяется выделение и событие щелчка работает хорошо.

как только нажата кнопка удалить, отправляется ajax-запрос.

и динамически обновляется таблица.

Заново назначаются события на таблицу,
но теперь событие одиночного 'click' срабатывает 2 раза подряд вместо одного , то есть одно ложное срабатывание.

Поэтому второй раз кнопка удалить не появляется, так как второй раз 'click' согланосно коду, означает что пользователь хочет отменить выделение.

проблема решается только тогда, когда кнопка обновить, которая вызывается после редактирования ячеек, запрашивает через ajax-функцию обновление таблицы.

Почему идет ложное срабатывание и как это исправить.

Спасибо.

рони 08.06.2019 21:40

alex-romanov,
Цитата:

Сообщение от alex-romanov
Заново назначаются события на таблицу

а зачем? похоже всё уже назначено, добавьте класс таблице после кликов, а перед назначением проверьте , если класс есть, то не надо ничего назначать.

alex-romanov 10.06.2019 21:54

вы оказались правы.
Я установил функцию, которая устанавливает события кликов мышью на строки, загружаться один раз, во время загрузки страницы.
А так как, когда таблица динамически очищается, тег <table> у меня остается на месте.

и достаточно один раз было установить событие

tableContext.on('dblclick', 'tr', function () {
....

динамическое обновление таблицы не мешает работе слушателей.

то есть повторное назначение событий дает сбой.

проблема исчезла.
Спасибо.


Часовой пояс GMT +3, время: 01:50.