hx-swap

hx-swap 속성을 μ‚¬μš©ν•˜λ©΄ AJAX μš”μ²­μ˜ target을 κΈ°μ€€μœΌλ‘œ 응닡이 μ–΄λ–»κ²Œ ꡐ체될지 지정할 수 μžˆμŠ΅λ‹ˆλ‹€. μ˜΅μ…˜μ„ μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ 기본값은 htmx.config.defaultSwapStyle(innerHTML)μž…λ‹ˆλ‹€.

이 μ†μ„±μ˜ κ°€λŠ₯ν•œ 값은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

μ΄λŸ¬ν•œ μ˜΅μ…˜μ€ ν‘œμ€€ DOM 이름 지정과 Element.insertAdjacentHTML 사양을 기반으둜 ν•©λ‹ˆλ‹€.

이 μ½”λ“œμ—μ„œλ„ λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€:

  <div hx-get="/example" hx-swap="afterend">Get Some HTML & Append It</div>

divλŠ” /example에 μš”μ²­μ„ 보내고 λ°˜ν™˜λœ μ½˜ν…μΈ λ₯Ό div 뒀에 μΆ”κ°€ν•©λ‹ˆλ‹€.

Modifiers

hx-swap 속성은 ꡐ체 λ™μž‘μ„ λ³€κ²½ν•˜κΈ° μœ„ν•œ μˆ˜μ •μžλ₯Ό μ§€μ›ν•©λ‹ˆλ‹€. μ•„λž˜μ— μ„€λͺ…λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

Transition: transition

ꡐ체가 λ°œμƒν•  λ•Œ μƒˆλ‘œμš΄ View Transitions APIλ₯Ό μ‚¬μš©ν•˜λ €λ©΄ ꡐ체에 transition:true μ˜΅μ…˜μ„ μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€. htmx.config.globalViewTransitions ꡬ성 섀정을 true둜 μ„€μ •ν•˜μ—¬ 이 κΈ°λŠ₯을 μ „μ—­μ μœΌλ‘œ ν™œμ„±ν™”ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

Timing: swap & settle

swap μˆ˜μ •μžλ₯Ό ν¬ν•¨ν•˜μ—¬ μ½˜ν…μΈ  ꡐ체λ₯Ό μœ„ν•΄ 응닡을 받은 ν›„ htmxκ°€ λŒ€κΈ°ν•˜λŠ” μ‹œκ°„μ„ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

  <!-- this will wait 1s before doing the swap after it is received -->
  <div hx-get="/example" hx-swap="innerHTML swap:1s">Get Some HTML & Append It</div>

λ§ˆμ°¬κ°€μ§€λ‘œ settle μˆ˜μ •μžλ₯Ό ν¬ν•¨ν•˜μ—¬ ꡐ체와 정리 둜직 μ‚¬μ΄μ˜ μ‹œκ°„μ„ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

  <!-- this will wait 1s before doing the swap after it is received -->
  <div hx-get="/example" hx-swap="innerHTML settle:1s">Get Some HTML & Append It</div>

μ΄λŸ¬ν•œ 속성을 μ‚¬μš©ν•˜μ—¬ htmxλ₯Ό CSS μ „ν™˜ 효과의 타이밍과 동기화할 수 μžˆμŠ΅λ‹ˆλ‹€.

Title: ignoreTitle

기본적으둜 htmxλŠ” 응닡 μ½˜ν…μΈ μ—μ„œ <title> νƒœκ·Έλ₯Ό 찾으면 νŽ˜μ΄μ§€μ˜ 제λͺ©μ„ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€. ignoreTitle μ˜΅μ…˜μ„ true둜 μ„€μ •ν•˜μ—¬ 이 λ™μž‘μ„ ν•΄μ œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Scrolling: scroll & show

scrollκ³Ό show μˆ˜μ •μžλ₯Ό μ‚¬μš©ν•˜μ—¬ λŒ€μƒ μš”μ†Œμ˜ 슀크둀 λ™μž‘μ„ λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 μˆ˜μ •μžλ“€μ€ 각각 topκ³Ό bottom 값을 κ°€μ§‘λ‹ˆλ‹€:

  <!-- 이 κ³ μ • 높이 divλŠ” μ½˜ν…μΈ κ°€ μΆ”κ°€λœ ν›„ div의 ν•˜λ‹¨μœΌλ‘œ μŠ€ν¬λ‘€λ©λ‹ˆλ‹€ -->
  <div style="height:200px; overflow: scroll" 
       hx-get="/example" 
       hx-swap="beforeend scroll:bottom">
     Get Some HTML & Append It & Scroll To Bottom
  </div>
  <!-- μ΄λŠ” 일뢀 μ½˜ν…μΈ λ₯Ό 가져와 #another-div에 μΆ”κ°€ν•œ ν›„,
       #another-div의 상단이 λ·°ν¬νŠΈμ— 보이도둝 ν•©λ‹ˆλ‹€ -->
  <div hx-get="/example" 
       hx-swap="innerHTML show:top"
       hx-target="#another-div">
    Get Some Content
  </div>

