为什么我的自定义插件每页只能正确运行一次?

时间:2020-09-28 作者:jmc1885

我有一个自定义插件,它使用短代码生成要由用户操作的表。当他们改变A2中的份数时,B2-E2中的值将除以A2中的值。enter image description here

第一次出现在页面上时,短代码和表格功能正常。如果我再次尝试使用短代码,它将生成表,但当单元格A2中的值更改时,不会发生任何变化,它不会像预期的那样分割值。

有什么想法吗?

Here is my .js code:

    \'use strict\';

    var updateNutritionValues = function updateNutritionValues(multipler, macros) {
      var carbs = document.querySelector(\'.nutrition-table__content--carbs\');
      var protein = document.querySelector(\'.nutrition-table__content--protein\');
      var fat = document.querySelector(\'.nutrition-table__content--fat\');
      var calories = document.querySelector(\'.nutrition-table__content--calories\');

      carbs.textContent = (macros.carbs / parseInt(multipler)).toFixed(1) + \'g\';
      protein.textContent = (macros.protein / parseInt(multipler)).toFixed(1) + \'g\';
      fat.textContent = (macros.fat / parseInt(multipler)).toFixed(1) + \'g\';
      calories.textContent = (macros.calories / parseInt(multipler)).toFixed(0) + \' cals\';
      console.log(\'carbs => \', (macros.carbs / parseInt(multipler)).toFixed(1) + \'g\');
      console.log(\'carbs => \', (macros.protein / parseInt(multipler)).toFixed(1) + \'g\');
      console.log(\'carbs => \', (macros.fat / parseInt(multipler)).toFixed(1) + \'g\');
      console.log(\'carbs => \', (macros.calories / parseInt(multipler)) + \' cals\');
    };

    var nutritionTable = function nutritionTable() {
      var number = document.querySelector(\'.nutrition-table__number\');
      var originalValues = {
        carbs: parseInt(document.querySelector(\'.nutrition-table__content--carbs\').textContent),
        protein: parseInt(document.querySelector(\'.nutrition-table__content--protein\').textContent),
        fat: parseInt(document.querySelector(\'.nutrition-table__content--fat\').textContent),
        calories: parseInt(document.querySelector(\'.nutrition-table__content--calories\').textContent)
      };

      number.addEventListener(\'change\', function (e) {
        updateNutritionValues(parseInt(e.target.value), originalValues);
      });
    };

    document.addEventListener(\'DOMContentLoaded\', function () {
      return nutritionTable();
    });

Here is my .php code

    function ls_nutritional_table_resources() {
        global $post;
        if( is_a( $post, \'WP_Post\' ) && has_shortcode( $post->post_content, \'nutrition_table\') ) {
            wp_register_style( \'ls-nutritional-table-css\',  plugin_dir_url( __FILE__ ) . \'nutritional-table.css\' );
            wp_enqueue_style( \'ls-nutritional-table-css\' );

            wp_enqueue_script(\'ls-nutritional-table-js\', plugin_dir_url( __FILE__ ) . \'nutritional-table.js\' );
        }
    }

    add_action( \'wp_enqueue_scripts\', \'ls_nutritional_table_resources\');


    add_shortcode(\'nutrition_table\', \'ls_nutritional_table\');

    function ls_shortcodes() {
        function ls_nutritional_table($atts) {
            $attributes = shortcode_atts(array(
                \'servings\' => \'1\',
                \'carbs\' => \'100\',
                \'protein\' => \'400\',
                \'fats\' => \'90\',
                \'calories\'=> \'2810\'
            ), $atts);

            $output = \'<div class="nutrition-table">
            <div class="nutrition-table__column">
            <div class="nutrition-table__head">Servings</div>
            <div class="nutrition-table__content">
                <input type="number" value="\' . esc_attr($attributes[\'servings\']) .  \'" min="1" autocomplete="off" class="nutrition-table__number">
            </div>
            </div>
            <div class="nutrition-table__column">
            <div class="nutrition-table__head">Carbs</div>
            <div class="nutrition-table__content nutrition-table__content--carbs">\' . esc_attr($attributes[\'carbs\']) .  \'g</div>
            </div>
            <div class="nutrition-table__column">
            <div class="nutrition-table__head">Protein</div>
            <div class="nutrition-table__content nutrition-table__content--protein">\' . esc_attr($attributes[\'protein\']) .  \'g</div>
            </div>
            <div class="nutrition-table__column">
            <div class="nutrition-table__head">Fat</div>
            <div class="nutrition-table__content nutrition-table__content--fat">\' . esc_attr($attributes[\'fats\']) .  \'g</div>
            </div>
            <div class="nutrition-table__column">
            <div class="nutrition-table__head">Calories</div>
            <div class="nutrition-table__content nutrition-table__content--calories">\' . esc_attr($attributes[\'calories\']) .  \' cals</div>
            </div>
        </div>\';

      return $output;
        }
    }

    add_action(\'init\', \'ls_shortcodes\');

    /** Always end your PHP files with this closing tag */
    ?>

1 个回复
最合适的回答,由SO网友:Paul 整理而成

代码仅应用于第一个表的原因是,您仅使用var number = document.querySelector(\'.nutrition-table__number\');

您需要遍历所有表,并为每个表添加一个事件侦听器。

下面是一个如何工作的示例。插件模式来自https://vanillajstoolkit.com/boilerplates/revealing-module-pattern/

/*!
 * Revealing Constructor Pattern Boilerplate
 * (c) 2019 Chris Ferdinandi, MIT License, https://gomakethings.com
 */
var NutritionTablesPlugin = (function () {

    \'use strict\';

    /**
     * Create the Constructor object
     */
    var Constructor = function (selector) {

        //
        // Variables
        //

        var publicAPIs = {};

        var nodes = document.querySelectorAll(selector);

        //
        // Methods
        //
        var allNodes = function (callback) {
            for (var i = 0; i < nodes.length; i++) {
                callback(nodes[i], i);
            }
        };

        /**
         * A private method
         */
        var updateNutritionValues = function (table, multipler, macros) {
            var carbs = table.querySelector( \'.nutrition-table__content--carbs\');
            var protein = table.querySelector(\'.nutrition-table__content--protein\');
            var fat = table.querySelector(\'.nutrition-table__content--fat\');
            var calories = table.querySelector(\'.nutrition-table__content--calories\');

            carbs.textContent = (macros.carbs / parseInt(multipler)).toFixed(1) + \'g\';
            protein.textContent = (macros.protein / parseInt(multipler)).toFixed(1) + \'g\';
            fat.textContent = (macros.fat / parseInt(multipler)).toFixed(1) + \'g\';
            calories.textContent = (macros.calories / parseInt(multipler)).toFixed(0) + \' cals\';
        };


        /**
         * Another public method
         */
        publicAPIs.init = function (options) {
            allNodes( function(node){

                var originalValues = {
                    carbs: parseInt(node.querySelector(\'.nutrition-table__content--carbs\').textContent),
                    protein: parseInt(node.querySelector(\'.nutrition-table__content--protein\').textContent),
                    fat: parseInt(node.querySelector(\'.nutrition-table__content--fat\').textContent),
                    calories: parseInt(node.querySelector( \'.nutrition-table__content--calories\').textContent)
                };

                node.addEventListener(\'change\', function (e) {
                    updateNutritionValues(node, parseInt(e.target.value), originalValues);
                });
            });
        };

        //
        // Return the Public APIs
        //
        return publicAPIs;
    };

    //
    // Return the Constructor
    //
    return Constructor;

})();

document.addEventListener("DOMContentLoaded", function(event) {
    var nutrition = new NutritionTablesPlugin(\'.nutrition-table\');
    nutrition.init();

});

在PHP代码中,您需要使用esc_html 对于碳水化合物/脂肪/蛋白质/卡路里属性输出。https://developer.wordpress.org/reference/functions/esc_html/

相关推荐

Page-slug.php不起作用,但仅适用于特定的插件

我正在尝试创建一个名为“的页面”;“漫画”;带着鼻涕虫“;“漫画”;用作我的网络经济网站的主目录。我已经创建了一个页面的漫画。然而,当我转到页面时,它只是链接回索引。php。当我尝试使用ID时,它也不起作用。当我尝试在其他slug和id中使用相同的格式时,效果很好,所以我知道WordPress工作正常。我认为这可能与我在函数中的某些内容相冲突。php,但是没有其他名称使用;“漫画”;(我已链接到下面的文件,供任何人查看)。我还尝试清理数据库中可能使用该slug的任何已删除项目,但一无所获。有人知道是什么导