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

时间:2020-04-27 11:07:07

标签: javascript wordpress wordpress-theming wordpress-gutenberg

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

我已经搜索了文档和Google,但看不到任何人以块样式运行JS脚本的示例。

本质上,如果它具有特定的样式,我想在 String JSONString = "{\"Info\":[{\"area\":301336,\"nativeName\":\"Italia\",\"capital\":\"Rome\",\"demonym\":\"Italian\",\"flag\":\"https://restcountries.eu/data/ita.svg\",\"alpha2Code\":\"IT\",\"languages\":[{\"nativeName\":\"Italiano\",\"iso639_2\":\"ita\",\"name\":\"Italian\",\"iso639_1\":\"it\"}],\"borders\":[\"AUT\",\"FRA\",\"SMR\",\"SVN\",\"CHE\",\"VAT\"],\"subregion\":\"Southern Europe\",\"callingCodes\":[\"39\"],\"regionalBlocs\":[{\"otherNames\":[],\"acronym\":\"EU\",\"name\":\"European Union\",\"otherAcronyms\":[]}],\"gini\":36,\"population\":60665551,\"numericCode\":\"380\",\"alpha3Code\":\"ITA\",\"topLevelDomain\":[\".it\"],\"timezones\":[\"UTC+01:00\"],\"cioc\":\"ITA\",\"translations\":{\"br\":\"Itália\",\"de\":\"Italien\",\"pt\":\"Itália\",\"ja\":\"イタリア\",\"hr\":\"Italija\",\"it\":\"Italia\",\"fa\":\"ایتالیا\",\"fr\":\"Italie\",\"es\":\"Italia\",\"nl\":\"Italië\"},\"name\":\"Italy\",\"altSpellings\":[\"IT\",\"Italian Republic\",\"Repubblica italiana\"],\"region\":\"Europe\",\"latlng\":[42.83333333,12.83333333],\"currencies\":[{\"symbol\":\"\\u20ac\",\"code\":\"EUR\",\"name\":\"Euro\"}]}]}"; JSONArray JSON = new JSONArray(JSONString); 块周围注入两个元素。

我的代码在前端工作得很好,但是在后端,选择块样式后,我只能让它在页面刷新上工作。这是到目前为止我得到的:

使用php通过块样式注册:

core/group

我要在使用样式时运行的功能

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');
        }
    });

} 

块编辑器中的调用功能(仅在页面加载时已选择样式的情况下有效)

$(document).ready(function() {
    $('.is-style-shape-pattern-1, .is-style-shape-pattern-2, .is-style-shape-pattern-3').each(function() {
        initialiseShapePatterns( $(this) );
    });
});

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

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

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

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

id

您将需要设置要触发此功能的按钮的ID。您可以使用html <button id='myButtonId'> Button Text </button> 属性

AppStateType

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

答案 1 :(得分:0)

您可以尝试如下操作。.

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' );

这里我使用functions.php而非jsphp和registerBlockStyle钩住了脚本。您可以使用任何其他方式。

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

以下是有用的文档:

Doc1 Doc2

答案 2 :(得分:0)

没有一个答案让我满意,所以这是我的解决方案。我正在使用一个名为 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. 
      }
    }
  })
}

现在您可以看出,这种方法非常糟糕。它使用在某些 HTML 中呈现的块的标题以及样式变体的标签来应用事件侦听器。它确实有效,但编辑器的标记 (HTML) 将来可能会更改,从而破坏此代码。

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

// 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),而且只有当我的块样式发生变化时,我才能触发我的功能,而不是每次点击时在“样式按钮”上注册。这是通过比较更新前后块的类名来完成的,在我的例子中是类 is-style-dark。确保相应地更改它和回调函数。

相关问题