슀크둀링 λ˜λŠ” ν‘œμ‹œλ₯Ό μœ„ν•΄ λ‹€λ₯Έ μš”μ†Œλ₯Ό λŒ€μƒμœΌλ‘œ μ§€μ •ν•˜λ €λ©΄ scroll: λ˜λŠ” show: λ‹€μŒμ— CSS μ„ νƒμžλ₯Ό λ°°μΉ˜ν•˜κ³  :top λ˜λŠ” :bottom을 μΆ”κ°€ν•˜λ©΄ λ©λ‹ˆλ‹€:

  <!-- μ΄λŠ” 일뢀 μ½˜ν…μΈ λ₯Ό 가져와 ν˜„μž¬ div에 κ΅μ²΄ν•œ ν›„,
       #another-div의 상단이 λ·°ν¬νŠΈμ— 보이도둝 ν•©λ‹ˆλ‹€ -->
  <div hx-get="/example" 
       hx-swap="innerHTML show:#another-div:top">
    Get Some Content
  </div>

ν˜„μž¬ 창의 상단 및 ν•˜λ‹¨μœΌλ‘œ μŠ€ν¬λ‘€ν•˜λ €λ©΄ window:top 및 window:bottom을 μ‚¬μš©ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

  <!-- μ΄λŠ” 일뢀 μ½˜ν…μΈ λ₯Ό 가져와 ν˜„μž¬ div에 κ΅μ²΄ν•œ ν›„,
       λ·°ν¬νŠΈκ°€ 맨 μœ„λ‘œ μŠ€ν¬λ‘€λ˜λ„λ‘ ν•©λ‹ˆλ‹€ -->
  <div hx-get="/example" 
       hx-swap="innerHTML show:window:top">
    Get Some Content
  </div>

Boost된 링크와 폼의 κΈ°λ³Έ λ™μž‘μ€ show:topμž…λ‹ˆλ‹€. 이λ₯Ό μ „μ—­μ μœΌλ‘œ λΉ„ν™œμ„±ν™”ν•˜λ €λ©΄ htmx.config.scrollIntoViewOnBoostλ₯Ό μ‚¬μš©ν•˜κ±°λ‚˜ μš”μ†Œλ³„λ‘œ hx-swap="show:none"을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

<form action="/example" hx-swap="show:none">
  ...
</form>

Focus scroll

htmxλŠ” μ •μ˜λœ ID 속성이 μžˆλŠ” μž…λ ₯에 λŒ€ν•œ μš”μ²­ 간에 focusλ₯Ό μœ μ§€ν•©λ‹ˆλ‹€. 기본적으둜 htmxλŠ” μ‚¬μš©μžκ°€ 이미 ν–ˆμ„ λ•Œ κΈ΄ μš”μ²­μ—μ„œ μ›μΉ˜ μ•ŠλŠ” λ™μž‘μ΄ 될 수 μžˆλŠ”, μš”μ²­ κ°„ focus μž…λ ₯에 λŒ€ν•œ μžλ™ μŠ€ν¬λ‘€μ„ λ°©μ§€ν•©λ‹ˆλ‹€. focus μŠ€ν¬λ‘€μ„ ν™œμ„±ν™”ν•˜λ €λ©΄ focus-scroll:trueλ₯Ό μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.

  <input id="name" hx-get="/validation" 
       hx-swap="outerHTML focus-scroll:true"/>

λ˜λŠ” 각 μš”μ²­ ν›„ νŽ˜μ΄μ§€κ°€ focusκ°€ λ§žμΆ°μ§„ μš”μ†Œλ‘œ μžλ™ μŠ€ν¬λ‘€λ˜λ„λ‘ ν•˜λ €λ©΄ htmx μ „μ—­ ꡬ성 κ°’ htmx.config.defaultFocusScroll을 true둜 λ³€κ²½ν•˜λ©΄ λ©λ‹ˆλ‹€. 그런 λ‹€μŒ focus-scroll:falseλ₯Ό μ‚¬μš©ν•˜λ©΄ νŠΉμ • μš”μ²­μ— λŒ€ν•΄ 이 κΈ°λŠ₯을 λΉ„ν™œμ„±ν™”ν•©λ‹ˆλ‹€.

  <input id="name" hx-get="/validation" 
       hx-swap="outerHTML focus-scroll:false"/>

Notes