barba-js

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Barba.js

Barba.js

Modern page transition library for creating fluid, smooth transitions between website pages. Barba.js makes multi-page websites feel like Single Page Applications (SPAs) by hijacking navigation and managing transitions without full page reloads.
一款用于在网站页面之间创建流畅顺滑过渡效果的现代页面过渡库。Barba.js通过拦截导航并在无需整页刷新的情况下管理过渡效果,让多页面网站拥有类单页应用(SPA)的体验。

Overview

概述

Barba.js is a lightweight (7kb minified and compressed) JavaScript library that intercepts navigation between pages, fetches new content via AJAX, and smoothly transitions between old and new containers. It reduces page load delays and HTTP requests while maintaining the benefits of traditional multi-page architecture.
Core Features:
  • Smooth page transitions without full reloads
  • Lifecycle hooks for precise control over transition phases
  • View-based logic for page-specific behaviors
  • Built-in routing with @barba/router plugin
  • Extensible plugin system
  • Small footprint and high performance
  • Framework-agnostic (works with vanilla JS, GSAP, anime.js, etc.)
Barba.js是一款轻量级(压缩后仅7kb)的JavaScript库,它拦截页面间的导航请求,通过AJAX获取新内容,并在旧容器和新容器之间实现顺滑过渡。它减少了页面加载延迟和HTTP请求,同时保留了传统多页面架构的优势。
核心特性:
  • 无需整页刷新的顺滑页面过渡
  • 生命周期钩子,可精确控制过渡阶段
  • 基于视图的逻辑,支持页面特定行为
  • 内置路由(搭配@barba/router插件)
  • 可扩展的插件系统
  • 体积小巧且性能优异
  • 与框架无关(可配合原生JS、GSAP、anime.js等使用)

Core Concepts

核心概念

1. Wrapper, Container, and Namespace

1. Wrapper、Container与Namespace

Barba.js uses a specific DOM structure to manage transitions:
HTML Structure:
html
<body data-barba="wrapper">
  <!-- Static elements (header, nav) stay outside container -->
  <header>
    <nav>
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
  </header>

  <!-- Dynamic content goes in container -->
  <main data-barba="container" data-barba-namespace="home">
    <!-- This content changes on navigation -->
    <h1>Home Page</h1>
    <p>Content that will transition out...</p>
  </main>

  <!-- Static footer outside container -->
  <footer>© 2025</footer>
</body>
Three Key Elements:
  1. Wrapper (
    data-barba="wrapper"
    )
    • Outermost container
    • Everything inside wrapper but outside container stays persistent
    • Ideal for headers, navigation, footers that don't change
  2. Container (
    data-barba="container"
    )
    • Dynamic content area that updates on navigation
    • Only this section gets replaced during transitions
    • Must exist on every page
  3. Namespace (
    data-barba-namespace="home"
    )
    • Unique identifier for each page type
    • Used in transition rules and view logic
    • Examples: "home", "about", "product", "blog-post"
Barba.js使用特定的DOM结构来管理过渡效果:
HTML结构:
html
<body data-barba="wrapper">
  <!-- 静态元素(页眉、导航)放在容器外部 -->
  <header>
    <nav>
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
  </header>

  <!-- 动态内容放在容器内部 -->
  <main data-barba="container" data-barba-namespace="home">
    <!-- 导航时该内容会变化 -->
    <h1>Home Page</h1>
    <p>Content that will transition out...</p>
  </main>

  <!-- 静态页脚放在容器外部 -->
  <footer>© 2025</footer>
</body>
三个关键元素:
  1. Wrapper (
    data-barba="wrapper"
    )
    • 最外层容器
    • Wrapper内部但Container外部的所有元素会保持持久化
    • 适合放置页眉、导航、页脚等无需变化的元素
  2. Container (
    data-barba="container"
    )
    • 导航时会更新的动态内容区域
    • 过渡期间只有该部分会被替换
    • 每个页面都必须包含该元素
  3. Namespace (
    data-barba-namespace="home"
    )
    • 每种页面类型的唯一标识符
    • 用于过渡规则和视图逻辑
    • 示例:"home"、"about"、"product"、"blog-post"

2. Transition Lifecycle

2. 过渡生命周期

Barba.js follows a precise lifecycle for each navigation:
Default Async Flow:
  1. User clicks link
  2. Barba intercepts navigation
  3. Prefetch next page (via AJAX)
  4. Cache new content
  5. Leave hook - Animate current page out
  6. Wait for leave animation to complete
  7. Remove old container, insert new container
  8. Enter hook - Animate new page in
  9. Wait for enter animation to complete
  10. Update browser history
