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 %}
|
{% 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 -%}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
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