“目录”
-
text: “环境要求”
-
text: “JavaScript”
-
text: “加载脚本”
-
text: “HTML 代码”
-
text: “结论”
— 本教程提供可直接粘贴的 PHP 与 JS 代码,让你在 Bricks Builder 里用 RoughNotation 库实现「滚动到元素时触发手绘风格标注动画」——高亮、下划线、方框、圆圈、删除线等效果。 ## 目录 - 环境要求
-
结论 ## 环境要求 - Bricks 主题(任意版本)
-
已激活 Bricks 子主题 ## JavaScript 首先在子主题里创建
init.js文件。本例在子主题的/js/文件夹下创建了roughNotation_init.js,内容如下:javascript import { annotate } from 'https://unpkg.com/rough-notation?module'; window.addEventListener('load', () =>{ const annotations = { 'highlight-1': { type: 'highlight', color: '#fcc2d2', iterations: 4, multiline: true, animate: true }, 'highlight-2': { type: 'highlight', color: 'orange', iterations: 4, multiline: true, animate: true }, 'underline': { type: 'underline', color: 'yellow', iterations: 4, multiline: true, animate: true }, 'box': { type: 'box', color: 'purple', iterations: 2, multiline: true, animate: true }, 'circle': { type: 'circle', color: 'green', iterations: 1, multiline: true, animate: true }, 'strike-through': { type: 'strike-through', color: 'red', iterations: 1, multiline: true, animate: true }, 'crossed-off': { type: 'crossed-off', color: 'black', iterations: 2, multiline: true, animate: true }, 'bracket': { type: 'bracket', brackets: ['left','right'], color: 'blue', iterations: 2, multiline: true, animate: true }, }; // Set the variables var iOSupported = "IntersectionObserver" in window; /* true if supported */ var box = document.querySelectorAll('.notation'); // Check if IntersectionObserver is supported by the browser if (!iOSupported) { return; } // Set the config options const config = { root: null, // sets the framing element to the viewport rootMargin: '0% 0% -25% 0%', // the animation will be triggered when at 25% from the bottom of the viewport threshold: 0 }; // Init the observer let observer = new IntersectionObserver((entries) => { entries.forEach((item) => { let annotationType = item.target.dataset.notationType; let annotation = annotate(item.target, annotations[annotationType]); if (item.isIntersecting) { // Show the annotation when intersecting and stop observing after it. annotation.show(); observer.unobserve(item.target); } else { // Add an action when the target is not intersecting anymore. } }); }, config); box.forEach((item) => { observer.observe(item); }); })脚本分两个部分: 第一部分是定义动画样式对象的annotations常量——每种标注类型可配置type、color、iterations、padding等大量选项,完整选项列表见作者的项目主页。为了演示全部标注类型,示例定义了以下动画:javascript const annotations = { 'highlight-1': { type: 'highlight', color: '#fcc2d2', iterations: 4, multiline: true, animate: true }, 'highlight-2': { type: 'highlight', color: 'orange', iterations: 4, multiline: true, animate: true }, 'underline': { type: 'underline', color: 'yellow', iterations: 4, multiline: true, animate: true }, 'box': { type: 'box', color: 'purple', iterations: 2, multiline: true, animate: true }, 'circle': { type: 'circle', color: 'green', iterations: 1, multiline: true, animate: true }, 'strike-through': { type: 'strike-through', color: 'red', iterations: 1, multiline: true, animate: true }, 'crossed-off': { type: 'crossed-off', color: 'black', iterations: 2, multiline: true, animate: true }, 'bracket': { type: 'bracket', brackets: ['left','right'], color: 'blue', iterations: 2, multiline: true, animate: true }, };第二部分负责滚动触发动画,用的是IntersectionObserverAPI,非常轻量(方法同这篇教程):javascript // Set the variables var iOSupported = "IntersectionObserver" in window; /* true if supported */ var box = document.querySelectorAll('.notation'); // Check if IntersectionObserver is supported by the browser if (!iOSupported) { return; } // Set the config options const config = { root: null, // sets the framing element to the viewport rootMargin: '0% 0% -25% 0%', // the animation will be triggered when at 25% from the bottom of the viewport threshold: 0 }; // Init the observer let observer = new IntersectionObserver((entries) => { entries.forEach((item) => { let annotationType = item.target.dataset.notationType; let annotation = annotate(item.target, annotations[annotationType]); if (item.isIntersecting) { // Show the annotation when intersecting and stop observing after it. annotation.show(); observer.unobserve(item.target); } else { // Add an action when the target is not intersecting anymore. } }); }, config); box.forEach((item) => { observer.observe(item); });配置里rootMargin: '0% 0% -25% 0%'表示元素进入视口底部 25% 区域时才触发动画。 ## 加载脚本 RoughNotation 库走的是 JavaScript ES module,所以加载方式比常规脚本略特殊——需要给<script>标签加上type="module"。把下面代码粘贴到子主题的functions.php:php add_action( 'wp_enqueue_scripts', function() { // Enqueue your files on the canvas & frontend, not the builder panel. Otherwise custom CSS might affect builder) if ( ! bricks_is_builder_main() && class_exists( 'ACF' ) ) { // Rough Notation if ( get_field( 'activate_roughnotationjs' ) ) { wp_enqueue_script( 'roughNotation_init', get_stylesheet_directory_uri() . '/js/roughNotation_init.js', array(), filemtime( get_stylesheet_directory() . '/js/roughNotation_init.js' ) ); } } }); // Add type="module" to our script tag function add_type_attribute( $tag, $handle, $src ) { // if not your script, do nothing and return original $tag if ( 'roughNotation_init' !== $handle ) { return $tag; } // change the script tag by adding type="module" and return it. $tag = '<script type="module" src="' . esc_url( $src ) . '"></script>'; return $tag; } add_filter( 'script_loader_tag', 'add_type_attribute' , 10, 3 );> 💡 译者注:原文此处爬取文本里混入了 markdown 链接残留(class_exists( 'ACF' )),已按实际用途修正为class_exists( 'ACF' )。 这里还用了一个 ACF 字段(activate_roughnotationjs)按页控制是否加载脚本,方法见这篇教程。 ## HTML 代码 通常我们只想标注标题(Heading)、基础文本(Basic)或富文本(Rich)元素里的部分文字。做法:把目标文字包进<span>标签,加上触发滚动动画的类,并指定要运行的动画类型。下面是对标题应用高亮效果的示例:html I am an awesome <span class="notation" data-notation-type="highlight-1">heading</span>-.notation类负责让 IntersectionObserver 脚本盯住这个元素; -
data-notation-type="highlight-1"属性告诉脚本使用前面annotations常量中定义的highlight-1配置。 如果打算标注整个元素而不是其中一部分,就不需要包<span>——直接用 Bricks 内置字段给元素添加.notation类和data-notation-type属性即可。 > 相关阅读:
结论 一切正常的话,前端效果就是滚动到标注文字时出现手绘风格的涂抹高亮动画。祝标注愉快,下篇教程见!
常见误区与性能提示
几个坑:一是给大段正文都加手绘标注,滚动时满屏涂抹线,反而干扰阅读;二是没尊重 prefers-reduced-motion,晕动症用户不适,加媒体查询关掉;三是 RoughNotation 库没做按需加载,每页都引,浪费请求。它适合点缀标题、关键词这类少量重点,别当全文高亮笔用;标注元素少、只在关键句上用,才是正确打开方式。
延伸阅读
- 想要现成外贸独立站,从零搭出能收询盘的站?看 铲子铺 chanzipu 的外贸建站教程(同用 Bricks)
常见问题(FAQ)
RoughNotation 要引库吗? 要,在页面加载 RoughNotation 库(CDN 或本地),Bricks 本身不带。
标注太多会怎样? 满屏涂抹线干扰阅读,适合只点缀标题/关键词,别全文高亮。
怎么照顾晕动症用户? 用 @media (prefers-reduced-motion: reduce) 在开启减弱动效时关闭标注动画。
每页都引库浪费吗? 按需加载,只在用了标注的页面引,别全站无差别加载。
- 相关阅读:Bricks Setup Guide
延伸阅读
Bricks 内容切换器:纯 CSS 方案(radio + :has 实现标签切换)
实战技巧:Bricks 内容切换器:纯 CSS 方案(radio + :has 实现标签切换)——css 实操步骤+踩坑提醒,适合外贸独立站与 WordPress 开发者。
tips零代码:ACF Repeater 子字段值做成 Bricks Tabs 标签页
实战技巧:零代码:ACF Repeater 子字段值做成 Bricks Tabs 标签页——acf 实操步骤+踩坑提醒,适合外贸独立站与 WordPress 开发者。
tipsBricks Tabs 自动轮播:滚动到可视区后自动切换标签页
实战技巧:Bricks Tabs 自动轮播:滚动到可视区后自动切换标签页——tabs 实操步骤+踩坑提醒,适合外贸独立站与 WordPress 开发者。
tips手风琴展开项自动滚动到可视区(解决内容跳动问题)
实战技巧:手风琴展开项自动滚动到可视区(解决内容跳动问题)——accordion 实操步骤+踩坑提醒,适合外贸独立站与 WordPress 开发者。
