Форум программистов, компьютерный форум, киберфорум
JavaScript
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.96/25: Рейтинг темы: голосов - 25, средняя оценка - 4.96
0 / 0 / 1
Регистрация: 12.12.2012
Сообщений: 24

Вызов функции при клике на ячейку таблицы

29.06.2015, 17:16. Показов 5255. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть таблица. Требуется каждой ячейке (td) установить вызов одной функции, но с разными параметрами (номер строки и столбца ячейки). Есть следующий код:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
InputManager.prototype.bindAllCells = function() {
    var cells = document.querySelectorAll(".game-grid td");
    
    for (var i = 0; i < cells.length; i++) {
        var x = cells[i].cellIndex;
        var y = cells[i].parentNode.rowIndex;
        
        this.bind(
            cells[i], 
            function(event) {
                this.step(event, { x: x, y: y });
            }
        );
    }
    
};
 
InputManager.prototype.bind = function(element, callback) {
    if (element) {
        element.addEventListener("click", callback.bind(this));
        element.addEventListener(this.eventTouchend, callback.bind(this));
    }
};
 
InputManager.prototype.step = function(event, position) {
    event.preventDefault();
    this.emit("step", { x: position.x, y: position.y });
};
 
InputManager.prototype.emit = function(event, data) {
    var callbacks = this.events[event];
    
    if (callbacks) {
        callbacks.forEach(function(callback) {
            callback(data);
        });
    }
};
При клике на любой ячейке происходит вызов функции с одинаковыми параметрами - которые были на последней итерации цикла добавления события. В чем может быть проблема?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.06.2015, 17:16
Ответы с готовыми решениями:

Удаление строк и столбцов таблицы при клике на ячейку
Дана таблица N*N. Нужно При клике на ячейку удалить (не перекрасить) i- строку и j- столбец

Как сделать обработку событий при клике на ячейку таблицы
Есть таблица, в ячейках некий текст. Как сделать ячейки таблицы кликабельными? И как проверять содержимое ячеек. Например при клике по...

При клике на одну ячейку таблицы одновременно кликались две ячейки
Здравствуйте! Не так давно изучаю HTML, поэтому мало что в нём понимаю. Мне нужно, чтобы при клике на одну ячейку таблицы, происходил клик...

7
Ренегат
Эксперт HTML/CSS
 Аватар для BANO
1740 / 1085 / 386
Регистрация: 06.08.2014
Сообщений: 5,203
Записей в блоге: 1
03.07.2015, 02:23
Zlobengod, у меня похожая проблема тут
только у меня был последний инициированный класс
так и не могу разобраться в чём проблема,
и у тебя скрипт вроде правильный, но как я понимаю работает не корректно

у меня подозрения что это какая-то из "хитростей" prototype
хотя может я и криворукий

Добавлено через 7 минут
а что такое у вас eventTouchend?

Добавлено через 42 секунды
точнее говоря, приведите его код пожалуйста
0
 Аватар для Sn1p3rOk
288 / 175 / 86
Регистрация: 19.04.2014
Сообщений: 1,095
03.07.2015, 02:28
Цикл прошел, значение получилось то которое вышло из него и так каждый раз. Или может я не так понял ваш код? Сбрось весь проект, я посмотрю.
0
супермизантроп
Эксперт JS
3941 / 2979 / 692
Регистрация: 18.04.2012
Сообщений: 8,629
03.07.2015, 04:06
прописывать функцию каждой ячейке - не рационально
достаточно прописать функцию таблице, которая:
1) определит объект клика через event.srcElement || event.target
2) по цепочке родителей дойдёт до тега <td> и узнает его cellIndex
3) продолжив "поход" по цепочке, дойдёт до тега <tr> и узнает его rowIndex
0
Модератор
 Аватар для Thisman
771 / 352 / 142
Регистрация: 17.07.2013
Сообщений: 992
03.07.2015, 04:06
Zlobengod, если вы работает с обработчиками, то используйте всегда замыкание, если вешаете их на несколько элементов с индивидуальными параметрами. А еще лучше, записать данные в атрибут элемента и передавать сам элемент в ф-цию


Может проблема и не в этом, но попробуйте так
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (var i = 0; i < cells.length; i++) {
    var x = cells[i].cellIndex;
    var y = cells[i].parentNode.rowIndex;
    var self = this; // ссылка нужна для замыкания
 
    // замыкание наше все
    var handler = (function (coords) {
        return function(event) {
            self.step(event, coords);
       }
    })({x : x, y : y});
        
    this.bind(cells[i], handler);
}
0
 Аватар для Jetlag
111 / 49 / 20
Регистрация: 21.10.2013
Сообщений: 212
04.07.2015, 14:52
Zlobengod, добро пожаловать в удивительный мир замыканий и областей видимости.

Ошибка здесь:
JavaScript
1
2
3
4
5
6
     this.bind(
            cells[i], 
            function(event) {
                this.step(event, { x: x, y: y });
            }
        );
