FxDOM
HTML DOM Bindings for the Functional Extensions for Javascript
Install / Use
/learn @marpple/FxDOMREADME
FxDOM
HTML DOM Bindings for the FxJS
Selector
<div class="container div1" active="true">
<ul class="list1">
<li class="item1">1</li>
<li class="item2">2</li>
<li class="item3">3</li>
</ul>
<div class="div2" active="true">
<ul class="list2">
<li class="item4">4</li>
<li class="item5">5</li>
</ul>
</div>
</div>
$, $.all
$는 document.querySelector를 사용하고 $.all은 document.querySelectorAll을 사용합니다.
console.log($(".container li"));
// li.item1
console.log($.all(".container li"));
// NodeList(5) [li.item1, li.item2, li.item3, li.item4, li.item5]
$.find, $.findAll
$.find는 el.querySelector를 사용하고 $.findAll은 el.querySelectorAll을 사용합니다.
console.log($.find("li", $(".container div")));
// li.item4
console.log($.findAll("li", $(".container div")));
// NodeList(2) [li.item4, li.item5]
console.log($.find("li", $(".container")));
// li.item1
console.log($.findAll("li", $(".container")));
// NodeList(5) [li.item1, li.item2, li.item3, li.item4, li.item5]
console.log($.findAll("ul li", $(".container")));
// NodeList(5) [li.item1, li.item2, li.item3, li.item4, li.item5]
el.querySelector나 el.querySelectorAll의 아쉬운점
el.querySelector나 el.querySelectorAll의 경우는 셀렉터의 시작으로 >를 사용할 수 없습니다.
try {
document.querySelector(".container").querySelectorAll("> ul li");
} catch (e) {
console.log(e);
// DOMException: Failed to execute 'querySelectorAll' on 'Element': '> ul li' is not a valid selector.
}
el.querySelector나 el.querySelectorAll의 경우는 셀렉터의 시작이 부모도 포함하고, 자식요소도 포함한다는 점을 유의해야합니다.
console.log(
document.querySelector(".container").querySelectorAll("[active=true] > ul li")
);
// NodeList(5) [li.item1, li.item2, li.item3, li.item4, li.item5]
with >, with &
아래 예제는 $.find, $.findAll와 el.querySelector나 el.querySelectorAll의 차이를 보여줍니다.
$.find, $.findAll은>를 셀렉터의 시작으로 사용할 수 있습니다.&를 통해 부모 element에 대해서만 추가 조건을 붙일 수 있습니다.
console.log($.findAll("> ul li", $(".container")));
// NodeList(5) [li.item1, li.item2, li.item3]
console.log($.findAll('&[active="true"] li', $(".container")));
// NodeList(5) [li.item1, li.item2, li.item3, li.item4, li.item5]
console.log($.findAll('&[active="true"] > ul li', $(".container")));
// NodeList(5) [li.item1, li.item2, li.item3]
console.log($.findAll('&[active="false"] li', $(".container")));
// NodeList() []
$.closest
자신을 포함하여 셀렉터와 매칭되는 부모 엘리먼트를 찾습니다.
console.log($.closest("li", $(".item4")));
// li.item4
console.log($.closest("ul", $(".item4")));
// ul.list2
console.log($.closest("div", $(".item4")));
// div.div2
console.log($.closest("div.container", $(".item4")));
// div.container.div1
$.children
$.prevAll
$.nextAll
$.prev
$.next
$.siblings
$.is
첫 번째 인자에 전달된 셀렉터와 매칭이 되는지 확인합니다.
console.log($.is(".item1", $("li:nth-child(1)")));
// true
console.log($.is(".item1", $("li:nth-child(2)")));
// true
$.contains
Create
$.els
console.log($.els('<span class="s1">1</span>'));
// HTMLCollection(2) [span.s1]
console.log($.els('<span class="s1">1</span><span class="s2">2</span>'));
// HTMLCollection(2) [span.s1, span.s2]
$.el
console.log($.el('<span class="s1">1</span>'));
// span.s1
console.log($.el('<span class="s1">1</span><span class="s2">2</span>'));
// span.s1
Manipulation
$.appendTo
$.appendTo($(".comments"), $.el('<div class="comment">새 댓글</div>'));
$.prependTo
$.prependTo($(".posts"), $.el('<div class="post">새 글</div>'));
$.append
$.append($.el('<div class="comment">새 댓글</div>'), $(".comments"));
$.prepend
$.prepend($.el('<div class="post">새 글</div>'), $(".posts"));
$.before
$.insertBefore
$.after
$.insertAfter
$.replaceAll
$.replaceWith
$.remove
$.remove($(".post"));
$.text
console.log($.text($.el("<div>hi</div>")));
// "hi"
$.setText
console.log($.setText("ho", $.el("<div></div>")));
// HTMLDivElement <div>ho</div>
$.html
console.log($.html($.el("<div><span>hi</span></div>")));
// "<span>hi</span>"
$.setHTML
console.log($.setHTML("<span>ho</span>", $.el("<div></div>")));
// HTMLDivElement <div><span>ho</span></div>
$.outerHTML
console.log($.outerHTML($.el("<div><span>hi</span></div>")));
// "<div><span>hi</span></div>"
$.setOuterHTML
<div id="div1"></div>let el = $("#div1");
$.setOuterHTML('<div id="div1" class="hi2"></div>', el);
console.log($("#div1"));
// HTMLDivElement <div id="div1" class="hi2"></div>
$.val
console.log($.val($.el('<input type="text" value="hoho">')));
// "hoho"
$.setVal
console.log($.setVal("hoho", $.el('<input type="text">')).value);
// "hoho"
$.attr
console.log($.attr("type", $.el('<input type="text" value="hoho">')));
// "text"
$.setAttr
console.log($.setAttr({ status: "ho" }, $.el('<div status="hi">')));
// HTMLDivElement <div status="ho"></div>
console.log(
$.setAttr({ status: "ho", class: "ye" }, $.el('<div status="hi">'))
);
// HTMLDivElement <div status="ho" class="ye"></div>
console.log($.setAttr(["status", "ho"], $.el('<div status="hi">')));
// HTMLDivElement <div status="ho"></div>
console.log($.setAttr({ status: "" }, $.el('<div status="hi">')));
// HTMLDivElement <div status></div>
$.removeAttr
console.log($.removeAttr("status", $.el('<div status="hi">')));
// HTMLDivElement <div></div>
$.prop
$.setProp
$.removeProp
CSS
$.addClass
console.log($.addClass("selected", $.el("div")));
// HTMLDivElement <div class="selected"></div>
console.log($.addClass("hi ho", $.el("div")));
// HTMLDivElement <div class="hi ho"></div>
console.log($.addClass("hi", $.el('<div class="ye">')));
// HTMLDivElement <div class="ye hi"></div>
$.removeClass
console.log($.removeClass("selected", $.el('<div class="selected"></div>')));
// HTMLDivElement <div class></div>
console.log($.removeClass("hi ho", $.el('<div class="hi ho"></div>')));
// HTMLDivElement <div class></div>
console.log($.removeClass("hi", $.el('<div class="ye hi">')));
// HTMLDivElement <div class="ye"></div>
$.toggleClass
console.log($.toggleClass("selected", $.el('<div class="selected"></div>')));
// HTMLDivElement <div class></div>
console.log($.toggleClass("selected", $.el("<div></div>")));
// HTMLDivElement <div class="selected"></div>
$.hasClass
console.log($.hasClass("selected", $.el('<div class="selected"></div>')));
// true
console.log($.hasClass("a", $.el('<div class="b"></div>')));
// false
$.css
$.setCss
$.show
$.hide
$.toggle
$.offset
console.log(
$.offset(
$.append(
$("body"),
$.setCss(
{
position: "absolute",
top: "20px",
left: "30px",
"margin-top": "50px",
},
$.el("div")
)
)
)
);
// { top: 70, left: 30 }
$.offsetParent
$.position
$.width
width
$.height
height
$.innerWidth
width + paddingLeft + paddingRight + borderLeft + borderRight
$.innerHeight
height + paddingTop + paddingBottom + borderTop + borderBottom
$.outerWidth
innerWidth + marginLeft + marginRight
$.outerHeight
innerHeight + marginTop + marginBottom
$.scrollTop
$.scrollLeft
$.setScrollTop
$.setScrollLeft
Event
$.on
$.on은 el.addEventListener를 대신합니다. $.on은 이벤트를 등록할 함수를 리턴하며, 커링 방식으로만 사용할 수 있습니다.
- 인자로 받은 함수를 조작하지 않고
el.addEventListener에 그대로 적용하여, 같은 엘리먼트에 같은 이벤트와 같은 함수를 등록이 되지 않는el.addEventListener의 특징을 그대로 유지했습니다. el.addEventListener의capture,passive등의 옵션을 사용할 수 있습니다.e.preventDefault,e.stopPropagation을 사용할 수 있습니다.el.removeEventListener와$.off를 사용할 수 있습니다.
<button type="button" id="btn1">
<span>btn1</span>
</button>
const addClickEvent = $.on("click", function (e) {
console.log(e.currentTarget); // #btn1
console.log(e.target); // span
});
addClickEvent($("#btn1"));
addClickEvent($("#btn1")); // 두 번 등록해도 추가로 등록되지 않음.
$.trigger("click", $("#btn1 span"));
// #btn1
// span
$.on의 두 번째 인자에 셀렉터를 전달하면 매칭되는 자식요소에 이벤트를 등록합니다. 이 방식은 위임 방식이 아니며, 역시 el.addEventListener의 주요 특징과 기능을 모두 사용할 수 있습니다.
<div class="articles">
<div class="article">
<button type="button" class="remove"><span>삭제</span></button>
</div>
<div class="article">
<button type="button" class="remove"><span>삭제</span></button>
</div>
</div>
const Articles = {
addEvents: pipe(
$.on("click", ".article:nth-child(1)", function (e) {
console.log(e.currentTarget);
}),
$.on(
"click",
".article",
function (e) {
console.log(e.currentTarget);
},
{ capture: true }
),
$.on("click", ".remove", function (e) {
console.log("other_data:", e.other_data);
console.log(e.currentTarget);
})
),
};
Articles.addEvents($(".articles"));
$.trigger("click", $(".articles .article:nth-child(1) .remove")); // 한 번만 실행
// other_data: undefined
// button.remove
// div.article
$.trigger("click", $(".articles .article:nth-child(2) .remove"));
// div.article
// other_data: undefined
// button.remove
$.append(
$(".articles"),
$.el(`
<div class="article new">
<button type="button" class="remove
