actualizar el menú a medida que se pasan secciones

This commit is contained in:
f 2020-11-12 17:29:12 -03:00
parent 5ea8e57f2d
commit cdb81d02e5
4 changed files with 78 additions and 3 deletions

View file

@ -3,7 +3,7 @@
{% include_cached logo.svg %} {% include_cached logo.svg %}
</a> </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 -%} {%- for item in site.i18n.menu.items -%}
{% comment %} {% comment %}
Algunos items del menú tienen layouts para indicar que Algunos items del menú tienen layouts para indicar que
@ -22,7 +22,7 @@
{%- assign href = post.url | default: item.href -%} {%- assign href = post.url | default: item.href -%}
{%- assign active = include.active_cache_key | equals: href -%} {%- assign active = include.active_cache_key | equals: href -%}
<li class="nav-item"> <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 }} {{ item.title }}
{%- if active -%} {%- if active -%}

View file

@ -34,7 +34,7 @@
{%- assign active_cache_key = page.url | menu_active_item | default: 'none' -%} {%- assign active_cache_key = page.url | menu_active_item | default: 'none' -%}
{%- include_cached navbar.html active_cache_key=active_cache_key %} {%- include_cached navbar.html active_cache_key=active_cache_key %}
<main> <main data-controller="scroll">
{{ content }} {{ content }}
</main> </main>

View 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')
}
}

View 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 }}))
}
}