Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 16.10.2016, 11:36
Новичок на форуме
Отправить личное сообщение для Rostik Посмотреть профиль Найти все сообщения от Rostik
 
Регистрация: 16.10.2016
Сообщений: 2

Привязка одного события к многим однотипным элементам
Всем привет! Начал изучать js совсем не давно и естественно возникли некоторые сложности.
Нужно чтобы при первом нажатии на блок он развернулся, а при втором нажатии на него - свернулся.
Проблема в том что все работает только с последним блоком. И когда нажимаю на первый или второй блок, все равно действия происходит над 3-м.
Хотелось бы чтобы действия происходили над блоком с классом "post" и не задавать для этого блока артибут onClick.

вот моя попытка это сделать:
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>LoL</title>
	<style>
        .post{
            width: 500px;
            height: 40px;
            background: #666;
            margin-top: 10px;
        }
	</style>
</head>
<body>
    <div class="post"></div>
    <div class="post"></div>
    <div class="post"></div>
    <script>
        
        var post;
        var i = 0;
        var post = document.querySelectorAll(".post");
        while(document.querySelectorAll(".post")[i]){
            post[i].onclick = Post(post[i]); // здесь проблемка. походу обработчик вешается только на последний элемент
            i++;
        }
        function Post(mythis){
            $this = mythis;
            var startH = mythis.clientHeight;
            var tumbler = false;
            var n = 0;
            var tname;
            return function(){
                h = $this.clientHeight;
                tumbler = !tumbler;
                n++;
                if(tumbler){
                    clearTimeout(tname);
                    tname = setInterval(function(){
                        if(100 <= h) clearTimeout(tname); 
                        $this.style.height = h+"px";
                        h +=1;
                    },10);
                }else{
                    clearTimeout(tname);
                    tname = setInterval(function(){
                        if(startH >= h) clearTimeout(tname); 
                        $this.style.height = h+"px";
                        h -=1;
                    },10);
                }
            }  
        };
        
    </script>
</body>
</html>
Ответить с цитированием
  #2 (permalink)  
Старый 16.10.2016, 13:46
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Rostik,
как вариант...
<style>
        .post{
            width: 500px;
            height: 40px;
            background: #666;
            margin-top: 10px;
            transition: height .5s ease-in;
        }
        .post.active{
            height: 140px;
        }
</style>
<div class="post"></div>
    <div class="post"></div>
    <div class="post"></div>
    <script>
		[].forEach.call(document.querySelectorAll('.post'), function(div){
			div.addEventListener('click', function(){
				this.classList.toggle('active');
			})
		})
    </script>
Ответить с цитированием
  #3 (permalink)  
Старый 16.10.2016, 13:58
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,133

Rostik,
Сообщение от Rostik
здесь проблемка. походу обработчик вешается только на последний элемент
Пример ошибочного использования
Цитата:
Такой глюк возник из-за того, что все функции div[i].onclick получают значение i ... на момент активации onclick ... последнее значение i когда цикл завершился
решение либо замыкание, либо forEach вместо for, либо нужное значение хранить в самом элементе.

Последний раз редактировалось рони, 16.10.2016 в 14:03.
Ответить с цитированием
  #4 (permalink)  
Старый 16.10.2016, 14:05
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,133

Rostik,
пост выше для развития , а у вас просто var не хватает в строках 29 и 35
Ответить с цитированием
  #5 (permalink)  
Старый 16.10.2016, 14:09
Профессор
Отправить личное сообщение для warren buffet Посмотреть профиль Найти все сообщения от warren buffet
 
Регистрация: 08.07.2016
Сообщений: 1,332

Здесь проблемка в лобовом решении. Есть чуть более вбок, но тоже хрестоматийное. Меняем хтмл

<div class="posts"></div>
   <div></div>
   <div></div>
   <div></div>
</div>


Правила применяем к posts так

.posts > div {}

чтобы дивы следующего порядка не затрагивались

и вешаем на этот родительский див 1 листенер и 1 обработчик

document.querySelector('posts').addEventListener('click',togPost);

function togPost(ev){
  
  var el = ev.target;
  if(el===this) return;
  /* могут быть еще проверки, ну и пользуешься el для скрытия-раскрытия */

}


Канонично все.
Ответить с цитированием
  #6 (permalink)  
Старый 16.10.2016, 14:09
Новичок на форуме
Отправить личное сообщение для Rostik Посмотреть профиль Найти все сообщения от Rostik
 
