Изменение размера элемента при клике
Доброго времени суток! 3 дня не ем и не сплю пытаюсь сделать такую вещь:
есть элемент, при клике на него необходимо сделать увеличение его размеров, и уменьшение при очередном клике. НО! необходимо также сделать уменьшение, если человек щелкнул мышью вне этого элемента на экране. Все это должно работать одновременно. Сейчас код выглядит примерно так:
$('.float').click(function() {
$('.float').toggleClass('size');
});
При клике добавляю/убираю класс с увеличенным размером. Как сделать еще клик со свободной областью ума не приложу. Если делать общий клик по документу то он перебивает клик по селектору. Помогите пожалуйста! Заранее благодарен! |
Вероятно не самый лучший вариант..
<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>
|
Спасибо за решение, буду сидеть разбираться... делаю на jquery, поэтому для чистого js нужно немного вникнуть.
|
Единственное, что возможно вызывает непонимание - это setTimeout в onElementClick.
Без него, событие тут же отрабатывает на документе и логика ломается. Вместо setTimeout() можно просто остановить всплытие события: event.stopPropagation(); Причем в обработчике onDocumentClick setTimeout лишний - его можно удалить. |
еще решение
<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>
|
Забыл отметить что addEventListener нету в IE8, а classList - нету даже в IE9, и в старых версиях других браузеров. (но для всего этого есть костыли (polyfills))
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 ниже |
<зануда_mode>
1) Элемент <style> не должен быть внутри <body> (разве что с атрибутом scoped) 2) Твой скрипт отключит переход по ссылкам, так как ты предотвращаешь действие по умолчанию 3) Нет смысла переобъявлять переменную event (она уже объявлена как параметр) </зануда_mode> |
Цитата:
Можешь открыть инспектор и убедиться в этом. Хотя в общем то ничто не мешает поместить его в любое место скриптом в уже сформированном DOM-е. Между прочим, такая запись будет правильной: <style>/* тут стили */</style> <div>тут содержимое body</div> Браузер автоматом сформирует <head> и <body>, причем ошибок парсинга не возникнет, в отличие от твоего варианта. |
Цитата:
|
Цитата:
<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;
if (target.tagName == "DIV" && (target.className == 'float' || target.className == 'float size')) {
element.className = 'float' + (target.className == 'float' ? ' size' : '');
return false;
}
if (element.className == 'float size') {
element.className = 'float';
}
}
})();
</script>
</body>
http://learn.javascript.ru/play/FaPQPb |
$('.float').click(function() {
$('.float').toggleClass('size');
});
$(document).click(function(event){
if($(event.target).hasClass('float') return;
if(!$(event.target).hasClass('size') && $('.float').hasClass('size')){
$('.float').toggleClass('size');
}
});
Вообще пробую так как написал выше. Делаю проверку, если клик на элементе, то возврат. Если клик вне элемента и элемент имеет класс size то тогда убирать класс у него. На одном элементе работает такая схема, а когда элементов несколько то беда... Задача была у меня следующая: есть 4 картинки с описанием каждой, при клике на картинку необходимо увеличивать ее размер и показывать описание, мой способ работает если документ один, когда элементов несколько не хочет, плывет css весь( и вообще похоже это все на говнокод) я слабоват еще) |
Мой вариант, переписанный с использованием jQuery и слегка измененный.
<style>
.float{height: 20px;background: yellow;margin-bottom:10px;}
.size{height:100px}
</style>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
(function(){
var $target = null;
var skipClick = false;
var onDocumentClick = function() {
$target.removeClass('size');
$target = null;
return false;
};
var onElementClick = function() {
if (!skipClick) {
setTimeout(function(){
$(document).one('click', onDocumentClick);
});
skipClick = true;
$target = $(this);
$target.addClass('size');
return false;
}
skipClick = false;
};
$('.float').click(onElementClick);
})();
</script>
|
<!DOCTYPE HTML>
<head>
<style>
.float {
height: 80px;
background: yellow;
width:120px;
margin: 5px;
float: left;
}
.size {
height:160px
}
</style>
</head>
<body>
<div class="float">
<div>Test</div>
</div>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
<script>
(function () {
document.onclick = function (event) {
event = event || window.event;
var target = event.target || event.srcElement,
active = this.querySelector('.size'),
elCls;
while (target != this) {
elCls = target.className;
elCls == 'float' && (target.className += ' size') ||
elCls == 'float size' && (target.className = 'float');
target = target.parentNode;
}
active && (active.className = 'float');
}
}());
</script>
</body>
http://learn.javascript.ru/play/YGn0Sb:dance: А код то становится все короче |
Derekovich, при клике по элементу чередование открытия закрытия - вне элемента все закрываются
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style>
.float{height: 20px;background: yellow;margin-bottom:10px;}
.size{height:100px}
</style>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
</script>
</head>
<body>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
<script>
$('.float').click(function(event) {
event.stopPropagation();
$(this).toggleClass('size');
});
$(document).click(function(){
$('.float').removeClass('size');
});
</script>
</body>
</html>
|
Derekovich,
Вариант клик по другому элементу закрывает предыдущий - всё остальное как выше
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style>
.float{height: 20px;background: yellow;margin-bottom:10px;}
.size{height:100px}
</style>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
</script>
</head>
<body>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
<script>
var floats = $('.float');
floats.click(function (event) {
event.stopPropagation();
floats.not(this).removeClass('size');
$(this).toggleClass('size');
});
$(document).click(function () {
floats.removeClass('size');
});</script>
</body>
</html>
|
Derekovich,
Ещё вариант варианта выше )))
<!DOCTYPE HTML>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style>
.float{height: 20px;background: yellow;margin-bottom:10px;}
.size{height:100px}
</style>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
</script>
</head>
<body>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
<script>
var floats = $('.float');
$(document).click(function (event) {
$('.size').not(event.target).removeClass('size');
$(event.target, floats).toggleClass('size');
});
</script>
</body>
</html>
|
В данном примере меняется только добавление/удаление единственного класса к элементу. А вот например как сделать, если есть 3 элемента с разными классами, и при клике должно также отображаться описание текста к картинке. Привожу пример самого блока:
<div class="section_1"> <div class="size_image"><img src="skin/frontend/default/il/images/img1.png" alt="" /></div> <div class="text_img1"> <p>TEXT only for img1</p> </div> </div> Таких картинок на странице 3 штуки, добавляю только в конце класса порядковый номер другой типа class="section_2", class="text_img2" и т.д. Возможно я неправильно сделал разметку, сейчас получается мне нужно для каждого клика необходимо писать обработчик клика, что не есть хорошо. Заранее благодарен! |
Цитата:
|
А как например тогда определить какое описание текста к картинке выводить?
|
Цитата:
|
<p>TEXT only for img1</p>
Текст находится в блоке у каждого элемента. Понимаю что все это не совсем правильно....но... |
Цитата:
|
Я пишу click() для каждого элемента с указанием его в селекторе, все вышепоказанные примеры в селекторе указывают только один класс. У мня же так не получится, я имею 3 блока, у каждого разный класс, в нем есть картинка и описание, в зависимости от клика я отображаю содержимое и увеличиваю картинку. Если например убрать классы которые заканчиваются на 1,2,3, то как пойму, что именно для этого элемента необходимо вывести именно это описание. Поэтому сделал 3 класса, но приходится тогда делать 3 раза обработчик клика, где в селекторе ставлю каждый класс. Как-то так....
|
Цитата:
|
| Часовой пояс GMT +3, время: 01:57. |