Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 13.02.2016, 13:38
Аватар для Lemme
Профессор
Отправить личное сообщение для Lemme Посмотреть профиль Найти все сообщения от Lemme
 
Регистрация: 15.07.2015
Сообщений: 511

Получить дочерний элемент по координатам клика.
Суть такая, есть блок (контейнер), внутри него есть n блоков, так вот, по клику на контейнер в любом месте, нужно получить подходящий элемент.

структура примерно такая:
---------------------------
 | 0 | | 1 | | 2 | | 3 |
---------------------------


Решил я это такм способом.

[].filter.call(this.children, function(item) {
     return item.getBoundingClientRect().left <= event.clientX;
}).pop();


Собственно, код работает, но, что-то мне подсказывает, что хоть способ и рабочий, фильтровать массив и вытаскивать с него последний элемент не лучший способ..

Есть у кого-то идеи?

Вот полный код.

<style>
	div {
	  display: flex;
	  justify-content: space-between;
	  padding: 30px;
	  background-color: #fff;
	  border: 1px solid #999;
	  cursor: pointer;
	}

	span {
	  width: 100px;
	  height: 100px;
	  background-color: tomato;
	  color: #fff;
	  text-align: center;
	  font-size: 80px;
	  -moz-user-select: none; /* fucking double click :D */
	}
</style>

<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<script>
	'use strict';

	const div = document.querySelector('div');

	div.addEventListener('click', handleClick);

	function getPos(item) {
		return item.getBoundingClientRect().left;
	}

	function handleClick(e) {
		const items = Array.from(this.children);
	  
	  const filtredItems = items.filter(item => 
	  	item.getBoundingClientRect().left <= e.clientX
	  );
	  
	  const item = filtredItems.pop() || items[0];
	  
	  // clear items
	  items.forEach(item => {
	  	item.innerHTML = '';
	  });
	  
	  // active item
	  item.innerHTML = '+';
	}
</script>
Ответить с цитированием
  #2 (permalink)  
Старый 13.02.2016, 14:27
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,124

Lemme,
решение Соединить прямой линией два элемента на javascript или Jquery ... чуть добавить фильтр
Ответить с цитированием
  #3 (permalink)  
Старый 13.02.2016, 14:38
Аватар для Lemme
Профессор
Отправить личное сообщение для Lemme Посмотреть профиль Найти все сообщения от Lemme
 
Регистрация: 15.07.2015
Сообщений: 511

рони, спасибо, интересно=)
Ответить с цитированием
  #4 (permalink)  
Старый 13.02.2016, 15:17
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Через offsetLeft никак? А потом через array.some найти нужный. Будет работать быстрее, т.к. не придется по всем элементам массива бегать.
var x = e.clientX;
                 var span = document.querySelectorAll('span');
                 var temp = span[0];
                 [].some.call(span, function (elem) {
                     if (elem.offsetLeft > x) {
                         return true;
                     }
                     temp = elem;
                 })

Последний раз редактировалось destus, 13.02.2016 в 15:22.
Ответить с цитированием
  #5 (permalink)  
Старый 13.02.2016, 15:32
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,124

Ближайший элемент от места клика
Lemme,
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style>
	div {
	  display: flex;
	  justify-content: space-between;
	  padding: 30px;
	  background-color: #fff;
	  border: 1px solid #999;
	  cursor: pointer;
	}

	span {
	  width: 100px;
	  height: 100px;
	  background-color: tomato;
	  color: #fff;
	  text-align: center;
	  font-size: 80px;
	  -moz-user-select: none; /* fucking double click :D */
	}
</style>
</head>

<body>


<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<script>
window.addEventListener("DOMContentLoaded", function() {
    var b = document.querySelector("div"),
        d = b.querySelectorAll("span"),
        c;
    b.addEventListener("click", function(b) {
        c = [].map.call(d, function(a) {
            var e = a.getBoundingClientRect(),
                c = e.left + a.offsetWidth / 2 - b.clientX;
            a = e.top + a.offsetHeight / 2 - b.clientY;
            return Math.sqrt(c * c + a * a)
        });
        var f = Math.min.apply(null, c);
        [].forEach.call(d, function(a, b) {
            a.innerHTML = c[b] > f ? "" : "+"
        })
    })
});
</script>

</body>

</html>
Ответить с цитированием
  #6 (permalink)  
Старый 13.02.2016, 15:42
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

<style>
        div {
	  display: flex;
	  justify-content: space-between;
	  padding: 30px;
	  background-color: #fff;
	  border: 1px solid #999;
	  cursor: pointer;
	}

	span {
	  width: 100px;
	  height: 100px;
	  background-color: tomato;
	  color: #fff;
	  text-align: center;
	  font-size: 80px;
	  -moz-user-select: none; /* fucking double click :D */
	}
    </style>

    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
<script>
var div = document.querySelector('div');
             div.addEventListener('click', function (e) {
                 var x = e.clientX;
                 var span = document.querySelectorAll('span');
                 var temp = span[0];
                 [].some.call(span, function (elem, i) {
                     if (elem.offsetLeft > x) {
                         return true;
                     }
                     temp = elem;
                 });
                 [].forEach.call(span,function(elem){
                     (elem == temp) ? elem.innerHTML = '+' : elem.innerHTML = '';
                 })
             })
</script>
Ответить с цитированием
  #7 (permalink)  
Старый 13.02.2016, 15:44
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,124

Lemme,
вопрос только - можно кликнуть так что минимальное растояние будет одинаковое для нескольких элементов, тогда как?
Ответить с цитированием
  #8 (permalink)  
Старый 13.02.2016, 15:46
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,124

destus,
не работает если брать минимальное растояние -- ваш вариант для ближайшего слева
Ответить с цитированием
  #9 (permalink)  
Старый 13.02.2016, 15:47
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Сообщение от рони Посмотреть сообщение
destus,
ваш вариант для ближайшего слева
а надо как? Определять по координатам к какому блоку ближе отношусь и его помечать "+" ?
Ответить с цитированием
  #10 (permalink)  
Старый 13.02.2016, 16:46
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,124

Сообщение от destus
Определять по координатам к какому блоку ближе отношусь и его помечать "+" ?
я понял так, подождём Lemme,
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Получить элемент с указанным содержимым cevut Events/DOM/Window 4 08.07.2014 12:59
Как вытащить дочерний элемент? alexandr_v-vich Элементы интерфейса 7 29.02.2012 14:35
Как получить второй дочерний элемент, или второй смежный libinstyle Events/DOM/Window 4 30.06.2010 20:41
Как получить указатель на элемент вызвавший функцию pelayo Общие вопросы Javascript 9 29.06.2010 23:32
задействовать только дочерний элемент roma86 jQuery 2 03.10.2009 21:36