admin管理员组

文章数量:1192816

Is there a way to detect when the position of a block has changed? I am trying to do something when a block is moved.

I'm trying:

var blockIndex = wp.data.select( "core/block-editor" ).getBlockIndex( clientId );
const [ index, setIndex ] = useState(blockIndex);

useEffect( () => {
  console.log('Block moved');
}, [ blockIndex ] );

Is there a way to detect when the position of a block has changed? I am trying to do something when a block is moved.

I'm trying:

var blockIndex = wp.data.select( "core/block-editor" ).getBlockIndex( clientId );
const [ index, setIndex ] = useState(blockIndex);

useEffect( () => {
  console.log('Block moved');
}, [ blockIndex ] );
Share Improve this question asked Aug 5, 2022 at 11:32 CyberJCyberJ 4375 silver badges19 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 3

I don't know if there's an event or Gutenberg hook like blockMove or blockIndexChange, but you can use subscribe() from the @wordpress/data package to listen to the block index changes.

Working Example using hooks

  • WordPress dependencies:

    import { useBlockProps } from '@wordpress/block-editor';
    import { useState, useEffect } from '@wordpress/element';
    import { useSelect, subscribe } from '@wordpress/data';
    
  • The block's edit() function:

    function edit( { clientId } ) {
        const { getBlockIndex } = useSelect( 'core/block-editor' );
    
        // Set initial index.
        const [ currentBlockIndex, setBlockIndex ] = useState( getBlockIndex( clientId ) );
    
        // Subscribe once this block has been attached to the DOM.
        useEffect( () => {
            // Listen to block index changes and set the current index if necessary.
            // When you're done listening, just call unsubscribe().
            const unsubscribe = subscribe( () => {
                const blockIndex = getBlockIndex( clientId );
    
                if ( currentBlockIndex !== blockIndex ) {
                    console.log( `block move detected; from index ${ currentBlockIndex} to ${ blockIndex }` );
                    setBlockIndex( blockIndex ); // update current index
                }
            } );
    
            console.log( `subscribed; clientId is ${ clientId }` );
    
            // Unsubscribe; for example once this block is removed from the editor.
            return function cleanup() {
                unsubscribe();
                console.log( `unsubscribed - stopped listening to index changes; clientId is ${ clientId }` );
            };
        }, [ clientId, currentBlockIndex ] ); // note the currentBlockIndex
    
        return (
            <div { ...useBlockProps() }>
                Current block index: { currentBlockIndex }
            </div>
        );
    }
    

    So the useEffect callback will be called when the block is explicitly moved or that its index changed because another block was moved to the above block's current position.

You can also see my answer here for an example outside an edit function, which uses wp.domReady() and adds a block style once the current post type is determined.

本文标签: Gutenberg on block move