DOMおれおれAdvent Calendar 2015 – 24日目
最終日です。

jQueryでやってる事をjQueryなしでやるとしたらどうするのってやつです。
$(selector)
→ document.querySelectorAll(selector)
これが一番基本ですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 | // jQuery var $el = $( '.foo' ); console.log($el.length); console.log($el[0]); // DOM var els = document.querySelectorAll( '.foo' ); console.log(els.length); console.log(els[0]); // DOM(一件のみ) var el = document.querySelector( '.foo' ); console.log(el); |
find()
→ querySelectorAll()
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); console.log($el.find( '.bar' )); // DOM var els = document.querySelectorAll( '.foo' ); console.log(els[0].querySelectorAll( '.bar' )); |
each()
→ Array.prototype.forEach()
document.querySelectorAll()
の結果には each()
のように「全てに適用」する仕組みがありません。自前で for
文を書くか、配列の forEach()
を利用するのが便利です。
1 2 3 4 5 6 7 8 9 10 11 | // jQuery var $el = $( '.foo' ); $el.each( function (index, el) { console.log(index, el); }); // DOM var els = document.querySelectorAll( '.foo' ); Array.prototype.forEach.call(els, function (el, index) { console.log(index, el); }); |
コールバック関数に与えられる引数の順序が異なる点に気を付けてください。
on()
→ addEventListener()
1 2 3 4 5 6 7 8 9 10 11 | // jQuery var $el = $( '.foo' ); $el.on( 'click' , function (event) { console.log(event.type); }); // DOM var els = document.querySelectorAll( '.foo' ); els[0].addEventListener( 'click' , function (event) { console.log(event.type); }); |
document.querySelectorAll()
の結果は複数件になりますが、 addEventListener()
は一件ずつしか適用できません。複数件を対象にイベント監視する場合は別項で紹介した Array.prototype.forEach()
を使います。
以降も同じです。
デリゲートは event.target.matches(selector)
デリゲートっていう表現してたよね? $area.on('click', '.inner', listener)
みたいなやつ。
1 2 3 4 5 6 7 8 9 10 11 12 13 | // jQuery var $el = $( '.foo' ); $el.on( 'click' , '.bar' , function (event) { console.log(event.type); }); // DOM var els = document.querySelectorAll( '.foo' ); els[0].addEventListener( 'click' , function (event) { if (event.target.matches( '.bar' )) { console.log(event.type); } }); |
off()
→ removeEventListener()
1 2 3 4 5 6 7 8 9 10 11 | var callback = function (event) { console.log(event.type); }; // jQuery var $el = $( '.foo' ); $el.off( 'click' , callback); // DOM var els = document.querySelectorAll( '.foo' ); els[0].removeEventListener( 'click' , callback); |
解除するコールバック関数のインスタンスが必要なのがちょっと面倒なところ。WeakMapなんか使えると管理が楽そうなんだけどなー。
trigger()
→ dispatchEvent()
割と面倒くさい。
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '.foo' ); $el.trigger( 'mogu' ); // DOM var els = document.querySelectorAll( '.foo' ); var myEvent = document.createEvent( 'CustomEvent' ); myEvent.initCustomEvent( 'mogu' , true , true , null ); els[0].dispatchEvent(myEvent); |
クラス操作 → classList
addClass()
→ classList.add()
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); $el.addClass( 'is-active' ); // DOM var els = document.querySelectorAll( '.foo' ); els[0].classList.add( 'is-active' ); |
removeClass()
→ classList.remove()
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); $el.removeClass( 'is-active' ); // DOM var els = document.querySelectorAll( '.foo' ); els[0].classList.remove( 'is-active' ); |
toggleClass()
→ classList.toggle()
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); $el.toggleClass( 'is-active' ); // DOM var els = document.querySelectorAll( '.foo' ); els[0].classList.toggle( 'is-active' ); |
hasClass()
→ classList.has()
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); $el.hasClass( 'is-active' ); // DOM var els = document.querySelectorAll( '.foo' ); els[0].classList.contains( 'is-active' ); |
css()
→ style
、 getComputedStyle()
数値 200
は設定してもCSS的に不正なので、単位付き "200px"
で指定する必要があります。取得時も単位付きで得られます。
1 2 3 4 5 6 7 8 9 10 | // jQuery var $el = $( '.foo' ); $el.css({ color: 'red, width:200 }); console.log($el.css(' color ')); // DOM var els = document.querySelectorAll(' .foo '); els[0].style.color = ' red '; els[0].style.width = ' 200px'; console.log(getComputedStyle(els[0]).color); |
attr()
→ setAttribute()
、 getAttribute()
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '.foo' ); $el.attr( 'href' , '#top' ); console.log($el.attr( 'href' )); // DOM var els = document.querySelectorAll( '.foo' ); els[0].setAttribute( 'href' , '#top' ); console.log(els[0].getAttribute( 'href' )); |
prop()
→ プロパティ
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '.foo' ); $el.prop( 'href' , '#top' ); console.log($el.prop( 'href' )); // DOM var els = document.querySelectorAll( '.foo' ); els[0].href = '#top' ; console.log(els[0].href); |
val()
→ value
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '.foo' ); $el.val( 'I like it!' ); console.log($el.val()); // DOM var els = document.querySelectorAll( '.foo' ); els[0].value = 'I like it!' ; console.log(els[0].value); |
text()
→ textContent
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '.foo' ); $el.text( '<b>BOLD</b>' ); console.log($el.text()); // DOM var els = document.querySelectorAll( '.foo' ); els[0].textContent = '<b>BOLD</b>' ; console.log(els[0].textContent); |
html()
→ innerHTML
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '.foo' ); $el.html( '<b>BOLD</b>' ); console.log($el.html()); // DOM var els = document.querySelectorAll( '.foo' ); els[0].innerHTML = '<b>BOLD</b>' ; console.log(els[0].innerHTML); |
$(html)
→ innerHTML
を使って自作
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '<div>' ); console.log($el); // DOM var wrapper = document.createElement( 'div' ); wrapper.innerHTML = '<div></div>' ; var el = wrapper.firstChild; console.log(el); |
is()
→ matches()
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); console.log($el.is( '.foo' )); // DOM var els = document.querySelectorAll( '.foo' ); console.log(els[0].matches( '.foo' )); |
parent()
→ parentNode
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); console.log($el.parent()); // DOM var els = document.querySelectorAll( '.foo' ); console.log(els[0].parentNode); |
closest()
→ 自作
1 2 3 4 5 6 7 8 9 10 11 12 | // jQuery var $el = $( '.foo' ); console.log($el.closest( '.wrapper' )); // DOM var els = document.querySelectorAll( '.foo' ); for ( var closest=els[0]; closest; closest=closest.parentElement) { if (closest.matches( '.wrapper' )) { break ; } } console.log(closest); |
children()
→ children
1 2 3 4 5 6 7 8 9 10 11 12 13 | // jQuery var $el = $( '.foo' ); var $children = $el.children(); for ( var i=0, l=$children.length; i<l; i++) { console.log($children[i]); } // DOM var els = document.querySelectorAll( '.foo' ); var children = els[0].children; for ( var i=0, l=children.length; i<l; i++) { console.log(children[i]); } |
その他 firstElementChild
、 lastElementChild
というのもあります。
prev()
→ previousElementSibling
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); console.log($el.prev()); // DOM var els = document.querySelectorAll( '.foo' ); console.log(els[0].previousElementSibling); |
next()
→ nextElementSibling
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); console.log($el.next()); // DOM var els = document.querySelectorAll( '.foo' ); console.log(els[0].nextElementSibling); |
filter()
→ Array.prototype.filter()
1 2 3 4 5 6 7 8 9 10 | // jQuery var $el = $( '.foo' ); console.log($el.filter( '.bar' )); // DOM var els = document.querySelectorAll( '.foo' ); var filtered = Array.prototype.filter.call(els, function (el) { return el.matches( '.bar' ); }); console.log(filtered); |
append(el)
→ appendChild(el)
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '.foo' ); var $child = $( '.child' ); $el.append($child); // DOM var els = document.querySelectorAll( '.foo' ); var children = document.querySelectorAll( '.child' ); els[0].appendChild(children[0]); |
append(html)
→ innerHTML
と appendChild(el)
で自作
別項で紹介したやつの組み合わせです。
1 2 3 4 5 6 7 8 9 10 | // jQuery var $el = $( '.foo' ); $el.append( '<b>BOLD</b>' ); // DOM var els = document.querySelectorAll( '.foo' ); var wrapper = document.createElement( 'div' ); wrapper.innerHTML = '<b>BOLD</b>' ; var child = wrapper.firstChild; els[0].appendChild(child); |
remove()
→ removeChild()
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); $el.remove(); // DOM var els = document.querySelectorAll( '.foo' ); els[0].parentNode.removeChild(els[0]); |
width()
→ clientWidth
1 2 3 4 5 6 7 8 9 | // jQuery var $el = $( '.foo' ); $el.width(200); console.log($el.width()); // DOM var els = document.querySelectorAll( '.foo' ); els[0].style.width = '200px' ; console.log(els[0].clientWidth); |
outerWidth()
→ getBoundingClientRect()
1 2 3 4 5 6 7 | // jQuery var $el = $( '.foo' ); console.log($el.outerWidth()); // DOM var els = document.querySelectorAll( '.foo' ); console.log(els[0].getBoundingClientRect().width); |
position()
→ offsetLeft
、 offsetTop
1 2 3 4 5 6 7 8 | // jQuery var $el = $( '.foo' ); var position = $el.position(); console.log(position.left, position.top); // DOM var els = document.querySelectorAll( '.foo' ); console.log(els[0].offsetLeft, els[0].offsetTop); |
offset()
→ getBoundingClientRect()
1 2 3 4 5 6 7 8 9 10 11 | // jQuery var $el = $( '.foo' ); var offset = $el.offset(); console.log(offset.top); // DOM var els = document.querySelectorAll( '.foo' ); var offset = els[0].getBoundingClientRect(); var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; var top = scrollTop + offset.top; console.log(top); |
その他
DOMじゃないけど。
$.ajax()
→ XMLHttpRequest
で頑張る
簡単な例だけ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // jQuery $.ajax({ url: '/api/sugoi' , data: { foo:123 } }).done( function (data) { console.log(data); }); // DOMじゃない var xhr = new XMLHttpRequest(); xhr.addEventListener( 'load' , function (event) { var data = JSON.parse( this .response); console.log(data); }); xhr.open( 'GET' , '/api/sugoi' ); xhr.send(JSON.stringify({ foo:123 })); |
おしまい
こんな感じの実装を、昨日分の記事の「基本戦略」と組み合わせると「おれおれjQuery」ができあがります。
というわけで、よければgQuery使ってみてください。