Регистрация: 16.10.2016
Сообщений: 2

Всем большое спасибо! вижу многому нужно еще учится))

я тут похимичил и вот что в итоге получилось...
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>LoL</title>
	<style>
        .post{
            width: 500px;
            height: 40px;
            background: #666;
            margin-top: 10px;
        }
	</style>
</head>
<body>
    <div class="post"></div>
    <div class="post"></div>
    <div class="post"></div>
    <script>
        
        var post;
        var i = 0;
        var post = document.querySelectorAll(".post");
        while(document.querySelectorAll(".post")[i]){
            post[i].myClick = new Post(post[i]);
            post[i].onclick = post[i].myClick.do();
            i++;
        }
        function Post($this){
            this.do = function(){
                var startH = $this.clientHeight;
                var tumbler = false;
                var n = 0;
                var tname;
                return function(){
                    h = $this.clientHeight;
                    tumbler = !tumbler;
                    n++;
                    if(tumbler){
                        clearTimeout(tname);
                        tname = setInterval(function(){
                            if(100 <= h) clearTimeout(tname); 
                            $this.style.height = h+"px";
                            h +=1;
                        },10);
                    }else{
                        clearTimeout(tname);
                        tname = setInterval(function(){
                            if(startH >= h) clearTimeout(tname); 
                            $this.style.height = h+"px";
                            h -=1;
                        },10);
                    }
                }  
        };
        };
        
    </script>
</body>
</html>

Последний раз редактировалось Rostik, 29.10.2016 в 22:29.
Ответить с цитированием
  #7 (permalink)  
Старый 16.10.2016, 14:14
Профессор
Отправить личное сообщение для warren buffet Посмотреть профиль Найти все сообщения от warren buffet
 
Регистрация: 08.07.2016
Сообщений: 1,332

Сообщение от Rostik
многому нужно еще учится
Вот именно. Чем меньше знаешь, тем больше плодишь лишних сущностей. Простейшую переключалку ты превратил в какое-то монструозное угребище.
Ответить с цитированием
  #8 (permalink)  
Старый 16.10.2016, 14:17
Профессор
Отправить личное сообщение для warren buffet Посмотреть профиль Найти все сообщения от warren buffet
 
Регистрация: 08.07.2016
Сообщений: 1,332

Причем они почему-то с нуля начинают с лишней сущности под названием JQuery. Капец блин этим дерьмом народу мозг как законопатили. В свое время я тоже подозревал, что Жикверя - это язык.)
Ответить с цитированием
  #9 (permalink)  
Старый 16.10.2016, 14:20
Профессор
Отправить личное сообщение для warren buffet Посмотреть профиль Найти все сообщения от warren buffet
 
Регистрация: 08.07.2016
Сообщений: 1,332

Причем можно вообще без js обойтись для решения такой задачи, если не брезговать дополнительными чекбоксами. Через CSS правила для чекнутого бокса применяются к непосредственному соседу и все раскрывается и скрывается без скриптов.

Способ не очень, но рабочий.
Ответить с цитированием
  #10 (permalink)  
Старый 16.10.2016, 14:43
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Цитата:
Причем можно вообще без js обойтись для решения такой задачи
как-то так?
<style>
        .post{
            width: 500px;
            height: 40px;
            background: #666;
            margin-top: 10px;
			transition: height .5s ease-in;
        }
		
		input[type=checkbox]{
			display: none;
		}
		
		label > input[type='checkbox']:checked ~ .post{
			height: 100px;
		}
		
	</style>
	<label><input type="checkbox"><div class="post"></div></label>
    <label><input type="checkbox"><div class="post"></div></label>
	<label><input type="checkbox"><div class="post"></div></label>
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
jQuery UI widget и привязка более одного инстанса к элементу LabMapDo jQuery 2 11.09.2014 13:03
Установить класс всем элементам с похожими именами, Id, элементам одного класса sergey_privacy Events/DOM/Window 12 27.01.2014 17:27
Пересоединить события от одного элемента к другому wwwboy jQuery 1 07.02.2012 17:10
События onclick,ondblclick,onmousedown,onmouseup и т.п. с одного хтмл объекта. PashaTurok Events/DOM/Window 0 07.01.2011 21:18
привязка события к disabled IOpeH Events/DOM/Window 4 20.03.2009 01:11