Всем доброго времени суток!
Задание таково:
Сделать подсветку(смену стиля/свойства/преступной прошлой жизни) элементов, находящихся рядом с активным(на который навели курсор). Я знаю, что задавал вопрос про таблицу, но это совсем другое.
Но проблема основная не в том, как сделать, а как оптимизировать(основной вопрос после кода)
(function () {//это вспомогательное всё, основное дальше
"use strict";
window.FLUENT = {
all: (arr, clbc, stopIf) => {
if (arguments.length === 3)
for (let i = 0, len = arr.length; i < len; i++) {
if (clbc(arr[i], i) === stopIf)
return;
}
else
for (let i = 0, len = arr.length; i < len; i++) {
clbc(arr[i], i);
}
},
pos: (elem, pageXOffset = !0, pageYOffset = !0) => {
let rect,
win,
a = elem;
if (!a.getClientRects().length) {
return {
top: 0,
left: 0
};
}
rect = a.getBoundingClientRect();
win = a.ownerDocument.defaultView;
return {
top: rect.top + (pageYOffset ? win.pageYOffset : 0),
left: rect.left + (pageXOffset ? win.pageXOffset : 0)
};
},
uid: () => ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16))
};
})();
/**
будет два новых элемента:
f-cubox
f-cub
**/
(function() {
"use strict";
let cubs = {}; //здесь все "кубы" всех "кубоксов"
class el extends HTMLElement { //создаём класс элемента
connectedCallback() { //при создании элемента
let uid = this.parentNode.getAttribute("uid") || FLUENT.uid(), //uid текущего f-cubox
th = this,
thPos = {},
thIndex,
otherPos = {},
temp,
row,
col,
out = false,
over = false,
setter = s => { //это чтоб не повторять кучу кода по 2 раза
s === 2 && (
row[col - 2] && row[col - 2].setAttribute("pos", "d2"),
row[col - 1] && row[col - 1].setAttribute("pos", "cd"),
row[col] && row[col].setAttribute("pos", "c2"),
row[col + 2] && row[col + 2].setAttribute("pos", "d2"),
row[col + 1] && row[col + 1].setAttribute("pos", "cd"));
s === 1 && (
row[col - 1] && row[col - 1].setAttribute("pos", "d1"),
row[col - 2] && row[col - 2].setAttribute("pos", "cd"),
row[col] && row[col].setAttribute("pos", "c1"),
row[col + 2] && row[col + 2].setAttribute("pos", "cd"),
row[col + 1] && row[col + 1].setAttribute("pos", "d1"));
};
if (cubs[uid] === undefined) { //если текущий cubox не получил uid
th.parentNode.setAttribute("uid", uid); //добавляем его
cubs[uid] = [];
}
cubs[uid].push(th); //после чего добавляем текущий куб(далее=th) в массив
th.addEventListener("mouseover", () => {
if (over) //это чтоб действие не повторялось кучу раз
return;
out = false;
over = true;
th.setAttribute("pos", "c0"); //ставим на th значение pos для центра
thPos = FLUENT.pos(th); //запоминаем позицию th
temp = { //создаём пустой temp
alltop: [] //здесь будут все позиции кубов по top
};
FLUENT.all(cubs[uid], el => {//итерируем массив с кубами текущего кубокса
otherPos = FLUENT.pos(el);//запоминаем позицию el
if (temp.alltop.indexOf(otherPos.top) === -1)//если в массиве alltop нет текущего top кубов
temp.alltop.push(otherPos.top);//то добавляем её
if (temp[otherPos.top] === undefined) //еси в матррице нет текущей высоты
temp[otherPos.top] = [el];//то добавляем свойство с именем высота_el и значением массив с el
else
temp[otherPos.top].push(el);//else просто добавляем el к нужному ряду
});
temp.alltop.sort((a, b) => a - b); //сортируем список топов по возрастанию
thIndex = temp.alltop.indexOf(thPos.top); //получаем индекс позиции th по top в массиве top'ов
if (thIndex - 2 > -1) { //проверка на.. ну понятно же
row = temp[temp.alltop[thIndex - 2]]; //получаем из матрицы ряд с элементами
col = temp[thPos.top].indexOf(th);//получаем индекс колонки с th в ряду row
setter(2);//выполняем второй сценарий в setter
}
if (thIndex - 1 > -1) {
row = temp[temp.alltop[thIndex - 1]];
col = temp[thPos.top].indexOf(th);
setter(1);//выполняем первый сценарий в setter
}
if (thIndex > -1) {
row = temp[temp.alltop[thIndex]];
col = temp[thPos.top].indexOf(th);
row[col - 2] && row[col - 2].setAttribute("pos", "c2");
row[col - 1] && row[col - 1].setAttribute("pos", "c1");
row[col + 2] && row[col + 2].setAttribute("pos", "c2");
row[col + 1] && row[col + 1].setAttribute("pos", "c1");
}
if (thIndex + 1 < temp.alltop.length) {
row = temp[temp.alltop[thIndex + 1]];
col = temp[thPos.top].indexOf(th);
setter(1);
}
if (thIndex + 2 < temp.alltop.length) {
row = temp[temp.alltop[thIndex + 2]];
col = temp[thPos.top].indexOf(th);
setter(2);
}
});
th.addEventListener("mouseout", () => {//тут просто очистка всех pos после выхода мыши с элемента
if (out)
return;
out = true;
over = false;
cubs[uid].forEach(el => {
el.setAttribute("pos", "");
});
});
}
}
customElements.define("f-cub", el);//ну и добавляем теперь элемент
})();
body {
background: rgba(0, 0, 0, .9);
}
f-cubox {
width: 100%;
height: 100%;
position: relative;
}
f-cub {
cursor: default;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
width: 50px;
height: 50px;
float: left;
}
/*fluent animation*/
f-cub {
background: rgba(255, 255, 255, .01);
color: rgba(255, 255, 255, 0.60);
border: 3px solid rgba(0, 0, 0, 0);
tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
transition: all .3s;
}
/*
==========================
d2 || cd || c2 || cd || d2
==========================
cd || d1 || c1 || d1 || cd
==========================
c2 || c1 || c0 || c1 || c2
==========================
cd || d1 || c1 || d1 || cd
==========================
d2 || cd || c2 || cd || d2
==========================
это общий вид матриц с элементами
*/
f-cub[pos=c0],
f-button[sensor]:active {
background: rgba(255, 255, 255, .06);
color: rgba(255, 255, 255, 1);
border-color: rgba(255, 255, 255, .03);
}
f-cub[pos=c1] {
background: rgba(255, 255, 255, .03);
color: rgba(255, 255, 255, .7);
border-color: rgba(255, 255, 255, .01);
}
f-cub[pos=c2] {
background: rgba(255, 255, 255, .02);
color: rgba(255, 255, 255, .6);
}
f-cub[pos=d1] {
background: rgba(255, 255, 255, .025);
color: rgba(255, 255, 255, .65);
border-color: rgba(255, 255, 255, .005);
}
f-cub[pos=d2] {
background: rgba(255, 255, 255, .01);
color: rgba(255, 255, 255, .5);
}
f-cub[pos=cd] {
background: rgba(255, 255, 255, .015);
color: rgba(255, 255, 255, .55);
}
<f-cubox>
<f-cub>a</f-cub>
<f-cub>b</f-cub>
<f-cub>c</f-cub>
<f-cub>d</f-cub>
<f-cub>e</f-cub>
<f-cub>f</f-cub>
<f-cub>g</f-cub>
<f-cub>h</f-cub>
<f-cub>i</f-cub>
<f-cub>j</f-cub>
<f-cub>k</f-cub>
<f-cub>l</f-cub>
<f-cub>m</f-cub>
<f-cub>n</f-cub>
<f-cub>o</f-cub>
<f-cub>p</f-cub>
<f-cub>q</f-cub>
<f-cub>r</f-cub>
<f-cub>s</f-cub>
<f-cub>t</f-cub>
<f-cub>u</f-cub>
<f-cub>v</f-cub>
<f-cub>w</f-cub>
<f-cub>x</f-cub>
<f-cub>y</f-cub>
<f-cub>z</f-cub>
<f-cub>0</f-cub>
<f-cub>1</f-cub>
<f-cub>2</f-cub>
<f-cub>3</f-cub>
<f-cub>4</f-cub>
<f-cub>5</f-cub>
<f-cub>6</f-cub>
<f-cub>7</f-cub>
<f-cub>8</f-cub>
<f-cub>9</f-cub>
</f-cubox>
Собственно вопрос таков: как оптимизировать кусок кода, отвечающий за создание "матрицы". Ведь я понимаю, что каждый раз при наведении на элемент итерировать и тасовать такую кучу есть очень плохо.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть такой код с выпадающим списком и скриптом , который отрисовует графики: