Instead of using raw DOM nodes, use the WP Element wrapper components and build it with wp scripts
For example here is an ESNext block using modern JS:
edit() {
return (
<div style={ blockStyle }>
Hello World, step 1 (from the editor).
</div>
);
},
And again using raw JS without the build step:
( function( blocks, i18n, element ) {
var el = element.createElement;
....
edit: function() {
return el(
'p',
{ style: blockStyle },
'Hello World, step 1 (from the editor).'
);
},
...
} )( window.wp.blocks, window.wp.i18n, window.wp.element );
Here’s what your edit function might look like using modern JS:
edit: function( props ) {
const data = wp.data.select( 'core/block-editor' );
const blocks = data.getBlocks();
setHeadingAnchors(blocks);
const headings = blocks.map( ( item, index ) => {
if ( item.name === 'core/heading' ) {
return null;
}
return <li>{item.attributes.content}</li>;
} );
return <div>
<h2>{ __( 'Table of Contents', 'simpletoc' ) }</h2>
<ul>
{headings}
</ul>
</div>;
},
Then we can use wp scripts
to build it:
https://github.com/WordPress/gutenberg-examples/blob/master/01-basic-esnext/package.json#L19-L22
As a result it will build the script and handle all the JSX and make sure it uses the WordPress element wrapper ( otherwise you’d have to use el( 'p'
etc. It’ll even give you a PHP file that returns an array of JS dependencies for wp_enqueue_script
so that your built JS stays super lean, and gets loaded at the correct time in the editor
Sidenotes:
item['name']
will give you issues,item
is an object, not an array- indent! Indent correctly and consistently
- It looks like you have a funciton
setHeadingAnchors
that meddles in the affairs of other blocks, I’d advise against this - You should use this code in your save function as well, the only thing your PHP needs to do is enqueue the JS, and ensure any assets needed on the frontend are loaded