Я динамически генерирую таблицу HTML с использованием JavaScript. Один из столбцов таблицы содержит событие onmouseover
, и когда курсор мыши находится над определенной ячейкой, я хочу отображать информацию, относящуюся к ячейке.
В моем случае я хочу показать значение nPos
через вызов alert()
как это было во время построения таблицы.
Упрощенный пример создания моей таблицы:
for (var iLoop = 0 ; iLoop < nHitsPerPage ; iLoop++) {
var nPos = (nCurrentPageParam * SearchResults.nMaximumHitsPage) + iLoop;
//...
var cellInfo = tableResultsRow.insertCell(6);
//...
cellInfo.className = "noWrapCell";
cellInfo.innerHTML = "?";
cellInfo.style.cursor = "pointer";
// The line below is important - I need to store nPos value during the table consturction
cellInfo.onmouseover = function(){alert("nPos = " + nPos)};
cellInfo.onmousemove = function(){FileResort.LightboxShortInfo.update(event)};
cellInfo.onmouseout = function(){FileResort.LightboxShortInfo.hide(event)};
}
Как вы можете видеть из приведенного выше примера, я итеративно создал таблицу внутри цикла for()
. Я хочу сохранить значение nPos
в каждой строке (записи), которая отличается для каждой строки (записи).
Моя проблема заключается в том, что, как только я навешиваю эту конкретную ячейку, я получаю одно и то же значение nPos
для каждой строки (записи), а nPos
- текущее значение nPos
в конкретном состоянии приложения.
Я не могу найти способ записи значения nPos
как это было во время выполнения for()
, что важно для меня при определении того, какая запись хранится в конкретной строке.
Есть ли способ захватить или сохранить значение nPos
для каждой строки (записи) во время начальной конструкции таблицы?
Вы еще одна жертва закрывающего монстра :)
Посмотри на это:
cellInfo.onmouseover = function(){alert("nPos = " + nPos)};
функция здесь - пусть назовет ее lambda
- придется найти значение переменной nPos
. Поскольку nPos
не объявляется внутри lambda
, он будет искать его в функции верхнего уровня, то есть в функции, где создается nPos
.
Когда произойдет событие mouseover
, код, который объявляет и устанавливает nPos
, уже будет запущен, поэтому nPos
будет иметь значение nHitsPerPage
.
Именно это отобразит lambda
. К сожалению, это не то, что вы хотите :).
Чтобы преодолеть это, вам нужно создать (лексическое) закрытие, то есть предоставить lambda
значение nPos
которое соответствует вашим потребностям.
Способ сделать это в Javascript выглядит следующим образом:
cellInfo.onmouseover = function(p){
return function () { alert("nPos = " + p)};
} (nPos);
позвоните nu
новой функции (той, которая принимает p
как параметр). Мы изменили lambda
так что теперь она относится к p
вместо nPos
.
Это означает, что когда событие mouseover
будет срабатывать, lambda
будет искать p
в своей верхней функции, которая теперь равна nu
. И он действительно найдет p
там, как параметр nu
.
p
- параметр функции, поэтому он получает копию nPos
в момент ее nPos
. Это означает, что lambda
будет ссылаться на другой экземпляр контекста вызова nu
для каждого экземпляра cellInfo
.
Каждый экземпляр обработчика события mouseover теперь будет содержать копию p
которая установлена на нужное значение nPos
.
Быстрый код Psuedo:
var nPosArray = [];
var itemsArray = [];
for (var iLoop = 0 ; iLoop < nHitsPerPage ; iLoop++)
{
var nPos = (nCurrentPageParam * SearchResults.nMaximumHitsPage) + iLoop;
//...
var cellInfo = tableResultsRow.insertCell(6);
//...
cellInfo.className = "noWrapCell";
cellInfo.innerHTML = "?";
cellInfo.style.cursor = "pointer";
// The line below is important - I need to store nPos value during the table consturction
nPosArray.push(nPos);
cellInfo.addEventListener('mouseout', cellMouseOut(event));
cellInfo.onmousemove = function(){FileResort.LightboxShortInfo.update(event)};
cellInfo.onmouseout = function(){FileResort.LightboxShortInfo.hide(event)};
itemsArray.push(cellInfo);
}
function cellMouseOut(e)
{
for(iLoop = 0 ; iLoop < cellInfo.length; iLoop++)
{
if(e.target.id == cellInfo[iLoop].id)
{
alert('NPos: ' + nPosArray[iLoop]);
}
}
}
cellInfo.onmouseover = alert("my output");
Во-вторых, мне не нужноreturn function ()
в вашем примере. В любом случае, большое спасибо за отличное объяснение в вашем ответе выше.nu
в вашем случае).