Sync Flow (with
sync: true
):
  1. User clicks link
  2. Barba intercepts navigation
  3. Prefetch next page
  4. Wait for new page to load
  5. Leave and Enter hooks run simultaneously (crossfade effect)
  6. Swap containers
  7. Update browser history
Barba.js为每次导航遵循精确的生命周期:
默认异步流程:
  1. 用户点击链接
  2. Barba拦截导航请求
  3. 预加载下一页内容(通过AJAX)
  4. 缓存新内容
  5. Leave钩子 - 为当前页面添加退出动画
  6. 等待退出动画完成
  7. 移除旧容器,插入新容器
  8. Enter钩子 - 为新页面添加进入动画
  9. 等待进入动画完成
  10. 更新浏览器历史记录
同步流程(启用
sync: true
):
  1. 用户点击链接
  2. Barba拦截导航请求
  3. 预加载下一页内容
  4. 等待新页面加载完成
  5. Leave与Enter钩子同时执行(交叉淡入淡出效果)
  6. 切换容器
  7. 更新浏览器历史记录

3. Hooks

3. 钩子

Barba provides 11 lifecycle hooks for controlling transitions:
Hook Execution Order:
Initial page load:
  beforeOnce → once → afterOnce

Every navigation:
  before → beforeLeave → leave → afterLeave →
  beforeEnter → enter → afterEnter → after
Hook Types:
  • Global hooks: Run on every transition (
    barba.hooks.before()
    )
  • Transition hooks: Defined within specific transition objects
  • View hooks: Defined within view objects for page-specific logic
Common Hook Use Cases:
  • beforeLeave
    - Reset scroll position, prepare animations
  • leave
    - Animate current page out
  • afterLeave
    - Clean up old page
  • beforeEnter
    - Prepare new page (hide elements, set initial states)
  • enter
    - Animate new page in
  • afterEnter
    - Initialize page scripts, analytics tracking
Barba提供11个生命周期钩子用于控制过渡效果:
钩子执行顺序:
初始页面加载:
  beforeOnce → once → afterOnce

每次导航:
  before → beforeLeave → leave → afterLeave →
  beforeEnter → enter → afterEnter → after
钩子类型:
  • 全局钩子: 在每次过渡时都会执行(
    barba.hooks.before()
  • 过渡钩子: 在特定过渡对象中定义
  • 视图钩子: 在视图对象中定义,用于页面特定逻辑
常见钩子使用场景:
  • beforeLeave
    - 重置滚动位置、准备动画
  • leave
    - 为当前页面添加退出动画
  • afterLeave
    - 清理旧页面
  • beforeEnter
    - 准备新页面(隐藏元素、设置初始状态)
  • enter
    - 为新页面添加进入动画
  • afterEnter
    - 初始化页面脚本、分析跟踪

4. Views

4. 视图

Views are page-specific logic containers that run based on namespace:
javascript
barba.init({
  views: [{
    namespace: 'home',
    beforeEnter() {
      // Home-specific setup
      console.log('Entering home page');
    },
    afterEnter() {
      // Initialize home page features
      initHomeSlider();
    }
  }, {
    namespace: 'product',
    beforeEnter() {
      console.log('Entering product page');
    },
    afterEnter() {
      initProductGallery();
    }
  }]
});
视图是基于Namespace运行的页面特定逻辑容器:
javascript
barba.init({
  views: [{
    namespace: 'home',
    beforeEnter() {
      // 首页专属设置
      console.log('Entering home page');
    },
    afterEnter() {
      // 初始化首页功能
      initHomeSlider();
    }
  }, {
    namespace: 'product',
    beforeEnter() {
      console.log('Entering product page');
    },
    afterEnter() {
      initProductGallery();
    }
  }]
});

Common Patterns

常见模式

1. Basic Setup

1. 基础设置

Installation:
bash
npm install --save-dev @barba/core
安装:
bash
npm install --save-dev @barba/core

or

yarn add @barba/core --dev

**Minimal Configuration**:
```javascript
import barba from '@barba/core';

barba.init({
  transitions: [{
    name: 'default',
    leave({ current }) {
      // Fade out current page
      return gsap.to(current.container, {
        opacity: 0,
        duration: 0.5
      });
    },
    enter({ next }) {
      // Fade in new page
      return gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});
yarn add @barba/core --dev

**最简配置**:
```javascript
import barba from '@barba/core';

barba.init({
  transitions: [{
    name: 'default',
    leave({ current }) {
      // 为当前页面添加淡出动画
      return gsap.to(current.container, {
        opacity: 0,
        duration: 0.5
      });
    },
    enter({ next }) {
      // 为新页面添加淡入动画
      return gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});

2. Fade Transition (Async)

2. 淡入淡出过渡(异步)

Classic fade-out, fade-in transition:
javascript
import barba from '@barba/core';
import gsap from 'gsap';

barba.init({
  transitions: [{
    name: 'fade',
    async leave({ current }) {
      await gsap.to(current.container, {
        opacity: 0,
        duration: 0.5,
        ease: 'power2.inOut'
      });
    },
    async enter({ next }) {
      // Start invisible
      gsap.set(next.container, { opacity: 0 });

      // Fade in
      await gsap.to(next.container, {
        opacity: 1,
        duration: 0.5,
        ease: 'power2.inOut'
      });
    }
  }]
});
经典的先淡出、再淡入的过渡效果:
javascript
import barba from '@barba/core';
import gsap from 'gsap';

barba.init({
  transitions: [{
    name: 'fade',
    async leave({ current }) {
      await gsap.to(current.container, {
        opacity: 0,
        duration: 0.5,
        ease: 'power2.inOut'
      });
    },
    async enter({ next }) {
      // 初始状态设为不可见
      gsap.set(next.container, { opacity: 0 });

      // 淡入
      await gsap.to(next.container, {
        opacity: 1,
        duration: 0.5,
        ease: 'power2.inOut'
      });
    }
  }]
});

3. Crossfade Transition (Sync)

3. 交叉淡入淡出过渡(同步)

Simultaneous fade between pages:
javascript
barba.init({
  transitions: [{
    name: 'crossfade',
    sync: true, // Enable sync mode
    leave({ current }) {
      return gsap.to(current.container, {
        opacity: 0,
        duration: 0.8,
        ease: 'power2.inOut'
      });
    },
    enter({ next }) {
      return gsap.from(next.container, {
        opacity: 0,
        duration: 0.8,
        ease: 'power2.inOut'
      });
    }
  }]
});
页面之间同时进行淡入淡出的效果:
javascript
barba.init({
  transitions: [{
    name: 'crossfade',
    sync: true, // 启用同步模式
    leave({ current }) {
      return gsap.to(current.container, {
        opacity: 0,
        duration: 0.8,
        ease: 'power2.inOut'
      });
    },
    enter({ next }) {
      return gsap.from(next.container, {
        opacity: 0,
        duration: 0.8,
        ease: 'power2.inOut'
      });
    }
  }]
});

4. Slide Transition with Overlap

4. 带重叠效果的滑动过渡

Slide old page out, new page in with overlap:
javascript
barba.init({
  transitions: [{
    name: 'slide',
    sync: true,
    leave({ current }) {
      return gsap.to(current.container, {
        x: '-100%',
        duration: 0.7,
        ease: 'power3.inOut'
      });
    },
    enter({ next }) {
      // Start off-screen right
      gsap.set(next.container, { x: '100%' });

      // Slide in from right
      return gsap.to(next.container, {
        x: '0%',
        duration: 0.7,
        ease: 'power3.inOut'
      });
    }
  }]
});
旧页面滑出、新页面滑入并带有重叠效果:
javascript
barba.init({
  transitions: [{
    name: 'slide',
    sync: true,
    leave({ current }) {
      return gsap.to(current.container, {
        x: '-100%',
        duration: 0.7,
        ease: 'power3.inOut'
      });
    },
    enter({ next }) {
      // 初始状态设为屏幕右侧外
      gsap.set(next.container, { x: '100%' });

      // 从右侧滑入
      return gsap.to(next.container, {
        x: '0%',
        duration: 0.7,
        ease: 'power3.inOut'
      });
    }
  }]
});

5. Transition Rules (Conditional Transitions)

5. 过渡规则(条件过渡)

Define different transitions based on navigation context:
javascript
barba.init({
  transitions: [
    // Home to any page: fade
    {
      name: 'from-home-fade',
      from: { namespace: 'home' },
      leave({ current }) {
        return gsap.to(current.container, {
          opacity: 0,
          duration: 0.5
        });
      },
      enter({ next }) {
        return gsap.from(next.container, {
          opacity: 0,
          duration: 0.5
        });
      }
    },
    // Product to product: slide left
    {
      name: 'product-to-product',
      from: { namespace: 'product' },
      to: { namespace: 'product' },
      leave({ current }) {
        return gsap.to(current.container, {
          x: '-100%',
          duration: 0.6
        });
      },
      enter({ next }) {
        gsap.set(next.container, { x: '100%' });
        return gsap.to(next.container, {
          x: '0%',
          duration: 0.6
        });
      }
    },
    // Default fallback
    {
      name: 'default',
      leave({ current }) {
        return gsap.to(current.container, {
          opacity: 0,
          duration: 0.3
        });
      },
      enter({ next }) {
        return gsap.from(next.container, {
          opacity: 0,
          duration: 0.3
        });
      }
    }
  ]
});
根据导航上下文定义不同的过渡效果:
javascript
barba.init({
  transitions: [
    // 从首页到任意页面:淡入淡出
    {
      name: 'from-home-fade',
      from: { namespace: 'home' },
      leave({ current }) {
        return gsap.to(current.container, {
          opacity: 0,
          duration: 0.5
        });
      },
      enter({ next }) {
        return gsap.from(next.container, {
          opacity: 0,
          duration: 0.5
        });
      }
    },
    // 从产品页到产品页:向左滑动
    {
      name: 'product-to-product',
      from: { namespace: 'product' },
      to: { namespace: 'product' },
      leave({ current }) {
        return gsap.to(current.container, {
          x: '-100%',
          duration: 0.6
        });
      },
      enter({ next }) {
        gsap.set(next.container, { x: '100%' });
        return gsap.to(next.container, {
          x: '0%',
          duration: 0.6
        });
      }
    },
    // 默认回退过渡
    {
      name: 'default',
      leave({ current }) {
        return gsap.to(current.container, {
          opacity: 0,
          duration: 0.3
        });
      },
      enter({ next }) {
        return gsap.from(next.container, {
          opacity: 0,
          duration: 0.3
        });
      }
    }
  ]
});

6. Router Plugin for Route-Based Transitions

6. 路由插件(基于路由的过渡)

Use
@barba/router
for route-specific transitions:
Installation:
bash
npm install --save-dev @barba/router
Usage:
javascript
import barba from '@barba/core';
import barbaPrefetch from '@barba/prefetch';
import barbaRouter from '@barba/router';

// Define routes
barbaRouter.init({
  routes: [
    { path: '/', name: 'home' },
    { path: '/about', name: 'about' },
    { path: '/products/:id', name: 'product' }, // Dynamic segment
    { path: '/blog/:category/:slug', name: 'blog-post' }
  ]
});

barba.use(barbaRouter);
barba.use(barbaPrefetch); // Optional: prefetch on hover

barba.init({
  transitions: [{
    name: 'product-transition',
    to: { route: 'product' }, // Trigger on route name
    leave({ current }) {
      return gsap.to(current.container, {
        scale: 0.95,
        opacity: 0,
        duration: 0.5
      });
    },
    enter({ next }) {
      return gsap.from(next.container, {
        scale: 1.05,
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});
使用
@barba/router
实现基于路由的过渡效果:
安装:
bash
npm install --save-dev @barba/router
使用:
javascript
import barba from '@barba/core';
import barbaPrefetch from '@barba/prefetch';
import barbaRouter from '@barba/router';

// 定义路由
barbaRouter.init({
  routes: [
    { path: '/', name: 'home' },
    { path: '/about', name: 'about' },
    { path: '/products/:id', name: 'product' }, // 动态分段
    { path: '/blog/:category/:slug', name: 'blog-post' }
  ]
});

barba.use(barbaRouter);
barba.use(barbaPrefetch); // 可选:悬停时预加载

barba.init({
  transitions: [{
    name: 'product-transition',
    to: { route: 'product' }, // 根据路由名称触发
    leave({ current }) {
      return gsap.to(current.container, {
        scale: 0.95,
        opacity: 0,
        duration: 0.5
      });
    },
    enter({ next }) {
      return gsap.from(next.container, {
        scale: 1.05,
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});

7. Loading Indicator

7. 加载指示器

Show loading state during page fetch:
javascript
barba.init({
  transitions: [{
    async leave({ current }) {
      // Show loader
      const loader = document.querySelector('.loader');
      gsap.set(loader, { display: 'flex', opacity: 0 });
      gsap.to(loader, { opacity: 1, duration: 0.3 });

      // Fade out page
      await gsap.to(current.container, {
        opacity: 0,
        duration: 0.5
      });
    },
    async enter({ next }) {
      // Hide loader
      const loader = document.querySelector('.loader');
      await gsap.to(loader, { opacity: 0, duration: 0.3 });
      gsap.set(loader, { display: 'none' });

      // Fade in page
      await gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});
在页面获取过程中显示加载状态:
javascript
barba.init({
  transitions: [{
    async leave({ current }) {
      // 显示加载器
      const loader = document.querySelector('.loader');
      gsap.set(loader, { display: 'flex', opacity: 0 });
      gsap.to(loader, { opacity: 1, duration: 0.3 });

      // 页面淡出
      await gsap.to(current.container, {
        opacity: 0,
        duration: 0.5
      });
    },
    async enter({ next }) {
      // 隐藏加载器
      const loader = document.querySelector('.loader');
      await gsap.to(loader, { opacity: 0, duration: 0.3 });
      gsap.set(loader, { display: 'none' });

      // 页面淡入
      await gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });
    }
  }]
});

Integration Patterns

集成模式

GSAP Integration

GSAP集成

Barba.js works seamlessly with GSAP for animations:
Timeline-Based Transitions:
javascript
import barba from '@barba/core';
import gsap from 'gsap';

barba.init({
  transitions: [{
    async leave({ current }) {
      const tl = gsap.timeline();

      tl.to(current.container.querySelector('h1'), {
        y: -50,
        opacity: 0,
        duration: 0.3
      })
      .to(current.container.querySelector('.content'), {
        y: -30,
        opacity: 0,
        duration: 0.3
      }, '-=0.2')
      .to(current.container, {
        opacity: 0,
        duration: 0.2
      });

      await tl.play();
    },
    async enter({ next }) {
      const tl = gsap.timeline();

      // Set initial states
      gsap.set(next.container, { opacity: 0 });
      gsap.set(next.container.querySelector('h1'), { y: 50, opacity: 0 });
      gsap.set(next.container.querySelector('.content'), { y: 30, opacity: 0 });

      tl.to(next.container, {
        opacity: 1,
        duration: 0.2
      })
      .to(next.container.querySelector('h1'), {
        y: 0,
        opacity: 1,
        duration: 0.5,
        ease: 'power3.out'
      })
      .to(next.container.querySelector('.content'), {
        y: 0,
        opacity: 1,
        duration: 0.5,
        ease: 'power3.out'
      }, '-=0.3');

      await tl.play();
    }
  }]
});
Reference gsap-scrolltrigger skill for advanced GSAP integration patterns.
Barba.js可与GSAP无缝配合实现动画效果:
基于时间轴的过渡:
javascript
import barba from '@barba/core';
import gsap from 'gsap';

barba.init({
  transitions: [{
    async leave({ current }) {
      const tl = gsap.timeline();

      tl.to(current.container.querySelector('h1'), {
        y: -50,
        opacity: 0,
        duration: 0.3
      })
      .to(current.container.querySelector('.content'), {
        y: -30,
        opacity: 0,
        duration: 0.3
      }, '-=0.2')
      .to(current.container, {
        opacity: 0,
        duration: 0.2
      });

      await tl.play();
    },
    async enter({ next }) {
      const tl = gsap.timeline();

      // 设置初始状态
      gsap.set(next.container, { opacity: 0 });
      gsap.set(next.container.querySelector('h1'), { y: 50, opacity: 0 });
      gsap.set(next.container.querySelector('.content'), { y: 30, opacity: 0 });

      tl.to(next.container, {
        opacity: 1,
        duration: 0.2
      })
      .to(next.container.querySelector('h1'), {
        y: 0,
        opacity: 1,
        duration: 0.5,
        ease: 'power3.out'
      })
      .to(next.container.querySelector('.content'), {
        y: 0,
        opacity: 1,
        duration: 0.5,
        ease: 'power3.out'
      }, '-=0.3');

      await tl.play();
    }
  }]
});
参考gsap-scrolltrigger技能获取更高级的GSAP集成模式。

View-Specific Initialization

基于视图的初始化

Initialize libraries or scripts per page:
javascript
barba.init({
  views: [
    {
      namespace: 'home',
      afterEnter() {
        // Initialize home page features
        initHomepageSlider();
        initParallaxEffects();
      },
      beforeLeave() {
        // Clean up
        destroyHomepageSlider();
      }
    },
    {
      namespace: 'gallery',
      afterEnter() {
        initLightbox();
        initMasonry();
      },
      beforeLeave() {
        destroyLightbox();
      }
    }
  ]
});
按页面初始化库或脚本:
javascript
barba.init({
  views: [
    {
      namespace: 'home',
      afterEnter() {
        // 初始化首页功能
        initHomepageSlider();
        initParallaxEffects();
      },
      beforeLeave() {
        // 清理
        destroyHomepageSlider();
      }
    },
    {
      namespace: 'gallery',
      afterEnter() {
        initLightbox();
        initMasonry();
      },
      beforeLeave() {
        destroyLightbox();
      }
    }
  ]
});

Analytics Tracking

分析跟踪

Track page views on navigation:
javascript
barba.hooks.after(() => {
  // Google Analytics
  if (typeof gtag !== 'undefined') {
    gtag('config', 'GA_MEASUREMENT_ID', {
      page_path: window.location.pathname
    });
  }

  // Or use data layer
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'pageview',
    page: window.location.pathname
  });
});
在导航时跟踪页面浏览量:
javascript
barba.hooks.after(() => {
  // Google Analytics
  if (typeof gtag !== 'undefined') {
    gtag('config', 'GA_MEASUREMENT_ID', {
      page_path: window.location.pathname
    });
  }

  // 或使用数据层
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'pageview',
    page: window.location.pathname
  });
});

Third-Party Script Re-Initialization

第三方脚本重新初始化

Re-run scripts after page transitions:
javascript
barba.hooks.after(() => {
  // Re-initialize third-party widgets
  if (typeof twttr !== 'undefined') {
    twttr.widgets.load(); // Twitter widgets
  }

  if (typeof FB !== 'undefined') {
    FB.XFBML.parse(); // Facebook widgets
  }

  // Re-run syntax highlighting
  if (typeof Prism !== 'undefined') {
    Prism.highlightAll();
  }
});
页面过渡后重新运行脚本:
javascript
barba.hooks.after(() => {
  // 重新初始化第三方小部件
  if (typeof twttr !== 'undefined') {
    twttr.widgets.load(); // Twitter小部件
  }

  if (typeof FB !== 'undefined') {
    FB.XFBML.parse(); // Facebook小部件
  }

  // 重新运行语法高亮
  if (typeof Prism !== 'undefined') {
    Prism.highlightAll();
  }
});

Performance Optimization

性能优化

1. Prefetching

1. 预加载

Use
@barba/prefetch
to load pages on hover:
bash
npm install --save-dev @barba/prefetch
javascript
import barba from '@barba/core';
import barbaPrefetch from '@barba/prefetch';

barba.use(barbaPrefetch);

barba.init({
  // Prefetch fires on link hover by default
  prefetch: {
    root: null, // Observe all links
    timeout: 3000 // Cache timeout in ms
  }
});
使用
@barba/prefetch
在鼠标悬停时加载页面:
bash
npm install --save-dev @barba/prefetch
javascript
import barba from '@barba/core';
import barbaPrefetch from '@barba/prefetch';

barba.use(barbaPrefetch);

barba.init({
  // 默认在链接悬停时触发预加载
  prefetch: {
    root: null, // 监听所有链接
    timeout: 3000 // 缓存超时时间(毫秒)
  }
});

2. Prevent Layout Shift

2. 防止布局偏移

Set container min-height to prevent content jump:
css
[data-barba="container"] {
  min-height: 100vh;
  /* Or use viewport height minus header/footer */
  min-height: calc(100vh - 80px - 60px);
}
设置容器最小高度以避免内容跳动:
css
[data-barba="container"] {
  min-height: 100vh;
  // 或使用视口高度减去页眉/页脚高度
  min-height: calc(100vh - 80px - 60px);
}

3. Optimize Animations

3. 优化动画

Use GPU-accelerated properties:
javascript
// ✅ Good - GPU accelerated
gsap.to(element, {
  opacity: 0,
  x: -100,
  scale: 0.9,
  rotation: 45
});

// ❌ Avoid - causes reflow/repaint
gsap.to(element, {
  width: '50%',
  height: '300px',
  top: '100px'
});
使用GPU加速属性:
javascript
// ✅ 推荐 - GPU加速
gsap.to(element, {
  opacity: 0,
  x: -100,
  scale: 0.9,
  rotation: 45
});

// ❌ 避免 - 会导致重排/重绘
gsap.to(element, {
  width: '50%',
  height: '300px',
  top: '100px'
});

4. Clean Up Event Listeners

4. 清理事件监听器

Remove listeners in
beforeLeave
or view hooks:
javascript
barba.init({
  views: [{
    namespace: 'home',
    afterEnter() {
      // Add listeners
      this.clickHandler = () => console.log('clicked');
      document.querySelector('.btn').addEventListener('click', this.clickHandler);
    },
    beforeLeave() {
      // Remove listeners
      document.querySelector('.btn').removeEventListener('click', this.clickHandler);
    }
  }]
});
beforeLeave
或视图钩子中移除监听器:
javascript
barba.init({
  views: [{
    namespace: 'home',
    afterEnter() {
      // 添加监听器
      this.clickHandler = () => console.log('clicked');
      document.querySelector('.btn').addEventListener('click', this.clickHandler);
    },
    beforeLeave() {
      // 移除监听器
      document.querySelector('.btn').removeEventListener('click', this.clickHandler);
    }
  }]
});

5. Lazy Load Images

5. 图片懒加载

Defer image loading until after transition:
javascript
barba.init({
  transitions: [{
    async enter({ next }) {
      // Complete transition first
      await gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });

      // Then load images
      const images = next.container.querySelectorAll('img[data-src]');
      images.forEach(img => {
        img.src = img.dataset.src;
        img.removeAttribute('data-src');
      });
    }
  }]
});
延迟加载图片直到过渡完成:
javascript
barba.init({
  transitions: [{
    async enter({ next }) {
      // 先完成过渡
      await gsap.from(next.container, {
        opacity: 0,
        duration: 0.5
      });

      // 然后加载图片
      const images = next.container.querySelectorAll('img[data-src]');
      images.forEach(img => {
        img.src = img.dataset.src;
        img.removeAttribute('data-src');
      });
    }
  }]
});

Common Pitfalls

常见陷阱

1. Forgetting to Return Promises

1. 忘记返回Promise

Problem: Transitions complete instantly without waiting for animations.
Solution: Always return promises or use
async/await
:
javascript
// ❌ Wrong - animation starts but doesn't wait
leave({ current }) {
  gsap.to(current.container, { opacity: 0, duration: 0.5 });
}

// ✅ Correct - returns promise
leave({ current }) {
  return gsap.to(current.container, { opacity: 0, duration: 0.5 });
}

// ✅ Also correct - async/await
async leave({ current }) {
  await gsap.to(current.container, { opacity: 0, duration: 0.5 });
}
问题: 过渡会立即完成,不会等待动画结束。
解决方案: 始终返回Promise或使用
async/await
javascript
// ❌ 错误 - 动画启动但不会等待
leave({ current }) {
  gsap.to(current.container, { opacity: 0, duration: 0.5 });
}

// ✅ 正确 - 返回Promise
leave({ current }) {
  return gsap.to(current.container, { opacity: 0, duration: 0.5 });
}

// ✅ 同样正确 - 使用async/await
async leave({ current }) {
  await gsap.to(current.container, { opacity: 0, duration: 0.5 });
}

2. Not Preventing Default Link Behavior

2. 未阻止链接默认行为

Problem: Some links cause full page reloads.
Solution: Barba automatically prevents default on internal links, but you may need to exclude external links:
javascript
barba.init({
  prevent: ({ href }) => {
    // Allow external links
    if (href.indexOf('http') > -1 && href.indexOf(window.location.host) === -1) {
      return true;
    }
    return false;
  }
});
问题: 部分链接会导致整页刷新。
解决方案: Barba会自动阻止内部链接的默认行为,但你可能需要排除外部链接:
javascript
barba.init({
  prevent: ({ href }) => {
    // 允许外部链接
    if (href.indexOf('http') > -1 && href.indexOf(window.location.host) === -1) {
      return true;
    }
    return false;
  }
});

3. CSS Conflicts Between Pages

3. 页面间CSS冲突

Problem: Old page CSS affects new page layout during transition.
Solution: Use namespace-specific CSS or reset styles:
css
/* Namespace-specific styles */
[data-barba-namespace="home"] .hero {
  background: blue;
}

[data-barba-namespace="about"] .hero {
  background: red;
}
Or reset in
beforeEnter
:
javascript
beforeEnter({ next }) {
  // Reset scroll position
  window.scrollTo(0, 0);

  // Reset any global state
  document.body.classList.remove('menu-open');
}
问题: 旧页面的CSS在过渡期间影响新页面布局。
解决方案: 使用Namespace专属CSS或重置样式:
css
/* Namespace专属样式 */
[data-barba-namespace="home"] .hero {
  background: blue;
}

[data-barba-namespace="about"] .hero {
  background: red;
}
或在
beforeEnter
中重置:
javascript
beforeEnter({ next }) {
  // 重置滚动位置
  window.scrollTo(0, 0);

  // 重置全局状态
  document.body.classList.remove('menu-open');
}

4. Not Updating Document Title and Meta Tags

4. 未更新文档标题和元标签

Problem: Page title and meta tags don't update on navigation.
Solution: Use
@barba/head
plugin or update manually:
bash
npm install --save-dev @barba/head
javascript
import barba from '@barba/core';
import barbaHead from '@barba/head';

barba.use(barbaHead);

barba.init({
  // Head plugin automatically updates <head> tags
});
Or manually:
javascript
barba.hooks.after(({ next }) => {
  // Update title
  document.title = next.html.querySelector('title').textContent;

  // Update meta tags
  const newMeta = next.html.querySelectorAll('meta');
  newMeta.forEach(meta => {
    const name = meta.getAttribute('name') || meta.getAttribute('property');
    if (name) {
      const existing = document.querySelector(`meta[name="${name}"], meta[property="${name}"]`);
      if (existing) {
        existing.setAttribute('content', meta.getAttribute('content'));
      }
    }
  });
});
问题: 导航时页面标题和元标签不会更新。
解决方案: 使用
@barba/head
插件或手动更新:
bash
npm install --save-dev @barba/head
javascript
import barba from '@barba/core';
import barbaHead from '@barba/head';

barba.use(barbaHead);

barba.init({
  // Head插件会自动更新<head>标签
});
或手动更新:
javascript
barba.hooks.after(({ next }) => {
  // 更新标题
  document.title = next.html.querySelector('title').textContent;

  // 更新元标签
  const newMeta = next.html.querySelectorAll('meta');
  newMeta.forEach(meta => {
    const name = meta.getAttribute('name') || meta.getAttribute('property');
    if (name) {
      const existing = document.querySelector(`meta[name="${name}"], meta[property="${name}"]`);
      if (existing) {
        existing.setAttribute('content', meta.getAttribute('content'));
      }
    }
  });
});

5. Animation Flicker on Enter

5. 进入动画闪烁

Problem: New page flashes visible before enter animation starts.
Solution: Set initial invisible state in CSS or
beforeEnter
:
css
/* CSS approach */
[data-barba="container"] {
  opacity: 0;
}

[data-barba="container"].is-visible {
  opacity: 1;
}
javascript
// JavaScript approach
beforeEnter({ next }) {
  gsap.set(next.container, { opacity: 0 });
}
问题: 新页面在进入动画开始前会短暂闪烁可见。
解决方案: 在CSS或
beforeEnter
中设置初始不可见状态:
css
/* CSS方式 */
[data-barba="container"] {
  opacity: 0;
}

[data-barba="container"].is-visible {
  opacity: 1;
}
javascript
// JavaScript方式
beforeEnter({ next }) {
  gsap.set(next.container, { opacity: 0 });
}

6. Sync Transitions Without Proper Positioning

6. 同步过渡未正确定位

Problem: Sync transitions cause layout shift as containers stack.
Solution: Position containers absolutely during transition:
css
[data-barba="wrapper"] {
  position: relative;
}

[data-barba="container"] {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}
Or manage in JavaScript:
javascript
barba.init({
  transitions: [{
    sync: true,
    beforeLeave({ current }) {
      gsap.set(current.container, {
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100%'
      });
    }
  }]
});
问题: 同步过渡时容器堆叠会导致布局偏移。
解决方案: 过渡期间将容器设为绝对定位:
css
[data-barba="wrapper"] {
  position: relative;
}

[data-barba="container"] {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}
或在JavaScript中管理:
javascript
barba.init({
  transitions: [{
    sync: true,
    beforeLeave({ current }) {
      gsap.set(current.container, {
        position: 'absolute',
        top: '0',
        left: '0',
        width: '100%'
      });
    }
  }]
});

Resources

资源

This skill includes:
本技能包含:

scripts/

scripts/

Executable utilities for common Barba.js tasks:
  • transition_generator.py
    - Generate transition boilerplate code
  • project_setup.py
    - Initialize Barba.js project structure
用于Barba.js常见任务的可执行工具:
  • transition_generator.py
    - 生成过渡模板代码
  • project_setup.py
    - 初始化Barba.js项目结构

references/

references/

Detailed documentation:
  • api_reference.md
    - Complete Barba.js API (hooks, transitions, views, router)
  • hooks_guide.md
    - All 11 hooks with execution order and use cases
  • gsap_integration.md
    - GSAP animation patterns for Barba transitions
  • transition_patterns.md
    - Common transition implementations
详细文档:
  • api_reference.md
    - 完整的Barba.js API(钩子、过渡、视图、路由)
  • hooks_guide.md
    - 全部11个钩子的执行顺序和使用场景
  • gsap_integration.md
    - 适用于Barba过渡的GSAP动画模式
  • transition_patterns.md
    - 常见过渡实现方案

assets/

assets/

Templates and starter projects:
  • starter_barba/
    - Complete Barba.js + GSAP starter template
  • examples/
    - Real-world transition implementations
模板和启动项目:
  • starter_barba/
    - 完整的Barba.js + GSAP启动模板
  • examples/
    - 真实场景下的过渡实现

Related Skills

相关技能

  • gsap-scrolltrigger - For advanced GSAP animations in transitions
  • locomotive-scroll - Can be combined with Barba for smooth scrolling between pages
  • motion-framer - Alternative approach for React-based page transitions
  • gsap-scrolltrigger - 用于过渡中的高级GSAP动画
  • locomotive-scroll - 可与Barba配合实现页面间的顺滑滚动
  • motion-framer - React项目页面过渡的替代方案