Estoy tratando de implementar barba.js en un sitio de HubSpot .
Considere las siguientes dos páginas:
Con mi implementación barba.js actual, este es el flujo actual que estoy experimentando:
resources (no haciendo la transición a ella, accediendo directamente a ella a través de /resources ).js está funcionando ( slick-sliders , funciones de desplazamiento, etc.)customers . La página se carga, pero todos los js específicos de los módulos y formularios para esa página no funcionan. En resumen, js para las páginas a las que hago la transition no funcionan.
Para resolver esto, lo que estoy tratando de hacer es volver a cargar todos los scripts dentro del container beforeEnter() .
Vea abajo:
$(function() { function delay(n){ n = n || 2000; return new Promise((done) => { setTimeout(() => { done(); }, n); }); } barba.init({ sync: true, prefetchIgnore: true, debug: true, transitions: [{ async leave(data){ const done = this.async(); await delay(200); done(); }, async beforeEnter({ next, container }) { $(container).find('script').each(function (i, script) { var $script = $(script); $.ajax({ url: $script.attr('src'), cache: true, dataType: 'script', success: function () { $script.trigger('load'); } }); }); }, async enter(data){ let scrollX = 0 let scrollY = 0 barba.hooks.leave(() => { scrollX = barba.history.current.scroll.x; scrollY = barba.history.current.scroll.y; }); window.scrollTo(scrollX, scrollY); }, async once(data){ console.log("done"); }, }] }); }); Sin embargo, mi beforeEnter() actual todavía produce los mismos resultados. ¿Alguna forma de evitar esto?
Editar
Para brindar más detalles, esta implementación de barba.js es para un sitio de HubSpot . Cuando creas custom modules en HubSpot , escupe el JS para ese módulo en la página (en etiquetas de script ). Por ejemplo, así es como se representa JS en la página:
<script> // js from custom module is here </script> <script src=".../scripts-min.min.js"></script> Como tal, cuando se ejecuta una transición de barba , necesito todos los JS que tienen src y aquellos que se procesan en línea (como módulos personalizados) para recargar.
Último enfoque basado en los comentarios de User863
$(function() { function delay(n){ n = n || 2000; return new Promise((done) => { setTimeout(() => { done(); }, n); }); } function reload_scripts(param){ $(param).find('script').each(function (i, script) { var $script = $(script); $.ajax({ url: $script.attr('src'), cache: true, dataType: 'script', success: function () { $script.trigger('load'); console.log("scripts loaded"); } }); }); } barba.init({ sync: true, prefetchIgnore: true, debug: true, transitions: [{ async leave(data){ const done = this.async(); await delay(200); done(); }, async beforeEnter(data) { reload_scripts(data.next.container); }, async beforeEnter({ next }) { reload_scripts(next.container); }, async enter(data){ // scroll to top of page when transitioning let scrollX = 0 let scrollY = 0 barba.hooks.leave(() => { scrollX = barba.history.current.scroll.x; scrollY = barba.history.current.scroll.y; }); window.scrollTo(scrollX, scrollY); }, async once(data){ console.log("transition complete"); }, }] }); }); Comportamiento actual: igual que antes (los scripts de los módulos se interrumpen cuando cambia la página). Los módulos con slick slider , por ejemplo, no funcionan (el slick no se inicia).
Podría resolverse usando eval como se menciona aquí: https://github.com/barbajs/barba/issues/32
Mencionado en los comentarios sobre el tema:
barba.hooks.after((data) => { let js = data.next.container.querySelectorAll('main script'); if(js != null){ js.forEach((item) => { console.log(js) eval(item.innerHTML); }); } });De acuerdo con los documentos
Los argumentos de beforeEnter transición serán objeto de
| Propiedad | Descripción |
|---|---|
| datos.actuales | Página actual relacionada |
| datos.siguiente | Página siguiente relacionada |
| datos.trigger | Enlace que desencadenó la transición |
https://barba.js.org/docs/advanced/hooks/#data-properties
Por lo tanto, la propiedad del container está disponible dentro de las propiedades data.current y data.next . En este caso, tenemos que usar el script de data.next que se relaciona con una nueva página.
Código fijo #1
async beforeEnter(data) { $(data.next.container).find('script').each(function (i, script) { // ... }) }Código fijo #2
async beforeEnter({ next }) { $(next.container).find('script').each(function (i, script) { // ... }) }