Это очень неинтуитивно конечно, но в обработчик который Вы тут привязываете, отдается всегда одинаковое значение x, y, поэтому такие штуки обычно в iife оборачиваются. К вечеру меня отпустит влом и я распишу понятнее.

А вообще Вы правой ногой левоое ухо чешете, почитайте про делегирование и сделайте как kalabuni говорит.
0
 Аватар для Jetlag
111 / 49 / 20
Регистрация: 21.10.2013
Сообщений: 212
05.07.2015, 21:56
Zlobengod, BANO
Я наконец-то добрался до объяснения.

Итак, первое что надо понимать, это что в js области видимости определяются не блоками, как в java, C# или C++.
Они определяются блоками.
Пример:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(function outerFunc(){
    var i = 'Меня видно везде внутри outerFunc';
    {
       var j = 'Меня тоже везде!'; 
       // Фигурные скопки не создают отдельной области видимости!
    }
    
    function innerFunc(){
        var k = 'А меня видно только внутри innerFunc';
        console.log(i);
        console.log(k);
    };
    
    innerFunc();
    console.log(j);
    // Раскомментим - ругнется. Потому что переменно k тут нету.
    //console.log(k);
       
})()
Второе, что надо понимать, это то, что "внутренняя" функция может использовать переменные из "внешней", поэтому пока внутренняя функция существует, переменные из внешней тоже должны сохраняться в памяти.
Можно проиллюстрировать это создав функцию, которая считает число своих вызовов например
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
function mySuperFunc(){
   var i = 1;
  return function h(){
      // Вот пока эта функция h существует, существует связанная с ней переменная i в памяти.
      console.log(i); 
      i++;
  }
}
 
var selfCounter = mySuperFunc();
selfCounter();
selfCounter();
И третье, что ОЧЕНЬ ВАЖНО понимать, по-моему самое неинтуитивное здесь, это то, что значение "внешних" переменных которые используются функцией берется на момент вызова функции, не на момент ее определения.

JavaScript
1
2
3
4
5
6
var i = 0;
var mySuperFunc = function(){
    console.log(i)
};
i++;
mySuperFunc(); // Вернет 1.
Ближе к текущему коду.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
InputManager.prototype.bindAllCells = function() {
    var cells = document.querySelectorAll(".game-grid td");
    
    for (var i = 0; i < cells.length; i++) {
        var x = cells[i].cellIndex;
        var y = cells[i].parentNode.rowIndex;
        
        this.bind(
            cells[i], 
            // Абракадабра, сейчас мы создаем замыкание!
            function(event) {
            // Там дальше мы прикрепляем эту функцию как обработчик.
            // Вот на момент когда мы этот обработчик будем выполнять, только тогда он посмотрит какие значения
            // переменных x и y у нас есть.
            // А цикл у нас к тому времени прокрутился до конца, поэтому в любом нашем обработчике получим
            // последнее посчитанное значение x и y
                this.step(event, { x: x, y: y });
            }
        );
    } 
};

Замыкания - это одна из самых могущественных и неинтуитивных частей js, граница между js-программистами и "простыми смертными" пролегает как раз где-то в районе понимания замыканий.

Что с этим делать? Самый простой и распространенный способ описал Thisman, надо создать отдельный лексический скоуп, отдельную область видимости, которая будет нужное вам значение переменной в себе сохранять. Обернуть в еще одну функцию другими словами.

TLDR: Заботай замыкания.

А вообще конкретно в этой задаче надо использовать делегирование событий.

BANO, релевантно твоему суперплееру?
0
супермизантроп
Эксперт JS
3941 / 2979 / 692
Регистрация: 18.04.2012
Сообщений: 8,629
06.07.2015, 01:49
посмотрите
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.07.2015, 01:49
Помогаю со студенческими работами здесь

При клике по ячейке вставить текст в другую ячейку этой же таблицы
Здравствуйте! У меня есть таблица: &lt;table&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td id=&quot;s1&quot;...

Как при клике на checkbox ввести галочку в текущую ячейку таблицы
Ребята подскажите пожалуста очень важно как при клике на checkbox ввести галочку в текущую ячейку таблицы откликнитесь кто нибудь

Вывод новой Form, при двойном клике на ячейку таблицы выбранного столбца
Есть DBGridEh1. В ней есть колонка &quot;ФИО&quot; и другие в Form1. Надо, чтобы при нажатии на строчку в выбранной колонке &quot;ФИО&quot;,...

Вызов функции при клике
&lt;script type='text/javascript' &gt; function MyFunc(S){ alert(S); //показываю принятый текст. } &lt;/script&gt; ...

Вызов функции при клике на кнопку
Здравствуйте. Проблема собственно вот в чем. Вешаю вызов функции на кнопку &lt;input type=&quot;submit&quot; name=&quot;enter&quot;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru