Ответ 1
РЕШЕНИЕ, концептуальное расширение моего ответа к аналогичному вопросу
CODE
function matrix(data, holder, config) {
'use strict';
//copy the config, substituting defaults
config = {
cellWidth : (config && config.cellWidth) || 150,
rowHeight : (config && config.rowHeight) || 22,
};
if (!data) {
//create 50000x26 array for data
data = (function (length, depth) {
var output = new Array(length);
var startAt;
for (var index = 0; index < length; ++index) {
//var startAt = Math.random().toString(36).substring(5);
var startAt = index + ':';
output[index] = new Array(depth);
for (var index2 = 0; index2 < depth; ++index2)
output[index][index2] = startAt + index2;
}
return output;
})(50000, 26);
}
//guard against 0 length arrays
if (data.length < 1 || data[0].length < 1)
return;
var areaForcer = holder.appendChild(holder.ownerDocument.createElement('div'));
var view = null;
function refreshWindow() {
//remove old view
if (view != null)
view.innerHTML = "";
//create new view
else
view = holder.appendChild(holder.ownerDocument.createElement('div'));
var firstRow = Math.floor(holder.scrollTop / config.rowHeight);
var lastRow = firstRow + Math.ceil(holder.offsetHeight / config.rowHeight) + 1;
if (lastRow + 2 > data.length)
lastRow = data.length - 1;
var firstColumn = Math.floor(holder.scrollLeft / config.cellWidth);
var lastColumn = firstColumn + Math.ceil(holder.offsetWidth / config.cellWidth) + 1;
if (lastColumn + 2 > data[0].length)
lastColumn = data[0].length - 1;
//position view in users face
view.id = 'view';
view.style.top = (firstRow * config.rowHeight) + 'px';
view.style.left = (firstColumn * config.cellWidth) + 'px';
var row;
var cell;
//add the rows
for (var index = firstRow; index <= lastRow; ++index) {
row = view.ownerDocument.createElement('div');
row.style.height = config.rowHeight - 2 + 'px';
view.appendChild(row);
//add the cells
for (var index2 = firstColumn; index2 <= lastColumn; ++index2) {
cell = row.ownerDocument.createElement('div');
cell.className = 'listItem';
cell.innerHTML = data[index][index2];
cell.style.width = config.cellWidth - 2 + 'px';
row.appendChild(cell);
}
}
console.log('viewing items [' + firstRow + ':' + lastRow + '][' + firstColumn + ':' + lastColumn + ']');
}
areaForcer.style.height = (data.length * config.rowHeight) + 'px';
areaForcer.style.width = (data[0].length * config.cellWidth) + 'px';
refreshWindow();
function delayingHandler() {
//wait for the scroll to finish
setTimeout(refreshWindow, 10);
}
if (holder.addEventListener)
holder.addEventListener('scroll', delayingHandler, false);
else
holder.attachEvent('onscroll', delayingHandler);
}
matrix(null, document.getElementById('listHolder'), false);
html, body {
width:100%;
height:100%;
padding:0;
margin:0
}
body{
overflow:hidden;
}
.listItem {
border : 1px solid gray;
margin : 1px 0px;
display : inline-block;
}
#listHolder {
position:relative;
height:100%;
width:100%;
background-color:#CCC;
box-sizing:border-box;
overflow:auto;
}
#view {
position:absolute;
}
#view, #view * {
overflow : hidden;
white-space : nowrap;
}
#view > div {
width : 100%;
}
<div id="listHolder"></div>
Просто некоторые вещи, чтобы очистить ваш код:
-
вы не используете объект в модуле OO, нет необходимости в новой/используйте функцию в качестве конструктора (и если хотите, запустите ее с помощью капитала)
-
в этот день и возраст компилятор может многое для нас сделать, нет оснований для использования имен типа "i" или "j", где "индекс" гораздо более понятен себе, а оператор if был сделан для того, что вы использовали для оператора и для (
!data && /*set data*/
, используйтеif (!data) /*set data*/
) -
не использовать анонимные функции call-once, где они не требуются, их необходимо перекомпилировать каждый раз, когда запускается родительская функция
-
объявлять переменные за пределами циклов
-
не используйте random() (в этом случае), если код не работает, затрудняет просмотр происходящего
-
личное предпочтение посылает null функции вместо undefined и не называет функцию $matrix, когда матрица точно так же apt используйте комментарии!
-
личное предпочтение, если вы не знаете, что делаете, ++ x - это именно то, что вам нужно, а x ++ - небольшая трата ресурсов
-
потому что вы используете горизонтальную прокрутку, забудьте о скрытии полосы прокрутки
-
начать просто и не пытаться получить высоту, просто заставьте ее. такие вещи, как обнаружение высоты, являются тонкостями, зарезервированными для рабочих решений.
-
всегда использовать правильный отступ, даже если оператор if может быть записан на одной строке. Неважно, о ваших личных предпочтениях, потому что вы отправляете код в Интернете, ожидая, что другие люди помогут вам.
-
когда вы редактируете код, убедитесь, что вы обновили семантику. Например. элемент, называемый "heightForcer", теперь также манипулирует шириной, избегая этого, называя его "areaForcer"