Javascript WP块样式-选择块样式时触发JS

Javascript WP块样式-选择块样式时触发JS,javascript,wordpress,wordpress-theming,wordpress-gutenberg,Javascript,Wordpress,Wordpress Theming,Wordpress Gutenberg,当选择块样式时,是否有一种在WP块编辑器中运行JS的“正确方法” 我搜索了文档和google,但没有看到任何人在块样式上运行JS脚本的示例 本质上,我想在核心/组块周围注入两个元素,如果它有特定的样式 我的代码在前端工作正常,但在后端,我只能在选择块样式后在页面刷新时工作。以下是我到目前为止得到的信息: 使用php按块样式注册: register_block_style( 'core/group', array( 'name' => 'shape-pattern-1',

当选择块样式时,是否有一种在WP块编辑器中运行JS的“正确方法”

我搜索了文档和google,但没有看到任何人在块样式上运行JS脚本的示例

本质上,我想在
核心/组
块周围注入两个元素,如果它有特定的样式

我的代码在前端工作正常,但在后端,我只能在选择块样式后在页面刷新时工作。以下是我到目前为止得到的信息:

使用php按块样式注册:

register_block_style(
  'core/group',
  array(
    'name' => 'shape-pattern-1',
    'label' => 'Shape Pattern 1'
  )
);
我想在使用样式时运行的功能

var initialiseShapePatterns = function($block) {

    $block.prepend('<span class="shape-before"></span>');
    $block.append('<span class="shape-after"></span>');

    $(window).on('load scroll', function() {
        if( $block.isInViewport() ) {
            $block.addClass('animate');
        } else {
            $block.removeClass('animate');
        }
    });

} 
在块编辑器中调用函数(仅当页面加载时已选择样式时有效)

我知道我只是告诉它在加载dom时运行,但在文档中找不到任何关于在样式选择上运行代码的内容


有什么想法吗

选择适合您的样式时,为单击的对象添加一个偶数侦听器。类似这样的内容(将#styleselectbutton更改为正确的元素)


在jquery中,您可以添加事件列表器,它将在事件发生时触发操作

单击id为“myButtonId”的按钮时,将执行以下代码段

$( "#myButtonId" ).click(function() {
  //myButtonId was clicked.
  $('.is-style-shape-pattern-1, .is-style-shape-pattern-2, .is-style-shape-pattern-3').each(function() {
        initialiseShapePatterns( $(this) );
    });
});
您需要设置要触发此功能的按钮的id。您可以使用html
id
属性来实现这一点

<button id='myButtonId'> Button Text </button>
按钮文本

您可以在wordpress中添加自定义HTML。您提到了块,所以我假设您使用的是gutenburg块编辑器。这意味着您可以找到块“自定义HTML”,然后将该HTML按钮放入自定义代码中。

您可以按如下方式尝试

function my_plugin_blocks() {

    wp_add_inline_script( 'wp-edit-post', "

    wp.blocks.registerBlockStyle( 'core/group', {
        name: 'shape-pattern-1',
        label: 'Shape Pattern 1',
    });

    jQuery.fn.isInViewport = function() {       
      var elementTop = jQuery(this).offset().top;
      var elementBottom = elementTop + jQuery(this).outerHeight();

      var viewportTop = jQuery(window).scrollTop();
      var viewportBottom = viewportTop + jQuery(window).height();

      return elementBottom > viewportTop && elementTop < viewportBottom;
    };

    var initialiseShapePatterns = function(\$block) {

        if(\$block.find('> span.shape-before').length == 0)
            \$block.prepend('<span class=\"shape-before\"></span>');
        if(\$block.find('> span.shape-after').length == 0)
            \$block.append('<span class=\"shape-after\"></span>');
    };  

    const getBlockList = () => wp.data.select( 'core/block-editor' ).getBlocks();
    let blockList = getBlockList();
    wp.data.subscribe(() => {
      const newBlockList = getBlockList();
      const blockListChanged = newBlockList !== blockList;
      blockList = newBlockList;
      if ( blockListChanged ) {
        jQuery('.is-style-shape-pattern-1, .is-style-shape-pattern-2, .is-style-shape-pattern-3').each(function() {
            initialiseShapePatterns( jQuery(this) );
        });
      }
    });

    function scrollcontent()
    {
        jQuery('.is-style-shape-pattern-1, .is-style-shape-pattern-2, .is-style-shape-pattern-3').each(function() {
            if(jQuery(this).isInViewport()) {
                jQuery(this).addClass('animate');
            } else {
                jQuery(this).removeClass('animate');
            }
        });
    };

    setTimeout(function(){
        scrollcontent(); 
        jQuery('.edit-post-layout__content').on('load scroll resize', function() { scrollcontent(); });
    }, 500); ");
}
add_action( 'enqueue_block_editor_assets', 'my_plugin_blocks' );
函数我的插件块(){
wp_添加_内联_脚本('wp edit post',”
wp.blocks.registerBlockStyle('core/group'{
名称:“shape-pattern-1”,
标签:“形状图案1”,
});
jQuery.fn.isInViewport=function(){
var elementTop=jQuery(this).offset().top;
var elementBottom=elementTop+jQuery(this.outerHeight();
var viewportTop=jQuery(window.scrollTop();
var viewportBottom=viewportTop+jQuery(window).height();
返回elementBottom>viewportTop&&elementTopspan.shape before')。长度==0)
\$block.prepend(“”);
if(\$block.find('>span.shape之后')。长度==0)
\$block.append(“”);
};  
const getBlockList=()=>wp.data.select('core/block editor').getBlocks();
让blockList=getBlockList();
wp.data.subscribe(()=>{
const newBlockList=getBlockList();
const blockListChanged=newBlockList!==blockList;
区块列表=新的区块列表;
如果(blockListChanged){
jQuery('.is-style-shape-pattern-1、.is-style-shape-pattern-2、.is-style-shape-pattern-3')。每个(函数(){
initialiseShapePatterns(jQuery(this));
});
}
});
函数scrollcontent()
{
jQuery('.is-style-shape-pattern-1、.is-style-shape-pattern-2、.is-style-shape-pattern-3')。每个(函数(){
if(jQuery(this).isInViewport()){
jQuery(this.addClass('animate');
}否则{
jQuery(this.removeClass('animate');
}
});
};
setTimeout(函数(){
滚动内容();
jQuery('.edit-post-layout__-content')。on('load scroll resize',function(){scrollcontent();});
}, 500); ");
}
添加_操作('enqueue_block_editor_assets'、'my_plugin_blocks');
在这里,我使用
js
not
php
functions.php
和registerBlockStyle钩住了脚本。您可以使用任何其他方法

我想当内容区域滚动而不是窗口时,您需要编写动画。因为内容区域在Wordpress块编辑器中是固定的

以下是有用的文档:


没有一个答案令我满意,所以这里是我的解决方案。我正在使用一个名为
section
的块,当选择样式变量
dark
时,我需要一个触发器。我正在使用WordPress 5.6

我的第一个方法:

document.querySelectorAll('.block-editor-block-styles__item').forEach(
    (element) => addClickListener(element)
);

// get the title of the block to make sure to only target this block with the style variant 'dark' (because there might be other blocks which also have this variant name. 
const blockTitle = document.querySelector('.block-editor-block-card__title');

function addClickListener(styleButton) {
  styleButton.addEventListener('click', () => {
    if (blockTitle && blockTitle.textContent === 'Section') {

      // Get the right styleButton by the label that is assigned to it. 
      if(styleButton.getAttribute('aria-label') === 'Dark'){
        soSomething(); // Execute this function when the style 'Dark' is selected. 
      }
    }
  })
}
// Checking for changes in the classNames to make changes to the bloc (only when the block is selected). 
if (props.isSelected) {
  const getCurrentBlock = () => wp.data.select('core/editor').getBlock(props.clientId);
  let oldBlock = getCurrentBlock();

  wp.data.subscribe(() => {
    const newBlock = getCurrentBlock();

    // Change this line with your classname and callback function. 
    whenStyleIsChanged('is-style-dark', () => doSomething() )

    function whenStyleIsChanged(style, callback) {
      if (newBlock?.attributes?.className?.includes(style) && !oldBlock?.attributes?.className?.includes(style)) {
        oldBlock = newBlock; // Reset to prevent never-ending recursion.
        callback()
      }
    }

  })
}
现在你可以看出,这种方法相当糟糕。它使用在某些HTML中呈现的块的标题以及样式变量的标签来应用事件侦听器。它确实可以工作,但是编辑器的标记(HTML)将来可能会改变,从而破坏这段代码

我的第二种(更好的)方法:

document.querySelectorAll('.block-editor-block-styles__item').forEach(
    (element) => addClickListener(element)
);

// get the title of the block to make sure to only target this block with the style variant 'dark' (because there might be other blocks which also have this variant name. 
const blockTitle = document.querySelector('.block-editor-block-card__title');

function addClickListener(styleButton) {
  styleButton.addEventListener('click', () => {
    if (blockTitle && blockTitle.textContent === 'Section') {

      // Get the right styleButton by the label that is assigned to it. 
      if(styleButton.getAttribute('aria-label') === 'Dark'){
        soSomething(); // Execute this function when the style 'Dark' is selected. 
      }
    }
  })
}
// Checking for changes in the classNames to make changes to the bloc (only when the block is selected). 
if (props.isSelected) {
  const getCurrentBlock = () => wp.data.select('core/editor').getBlock(props.clientId);
  let oldBlock = getCurrentBlock();

  wp.data.subscribe(() => {
    const newBlock = getCurrentBlock();

    // Change this line with your classname and callback function. 
    whenStyleIsChanged('is-style-dark', () => doSomething() )

    function whenStyleIsChanged(style, callback) {
      if (newBlock?.attributes?.className?.includes(style) && !oldBlock?.attributes?.className?.includes(style)) {
        oldBlock = newBlock; // Reset to prevent never-ending recursion.
        callback()
      }
    }

  })
}
第二种方法不仅更加干净,而且经得起未来的考验,它也是“古腾堡方法”(现实中的Redux),我只能在我的块样式改变时触发我的函数,而不是在“样式按钮”上注册单击时触发。这是通过比较更新前后块的类名来完成的,在我的例子中,类
是style dark
。确保相应地更改此项和回调函数

// Checking for changes in the classNames to make changes to the bloc (only when the block is selected). 
if (props.isSelected) {
  const getCurrentBlock = () => wp.data.select('core/editor').getBlock(props.clientId);
  let oldBlock = getCurrentBlock();

  wp.data.subscribe(() => {
    const newBlock = getCurrentBlock();

    // Change this line with your classname and callback function. 
    whenStyleIsChanged('is-style-dark', () => doSomething() )

    function whenStyleIsChanged(style, callback) {
      if (newBlock?.attributes?.className?.includes(style) && !oldBlock?.attributes?.className?.includes(style)) {
        oldBlock = newBlock; // Reset to prevent never-ending recursion.
        callback()
      }
    }

  })
}