actualizar el menú a medida que se pasan secciones
This commit is contained in:
parent
5ea8e57f2d
commit
cdb81d02e5
4 changed files with 78 additions and 3 deletions
|
@ -3,7 +3,7 @@
|
|||
{% include_cached logo.svg %}
|
||||
</a>
|
||||
|
||||
<ul class="navbar-nav d-print-none">
|
||||
<ul class="navbar-nav d-print-none" data-controller="menu">
|
||||
{%- for item in site.i18n.menu.items -%}
|
||||
{% comment %}
|
||||
Algunos items del menú tienen layouts para indicar que
|
||||
|
@ -22,7 +22,7 @@
|
|||
{%- assign href = post.url | default: item.href -%}
|
||||
{%- assign active = include.active_cache_key | equals: href -%}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {{ active | ternary: 'active', '' }}" href="{{ href }}">
|
||||
<a data-target="menu.item" class="nav-link {{ active | ternary: 'active', '' }}" href="{{ href }}">
|
||||
{{ item.title }}
|
||||
|
||||
{%- if active -%}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
{%- assign active_cache_key = page.url | menu_active_item | default: 'none' -%}
|
||||
{%- include_cached navbar.html active_cache_key=active_cache_key %}
|
||||
|
||||
<main>
|
||||
<main data-controller="scroll">
|
||||
{{ content }}
|
||||
</main>
|
||||
|
||||
|
|
32
_packs/controllers/menu_controller.js
Normal file
32
_packs/controllers/menu_controller.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
import 'core-js/stable'
|
||||
import 'regenerator-runtime/runtime'
|
||||
import { Controller } from 'stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = [ 'item' ]
|
||||
|
||||
connect () {
|
||||
window.addEventListener('scroll:section', event => this.update(event.detail.id))
|
||||
}
|
||||
|
||||
get items () {
|
||||
if (!this._items) {
|
||||
this._items = {}
|
||||
|
||||
for (const item of this.itemTargets) {
|
||||
this._items[item.href.split('#')[1]] = item
|
||||
}
|
||||
}
|
||||
|
||||
return this._items
|
||||
}
|
||||
|
||||
update (id) {
|
||||
console.log(id)
|
||||
for (const item of Object.values(this.items)) {
|
||||
item.classList.remove('active')
|
||||
}
|
||||
|
||||
if (this.items[id]) this.items[id].classList.add('active')
|
||||
}
|
||||
}
|
43
_packs/controllers/scroll_controller.js
Normal file
43
_packs/controllers/scroll_controller.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
import 'core-js/stable'
|
||||
import 'regenerator-runtime/runtime'
|
||||
import { Controller } from 'stimulus'
|
||||
|
||||
/*
|
||||
* Al navegar por el sitio y llegar a ciertas secciones, se van
|
||||
* activando ítems del menú.
|
||||
*
|
||||
* Para eso configuramos un IntersectionObserver en todo el documento y
|
||||
* a medida que van apareciendo secciones actualizamos el menú.
|
||||
*/
|
||||
export default class extends Controller {
|
||||
static targets = [ 'section' ]
|
||||
|
||||
connect () {
|
||||
for (const section of this.sectionTargets) {
|
||||
this.observer.observe(section)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Solo nos interesa la primera
|
||||
*/
|
||||
get observer () {
|
||||
if (!this._observer) this._observer = new IntersectionObserver((entries, observer) => this.update(entries), this.options)
|
||||
|
||||
return this._observer
|
||||
}
|
||||
|
||||
get options () {
|
||||
if (!this._options) this._options = { threshold: 0, rootMargin: '0px' }
|
||||
|
||||
return this._options
|
||||
}
|
||||
|
||||
update (entries) {
|
||||
const section = entries.find(x => x.isIntersecting)
|
||||
|
||||
if (!section) return
|
||||
|
||||
window.dispatchEvent(new CustomEvent('scroll:section', { detail: { id: section.target.id }}))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue