Subscribed unsubscribe Subscribe Subscribe

Kazuma Labolatory's

Nothing is Impossible. ✿

Menu

【js】pure JavaScipt で jQuery のToggleアニメーションを実現してみた

基礎編

 

  • list1-1
  • list1-2
  • list1-3

HTML

<button id="btn1">button1</button>
<ul id="list1">
   <li>list1-1</li>
   <li>list1-2</li>
   <li>list1-3</li>
</ul>

CSS

#list1 {
   transition: all .45s ease;
   }
#btn1 {
   transition: all .2s;
   }

 

JavaScript

"use strict";

var _ = console.log;

var btn1 = document.querySelector('.entry-content #btn1');
var list1 = document.querySelector('.entry-content #list1');
var list1_H;

list1.style.overflowY = 'hidden';
list1_H = list1.getBoundingClientRect().height;
btn1.list1_Height = list1_H;
list1.style.height = 0 + 'px';

btn1.addEventListener('click', function(e) {
    e.preventDefault();
        // _(this.textContent);
    var eBtn = this; // === 'ev.target'
    var eList = eBtn.nextElementSibling;
    var eListH_now = eList.getBoundingClientRect().height;
       //  _(eListH_now);
    if (eListH_now !== 0) {
        eList.style.height = '0';
    } else {
        eList.style.height = this.list1_Height + 'px';
    }
});

 

 

JS Bin on jsbin.com

 

 

関連項目

●Object(物体) のプロパティ
-- Adding New Property / JavaScript Object (w3schools.com)

https://www.w3schools.com/js/js_properties.asp
this キーワード

- this の使用場面 : 主にConstructer function内, Object のメソッド*1

- this が表すもの : excution context の Object

 

 

 

応用編

 

  • list2

  • list3-1
  • list3-2

  • list4-1
  • list4-2
  • list3-3

HTML

<button class="btn">button2</button>
<ul class="list">
   <li>list2</li>
</ul>
<button class="btn">button3</button>
<ul class="list">
   <li>list3-1</li>
   <li>list3-2</li>
</ul>
<button class="btn">button4</button>
<ul class="list">
   <li>list4-1</li>
   <li>list4-2</li>
   <li>list4-3</li>
</ul>

CSS

.list {
   transition: all .45s ease;
   }
.btn {
   transition: all .2s;
   }
.btn.clicked {
    box-shadow: inset 0 0 6px 1px rgba(255,255,255,0.7);
    }

 

JavaScript

"use strict";

var _ = console.log;

var btns = document.querySelectorAll('.entry-content .btn');
var lists = document.querySelectorAll('.entry-content .list');
var i = 0;

var toggleList = function (ev) {
    /************************************
    this === ev.target
    ************************************/
    ev.preventDefault();
    
    var evBtn = this;
    var evList = evBtn.nextElementSibling;
    var evListH_now = evList.getBoundingClientRect().height;
       // _(now_listH);
    if (evListH_now === 0) {
        evList.style.height = this.siblingListH + 'px';
        evBtn.classList.add('clicked');
    } else {
        evList.style.height = 0;
        evBtn.classList.remove('clicked');
    }
};

for (i = 0; i < lists.length; i++) {
    var btn = btns[i];
    var list = lists[i];
    var listH;
    
    list.style.overflowY = 'hidden'; 
    listH = list.getBoundingClientRect().height;
    btn.siblingListH = listH;  // --- (i)
    list.style.height = 0; // -- (ii)
    btn.addEventListener('click', toggleList);  // -- (iii)
}

 

 

JS Bin on jsbin.com

 

 

-- (i) 各btn(button) object の プロパティに、そのすぐ下に位置するulリストの「通常時の高さ(listH)」 を割り当てておく。list open の時に使うため。
【理由】
addEventListener(Type, callback)callback function の argument引数(実述)、は 'Event' object 一つのみ。したがって、listHを argument としてcallback function に渡す事ができない。--- 下の (iii) 参照)
❷また、別の方法

for ( ) {
    ...
    var listH = ...
    ...
    ...
    addEventListener('click', function(event) {
        listH = ...
    });
}

の 形でcallback function 内から、変数listHにアクセスする方法では、function内から参照できる変数は、"最後のループ"の変数のみ。これは、Jsエンジンのエグゼキューション・プロセスexecution processと関連あり。

 

-- (ii)
list.style.overflowY = 'hidden'
❷ listの高さを取得
list.style.height = '0'
順番が大事。

ulを 後でopenする時のために、通常時の高さを図っておく。ただし、overflowを設定してから高さ取得しないと誤差が出る。
overflow設定前の値の方が、5-7pxほど小さくなり、これでやってしまうとopen時、完全に開かない。

 

-- (iii) addEventListener(type, callback)
callback(Event)

- callback の parameter は一つ。Event

Event --- イベントに関連する情報を含んだobject。Event.type, Event.target, Event.preventDefault()などのメソッドが良く使われる。

又、function context (this の値)は EventTarget object;
( 要参照-- 1.3 Event Listener Registration | W3C DOM
https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration
特に
「1.3.1 Event Registration Interfaces」の 後半: Interface EventListener
https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener

 

:::::::::::::::::::::::::::::::: p.s:::::::::::::::::::::::::::

**何故かは分からないのですが、どうもはてなブログの何かが原因で、nextElementSibling がうまく作動しませんでした。なので、この記事のソースコードはサンプルコードやJS Binとは違う、別のコードでToggleを実装しています。

localhostだと、内臓ブラウザでもChrome, safari(iOS)共に上手く作動していました。。

うーん...いまいち原因がよくわからないので、モヤモヤしています...w(;´・ω・)??

*1:Object のプロパティの値がfunction のもの

This Blog uses M+ Font, Logo Type Gothic, Google Fonts and FontAwesome. It"s free & Designed cool font. Greatful for Koji Morishita of M+ Fonts Designer( Creator) and "フォントな" , Google, Adobe, and Dave Gandy!
Background Photos is downloaded by Unsplash.com. Thanks!
|*´-`)チラッ
Please Click Me
本ブログ全てにおいて、アフィリエイトプログラムには参加しておりません(•ᵕᴗᵕ•) 詳しくはこちらをご覧下さい。また、 以下のバナーは、私が「質が高い・あら素敵(ˊo̶̶̷ᴗo̶̶̷`)✨」と感じたサイト様を掲載させて頂いておます_(( _๑´ω`))_⭐️