在 Bricks Facebook 群里,有用户提问:
在构建器的颜色弹窗里,我很想把色板选择器(color palette selector)从弹窗底部挪到顶部——放在那里对我来说合理得多……
Update
正如 Maxime 在这个帖子里指出的,这个需求根本不需要 JS——直接用 CSS 的 order 属性就能实现。
虽然下面的 JS 方案对这个任务来说不是必需的,但当你要实现“只有 MutationObserver 才能做到的事情”时,它仍是一个很方便的参考。
本教程展示如何用 MutationObserver 接口监听 DOM 树的变化:当带 data-control 属性且值为 color 的 div 被插入 DOM(也就是在 Bricks 编辑器里打开颜色选择器)时,执行 JavaScript。
之前
之后
Step 1
如果 Bricks 子主题还没启用,先安装并激活它。
在子主题目录里创建 assets 目录,再在里面创建 js 目录。
在上面的目录里创建一个名为 builder.js 的文件,内容如下:
document.addEventListener("DOMContentLoaded", () => {
// Select the node that will be observed for mutations
const targetNode = document.querySelector("#bricks-panel")
// Options for the observer (which mutations to observe)
const config = { childList: true, subtree: true }
// childList: Set to true to monitor the target node (and, if subtree is true, its descendants) for the addition of new child nodes or removal of existing child nodes. The default value is false.
// subtree: Set to true to extend monitoring to the entire subtree of nodes rooted at target. All of the other properties are then extended to all of the nodes in the subtree instead of applying solely to the target node. The default value is false.
// Callback function to execute when mutations are observed
const callback = (mutationList, observer) => {
for (const mutation of mutationList) {
// console.log(mutation.target)
if (
mutation.target.hasAttribute("data-control") &&
mutation.target.getAttribute("data-control") === "color"
) {
const colorPaletteSelector = document.querySelector(
".color-palette-selector"
)
if (colorPaletteSelector) {
const colorPaletteSelectorParent = colorPaletteSelector.parentElement
colorPaletteSelectorParent.prepend(colorPaletteSelector)
}
}
}
}
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback)
// Start observing the target node for configured mutations
observer.observe(targetNode, config)
// Create style tag and append to head
document.head.appendChild(document.createElement("style")).innerHTML = `
[data-control=color] .bricks-control-popup .color-modes {
margin-bottom: 0;
}
[data-control=color] .bricks-control-popup .color-palette-selector {
margin-bottom: 30px;
}
`
})
Step 2
编辑子主题的 functions.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() ) {
wp_enqueue_style( 'bricks-child', get_stylesheet_uri(), ['bricks-frontend'], filemtime( get_stylesheet_directory() . '/style.css' ) );
}
} );
改成
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() ) {
wp_enqueue_style( 'bricks-child', get_stylesheet_uri(), ['bricks-frontend'], filemtime( get_stylesheet_directory() . '/style.css' ) );
} else {
wp_enqueue_script( 'builder', get_stylesheet_directory_uri() . '/assets/js/builder.js', [], '1.0.0', true );
}
} );
感谢 cmstew 和 portseif 提供了本教程所基于的 JS 代码。
💡 译者注:只是想把色板选择器挪到弹窗顶部的话,优先用作者 Update 里说的 CSS
order属性方案,零 JS 成本;MutationObserver 方案的真正价值在于提供了一种“监听某个元素被插入 DOM 后再执行 JS”的可复用模式,比如编辑器面板里的其他自定义增强。