Подсветка смежных элементов

215
28 апреля 2018, 14:46

Всем доброго времени суток!

Задание таково:

Сделать подсветку(смену стиля/свойства/преступной прошлой жизни) элементов, находящихся рядом с активным(на который навели курсор). Я знаю, что задавал вопрос про таблицу, но это совсем другое.

Но проблема основная не в том, как сделать, а как оптимизировать(основной вопрос после кода)

(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>

Собственно вопрос таков: как оптимизировать кусок кода, отвечающий за создание "матрицы". Ведь я понимаю, что каждый раз при наведении на элемент итерировать и тасовать такую кучу есть очень плохо.

READ ALSO
Как создать тег xml через js

Как создать тег xml через js

Вопрос, как создать xml тег в html документе используя javascript?

183
Появления блока с графиком

Появления блока с графиком

Есть такой код с выпадающим списком и скриптом , который отрисовует графики:

173
Проблема в Bootstrap 4?

Проблема в Bootstrap 4?

Существует следующий блок:

180