如何在块编辑器中加载块的附加脚本?

时间:2021-07-03 作者:leemon

我正在开发一个动态块,它使用ServerSideRender 组件:

<div class="accordion">
    <h3 class="accordion-title">A title</h3>
    <div class="accordion-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
</div>
要完全使用此块,需要Accordion 来自jQuery UI的组件:

accordion-jquery-start.js 文件:

( function( $ ) {

    $( function() {
        
        $( \'.accordion\' ).accordion( {
            header: \'h3\',
            heightStyle: \'content\',
            animate: 100,
            collapsible: true,
            active: false
        } );

    } );

} )( jQuery );
我正在使用以下方式注册动态块:

register_block_type( \'my/accordion-block\', array(
    \'style\'           => \'accordion-block-css\',
    \'editor_script\'   => \'accordion-block-js\',
    \'render_callback\' => \'render_block\',
);
要在块编辑器中加载上面显示的其他脚本,我使用enqueue_block_editor_assets 措施:

function my_enqueue_block_editor_assets() {
    wp_enqueue_script( \'accordion-jquery-start\', plugins_url( \'/assets/js/accordion-jquery-start.js\', __FILE__ ), array( \'jquery\', \'jquery-ui-accordion\', \'accordion-block-js\' ), false, true );
}
add_action( \'enqueue_block_editor_assets\', \'my_enqueue_block_editor_assets\' );
几乎所有的工作都正常:块被注册并打印正确的标记,所有需要的脚本和样式都被排队。但是,出于某种原因accordion jQuery UI中的函数未附加到.accordion 类,因此手风琴效果不起作用。但是,任何地方都没有控制台错误。看来accordion-jquery-start.js 脚本在块本身完全加载之前运行。

有什么想法吗?我应该加载accordion-jquery-start.js 脚本是否不同?

1 个回复
SO网友:Sally CJ

但是,出于某种原因accordion jQuery UI中的函数未附加到.accordion 类,因此手风琴效果不起作用。

这个ServerSideRender 组件使用RESTAPI获取动态块输出,因此出现上述问题,因为在DOM准备就绪时(即jQuery.ready()\'s回调运行),REST API AJAX调用尚未解析或甚至可能尚未启动,因此accordion div尚未连接到DOM。

我应该加载accordion-jquery-start.js 脚本是否不同?

是的,有点-ServerSideRender (尚未)提供;“加载内容时”;或“或”;关于AJAX完成/解决”;事件,因此您需要手动检查您的div是否已经在DOM中,如果已经在DOM中,请运行$( \'.accordion\' ).accordion().

在JS的现代世界中,一种简单的方法是使用MutationObserver API.

请查看MDN web文档(请参见上面的链接),以了解有关突变观察者API的更多详细信息,但对于Gutenberg或块编辑器以及动态块,这里有一个可以尝试学习的工作示例。:-)

所以在我的index.js 文件,我得到了这些:console.log() 只是为了调试的目的,所以以后不要忘记删除它们)

加载WordPress依赖项:

import { registerBlockType } from \'@wordpress/blocks\';
import { useRef, useLayoutEffect } from \'@wordpress/element\';
import { useBlockProps } from \'@wordpress/block-editor\';
import ServerSideRender from \'@wordpress/server-side-render\';
  • MutationObserver 回调:

    // This function checks if the accordion div has been attached to the DOM, and
    // if so, initializes jQuery accordion on that very div. So this function can be
    // placed at the top in your file (before you call registerBlockType()).
    function initAccordion( mutations ) {
        for ( let mutation of mutations ) {
            if ( \'childList\' === mutation.type && mutation.addedNodes[0] &&
                // Good, the added node has an accordion div.
                jQuery( \'.accordion\', mutation.addedNodes[0] ).length >= 1
            ) {
                // Convert the div to a jQuery accordion.
                jQuery( mutation.addedNodes[0] ).accordion( {
                    header: \'h3\',
                    heightStyle: \'content\',
                    animate: 100,
                    collapsible: true,
                    active: false
                } );
                console.log( \'accordion initialized\' );
            }
        }
    }
    

    registerBlockType( \'my/accordion-block\', {
        apiVersion: 2,
        title: \'My Accordion Block\',
        category: \'widgets\',
        edit() {
            // Create a ref for the block container.
            const ref = useRef( null );
    
            // Initialize the mutation observer once the block is rendered.
            useLayoutEffect( () => {
                let observer;
    
                if ( ref.current ) {
                    observer = new MutationObserver( initAccordion );
    
                    // Observe DOM changes in our block container only.
                    observer.observe( ref.current, {
                        childList: true,
                        subtree: true,
                    } );
                }
    
                // Cleanup function which stops the mutation observer.
                return () => {
                    if ( observer ) {
                        observer.disconnect();
                        console.log( \'observer disconnected\' );
                    }
                };
            }, [] );
    
            // Pass the ref to the block container.
            // Note: { ref } is short for { ref: ref }
            const blockProps = useBlockProps( { ref } );
    
            return (
                <div { ...blockProps }>
                    <ServerSideRender block="my/accordion-block" />
                </div>
            );
        }
    } );
    
  • 相关推荐

    您应该如何国际化分布在多个文件中但又构建在一个文件中的javascript?

    我遵循了国际化的说明:https://developer.wordpress.org/block-editor/developers/internationalization/, 但它似乎与Gutenberg的开发工具没有很好的配合。它将在src 多个目录中的目录js 文件,并将其用作相对路径npm run build 将制作一个build/index.js 我正在排队的文件。这个wp i18n make-json languages --no-purge 将创建多个MD5无法工作的文件(可能是因为相对路