tl;dr 看见standalone example plugin 这演示了在选择性刷新请求将不同的脚本或样式排入队列时启动完全刷新,以及为选择性刷新的部分放置容器重新初始化JS行为。
我理解,目标是最大限度地减少自定义程序中所需的逻辑量,以预览对更新的分区的更改,这些分区根据设置更改将不同的脚本和样式排队。这里的解决方案已在定制器中的选择性刷新设计中考虑在内。特别是,当呈现分部时,它会在显示该分部的URL的上下文中进行呈现。这意味着在呈现部分时,为给定URL排队的所有脚本和样式都应该排队。为此customize_render_partials_before
操作包含以下文档:
Fires immediately before partials are rendered.
插件可以执行调用等操作
wp_enqueue_scripts()
并收集可能在响应中排队的脚本和样式列表。
最终core可能会继续wp_enqueue_scripts()
默认情况下为自身。然而,对于选择性刷新的初始实现,排队是留给插件的。
脚本和样式排队后,需要与页面中的JS通信哪些资产已在响应中排队。这就是customize_render_partials_response
过滤器用于,如其文档所示:
Filters the response from rendering the partials.
插件可以使用此过滤器注入
$scripts
和
$styles
, 它们是所呈现部分的依赖项。响应数据将通过
render-partials-response
JS事件,这样客户端就可以将脚本和样式插入DOM中,如果它们还没有在DOM中排队的话。
如果插件做到了这一点,那么它们需要处理任何这样做的脚本document.write()
并确保这些未被注入,否则将函数重写为no op,否则页面将被销毁。
插件应该知道$scripts
和$styles
最终可能默认包含在响应中。
已筛选的$response
数组通过render-partials-response
事件触发时间wp.customize.selectiveRefresh
. 因此,要在选择性刷新请求将页面上尚未存在的资产排入队列时启动完全刷新,需要首先导出用于初始页面加载的已排入队列的脚本和样式的句柄,然后在render-partials-response
JS事件检查在选择性刷新请求期间排队的脚本和样式句柄是否与最初在页面上排队的脚本和样式句柄相同。如果它们不同,那么JS只需要调用wp.customize.selectiveRefresh.requestFullRefresh()
. 以下JS将仅在customizer预览中排队:
/* global wp, _ */
/* exported WPSE_247251 */
var WPSE_247251 = (function( api ) {
var component = {
data: {
enqueued_styles: {},
enqueued_scripts: {}
}
};
/**
* Init.
*
* @param {object} data Data exported from PHP.
* @returns {void}
*/
component.init = function init( data ) {
if ( data ) {
_.extend( component.data, data );
}
api.selectiveRefresh.bind( \'render-partials-response\', component.handleRenderPartialsResponse );
};
/**
* Handle render-partials-response event, requesting full refresh if newly-enqueued styles/styles differ.
*
* @param {object} response Response.
* @returns {void}
*/
component.handleRenderPartialsResponse = function handleRenderPartialsResponse( response ) {
if ( ! response.wpse_247251 ) {
return;
}
if ( ! _.isEqual( component.data.enqueued_styles, response.wpse_247251.enqueued_styles ) ) {
api.selectiveRefresh.requestFullRefresh();
}
if ( ! _.isEqual( component.data.enqueued_scripts, response.wpse_247251.enqueued_scripts ) ) {
api.selectiveRefresh.requestFullRefresh();
}
};
return component;
})( wp.customize );
可以在PHP中添加内联脚本以导出
enqueued_scripts
和
enqueued_styles
然后呼叫
WPSE_247251.init( data )
.
当有选择地刷新部分时,需要更多的操作来确保重新初始化与容器关联的任何JS行为。具体地说,应该设计JS,以便有一个函数负责查找要在DOM中设置的元素。默认情况下,此函数应查看整个body
. 但是,JS可以检查它是否在customizer预览的上下文中运行,如果是,请侦听partial-content-rendered
事件触发时间wp.customize.selectiveRefresh
然后调用传入的函数placement.container
作为初始化的范围,而不是整个body
:
if ( \'undefined\' !== typeof wp && \'undefined\' !== typeof wp.customize && \'undefined\' !== typeof wp.customize.selectiveRefresh ) {
wp.customize.selectiveRefresh.bind( \'partial-content-rendered\', function( placement ) {
initializeAllElements( $( placement.container ) );
} );
}
再次,请参见
standalone example plugin 这演示了在选择性刷新请求将不同的脚本或样式排入队列时启动完全刷新,以及为选择性刷新的部分放置容器重新初始化JS行为。
最后,如果WordPress主题可以用React之类的东西实现,那么我们可以避免添加对页面上选择性刷新元素的特殊支持,因为状态的更改会自动导致DOM中所需的更改。由于我们还没有做到这一点(尽管正在为此开发原型),我们必须满足于下一个最佳体验,即以开发人员最小的额外努力快速刷新页面的各个部分:选择性刷新。