Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Изменение размера элемента при клике (https://javascript.ru/forum/dom-window/43401-izmenenie-razmera-ehlementa-pri-klike.html)

Derekovich 04.12.2013 02:11

Изменение размера элемента при клике
 
Доброго времени суток! 3 дня не ем и не сплю пытаюсь сделать такую вещь:
есть элемент, при клике на него необходимо сделать увеличение его размеров, и уменьшение при очередном клике. НО! необходимо также сделать уменьшение, если человек щелкнул мышью вне этого элемента на экране. Все это должно работать одновременно. Сейчас код выглядит примерно так:
$('.float').click(function() {
 $('.float').toggleClass('size');
  });

При клике добавляю/убираю класс с увеличенным размером. Как сделать еще клик со свободной областью ума не приложу. Если делать общий клик по документу то он перебивает клик по селектору.
Помогите пожалуйста! Заранее благодарен!

danik.js 04.12.2013 03:00

Вероятно не самый лучший вариант..
<style>
.float{height: 20px;background: yellow}
.size{height:100px}
</style>
<div class="float"></div>
<script>
(function(){
var onDocumentClick = function() {
    setTimeout(function(){
        element.addEventListener('click', onElementClick);
    });
    document.removeEventListener('click', onDocumentClick);
    element.classList.remove('size');
};
var onElementClick = function() {
    setTimeout(function(){
        document.addEventListener('click', onDocumentClick);
    });
    element.removeEventListener('click', onElementClick);
    element.classList.add('size');
};

var element = document.querySelector('.float');
element.addEventListener('click', onElementClick);
})();
</script>

Derekovich 04.12.2013 03:09

Спасибо за решение, буду сидеть разбираться... делаю на jquery, поэтому для чистого js нужно немного вникнуть.

danik.js 04.12.2013 03:35

Единственное, что возможно вызывает непонимание - это setTimeout в onElementClick.
Без него, событие тут же отрабатывает на документе и логика ломается.
Вместо setTimeout() можно просто остановить всплытие события: event.stopPropagation();
Причем в обработчике onDocumentClick setTimeout лишний - его можно удалить.

Vlasenko Fedor 04.12.2013 04:00

еще решение
<body>
    <style>
      .float {
        height: 20px;
        background: yellow
      }
      .size {
        height:100px
      }
    </style>
    <div class="float"></div>
    <script>
      (function () {
        var element = document.querySelector('.float');
        document.onclick = function (e) {
          var target = e && e.target || e.srcElement;
          element.classList[target.className == 'float' ? 'add' : 'remove']('size');
          return false;
        }
      })();
    </script>
  </body>

danik.js 04.12.2013 04:54

Забыл отметить что addEventListener нету в IE8, а classList - нету даже в IE9, и в старых версиях других браузеров. (но для всего этого есть костыли (polyfills))

Poznakomlus, твой вариант на мой взгляд, ибо нерационально - ловить все клики, когда есть возможность ловить не все.

рони 04.12.2013 07:11

Derekovich,
http://javascript.ru/forum/jquery/39...tml#post256052

Vlasenko Fedor 04.12.2013 13:04

Цитата:

Сообщение от danik.js (Сообщение 284393)
Poznakomlus твой вариант на мой взгляд

эт смотря при каких условиях и задачах, можно еще тонн кода написать и фреймворки по подключать :)
<head>
    <style>
      .float {
        height: 20px;
        background: yellow
      }
      .size {
        height:100px
      }
    </style>
  </head>
<body>
<a href="http://mail.ru">Mail.ru</a>
<div class="float"></div>
<script>
  (function () {
	var element = document.querySelector('.float');
	document.onclick = function (event) {
	  event = event || window.event;
	  var target = event.target || event.srcElement;
	  element.className = 'float' + (target.className == 'float' ? ' size' : '');
	  return target.tagName == 'A';
	}
  })();
</script>
</body>

http://learn.javascript.ru/play/7BWXn
Поправил исходя из советов danik.js ниже

danik.js 04.12.2013 13:34

<зануда_mode>
1) Элемент <style> не должен быть внутри <body> (разве что с атрибутом scoped)
2) Твой скрипт отключит переход по ссылкам, так как ты предотвращаешь действие по умолчанию
3) Нет смысла переобъявлять переменную event (она уже объявлена как параметр)
</зануда_mode>

danik.js 04.12.2013 15:19

Цитата:

Сообщение от Poznakomlus
это не так

Ты наверно не понял. Ты конечно же можешь. Но браузер будет вынужден в процессе парсинга исправить твой косяк и в конечном итоге твой <style> все-равно попадет в <head>. Это описано в стандарте.
Можешь открыть инспектор и убедиться в этом. Хотя в общем то ничто не мешает поместить его в любое место скриптом в уже сформированном DOM-е.

Между прочим, такая запись будет правильной:
<style>/* тут стили */</style>
<div>тут содержимое body</div>


Браузер автоматом сформирует <head> и <body>, причем ошибок парсинга не возникнет, в отличие от твоего варианта.


Часовой пояс GMT +3, время: 13:59.