0

近两个星期以来,我一直在网上搜索 GitHub,她在堆栈溢出中为我下面提到的问题寻找正确的解决方案,我真的对 barba 很着迷,但不幸的是我无法让它为我工作。

很抱歉,这是一个很长的帖子。我希望这里有人能帮助我。

我正在使用带有 WordPress 的 barba.js v2(不使用 elementor,我创建了一个从头开始创建的自定义主题)。我已经设置了 functions.php 来将所有页面上的全局样式和脚本以及各个页面上的特定于页面的脚本和样式排入队列。

这是我的示例目录:

网站页面:

  • 主页 - front-page.php
  • 新闻/博客 - home.php
  • 关于 - page-templates/page_about.php
  • 单一新闻 - single-post.php
  • 团队 - page-templates/page_team.php
  • 标题
  • 页脚
  • 函数.php
  • 所有 css & js 都在 assets/css & assets/js 文件夹中

我正在使用的 Javascript/库:

全局脚本和样式:

  • 样式.css
  • bootstrap.min.css
  • Jquery 3.6.0(延迟)
  • main.js (defer) (用于标题导航菜单)
  • Barba-core v2(延迟)(来自 cdn.jsdelivr)
  • gsap.min (延迟) (cdn)
  • page-transition.js(延迟)(用于 barba.init())

以下是页面特定的全局脚本和 CSS 

  • Slick.js(应该只在主页、关于和新闻页面加载)
  • Bootstrap.js(应仅在团队页面中加载)
  • Typewritter.js (应该只在主页加载)

个别页面特定的样式和脚本:

  • Home.css 和 home.js(包含 slick 和 typewritter 配置)
  • about.css & about.js(包含漂亮的配置)
  • 团队.css
  • news.css 和 news.js(包含多个 slick 配置)
  • 单post.css

问题:

  • 无法在所需页面上应用 slick 和 typewriter js
  • 当我加载网站主页然后转到“关于”页面时,它可以工作。如果我重新加载关于页面,它也可以工作。重新加载关于页面后,当我回到主页时,如果我回到关于页面,光滑的滑块会中断。 
  • 在主页上,打字机js最初是加载的,但是当我从任何其他页面回到主页时,它就不起作用了。

这是我的 page-transition.js

document.addEventListener("DOMContentLoaded", () => {

    barba.init({
        debug: true,
        logLevel: 'debug',
        sync: false
    });

    barba.hooks.afterLeave(data => {
        var nextPageStyle = data.next.namespace;
        let nextPagescript =  data.next.container.querySelector("#primary").getAttribute("class").trim().split(" ");
        var newScriptUrl = "http://localhost/website/wp-content/themes/mytheme/assets/js/" + nextPageStyle + ".js";

        // I have added 'css' or 'js' classes via php function to div#primary in my header.php depending on the page-specific.css and page-specific.js enqueued in the page
        if (nextPagescript.includes("js")) {

            // If div#primary has 'js' class
            $.getScript( newScriptUrl, function( data, textStatus, jqxhr ) {
                // For ex: in home.js, I have added var Scripts { init: function () }
                Scripts.init();
                alert("Scripts initiated");
            });
        }

        // I have added 'slick', 'bootstrap', 'typewritter' classes via php function to div#main in my header.php depending on which page has slick or bootstrap or typewritter js
        let currentClassArray = data.current.container.querySelector("#main").getAttribute("class").trim().split(" ");
        let nextPageClassArray = data.next.container.querySelector("#main").getAttribute("class").trim().split(" ");


        // If the current page has Slick and next page doesn't, remove slick
        if (currentClassArray.includes("slick") && !(nextPageClassArray.includes("slick"))) {
               $('link[rel=stylesheet][id~="slick-css"]').remove();
               $('script[id~="slick-js"]').remove();
        } else if (!(currentClassArray.includes("slick")) && nextPageClassArray.includes("slick")) {
               // If the current page doesn't have Slick and next page does have slick, include them
               $("head").append(
                   '<link rel="stylesheet" id="slick-css" type="text/css" href="http://localhost/website/wp-content/themes/mytheme/assets/slick/slick/slick.css" />'
               );
               $.getScript( "http://localhost/website/wp-content/themes/mytheme/assets/slick/slick/slick.min.js", function( ) {
                   // Scripts.init();
               });
        } else if ((currentClassArray && nextPageClassArray).includes("slick")) {
                // If both pages have slick, do nothing
        } else if (!(currentClassArray && nextPageClassArray).includes("slick")) {
                //  If both pages do not have slick, do nothing
        }

        // If it is home page, include typewritter, if it is not already included
        if (nextPageStyle == "home") {
            if (document.querySelector('script[id="typewritter-js"][src="http://localhost/website/wp-content/themes/mytheme/assets/typewritter/typewritter.js"]')) {
                alert("True");
            } else {
                alert("False");
                $.getScript( "http://localhost/website/wp-content/themes/mytheme/assets/typewritter/typewritter.js", function( ) {
                     alert("Script loaded");
                });
            }
        } else { }
    });


    // Before Enter
    barba.hooks.beforeEnter(data => {
        var nextPageStyle = data.next.namespace;
        
        var newStyleUrl = "http://localhost/website/wp-content/themes/mytheme/assets/css/" + nextPageStyle + ".css";
        var newScriptUrl = "http://localhost/website/wp-content/themes/mytheme/assets/js/" + nextPageStyle + ".js";

        let nextpagehasCss = data.next.container.querySelector("#primary").getAttribute("class").trim().split(" ");

        if (nextpagehasCss.includes("css")) {
            $("head").append(
                '<link rel="stylesheet" id="' + nextPageStyle + '-css" type="text/css" href="' + newStyleUrl + '" />'
            );
        }
    });


    // Enter
    barba.hooks.enter(data => {

        // Update body class
        let parser = new DOMParser();
        let htmlDoc = parser.parseFromString(
            data.next.html.replace(
                /(<\/?)body( .+?)?>/gi,
                "$1notbody$2>",
                data.next.html
            ),
            "text/html"
        );
        let bodyClasses = htmlDoc.querySelector("notbody").getAttribute("class");
        $("body").attr("class", bodyClasses);


        // Remove Previous Page Style and Js
        let previousPagehasCss = data.current.container.querySelector("#primary").getAttribute("class").trim().split(" ");
        let nextPagehasJs = data.next.container.querySelector("#primary").getAttribute("class").trim().split(" ");
        var currentPageStyle = data.current.namespace;

        if (previousPagehasCss.includes("css")) {
            $('link[rel=stylesheet][id~="' + currentPageStyle + '-css"]').remove();
        }
        
        if (previousPagehasCss.includes("js")) {
            $('script[id~="' + currentPageStyle + '-js"]').remove();
        }
    });

   
});

这是我的 header.php

<?php

/**
 * The header.
 * 
 * This is the template that displays all of the <head> section and everything up until main.
 * 
 * @package WordPress
 * @subpackage website
 * @since My Theme 1.0
 */
?>

<!doctype html>
<html <?php language_attributes(); ?>>

<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="profile" href="https://gmpg.org/xfn/11">
    <?php wp_head(); ?>
</head>

<body <?php body_class(); ?> data-barba="wrapper">
<?php
    if (is_front_page()) {
        $get_url_name = "home";
    } elseif (is_home()) {
        $get_url_name = "news";
    } elseif (is_singular('post')) {
        $get_url_name = "single-post";
    } else {
        $get_url_name = basename(get_permalink());
    }
?>
    <div id="page" class="site">
        // Nav Menu
        <?php get_template_part('template-parts/header/site-header'); ?>

        <div class="loader"></div>

        <div id="content" class="site-content " data-barba="container" data-barba-namespace="<?php echo $get_url_name; ?>">
            // function stylescript() adds 'css' or 'js' classes if the current page has page-specific css or js like home.css or home.js
            <div id="primary" class="content-area <?php stylescript(); ?>">
                // function main_class() adds 'slick', 'bootstrap', or 'typewritter' classes if the current page requires any of these global page-specific scripts
                <div id="main" class="site-main <?php main_class(); ?>" role="main">

这是我的 home.js

document.addEventListener("DOMContentLoaded", () => {
  Scripts.init();
});

// Slick Carousal settings
var Scripts = {
  init: function () {
     const nextArrow = `<button class='nextArrow btn'><svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="currentColor" class="bi bi-arrow-right-short" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 8a.5.5 0 0 1 .5-.5h5.793L8.146 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L10.293 8.5H4.5A.5.5 0 0 1 4 8z"/></svg> </button>`;

    const prevArrow = `<button class='prevArrow btn'><svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="currentColor" class="bi bi-arrow-left-short" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M12 8a.5.5 0 0 1-.5.5H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5a.5.5 0 0 1 .5.5z"/></svg></button>`;

    const carousel_settings = {
      dots: false,
      infinite: false,
      arrows: true,
      prevArrow,
      nextArrow,
      speed: 300,
      slidesToShow: 2.5,
      slidesToScroll: 1,

      responsive: [
        {
          breakpoint: 992,
          settings: {
            slidesToShow: 1.5,
          },
        },
        {
          breakpoint: 769,
          settings: {
            slidesToShow: 1,
          },
        },
      ],
    };

    $(".testimonial-slider").slick(carousel_settings);
    $(".latest_video--carousel-container").slick({
      ...carousel_settings,
    });

    // TODO :- TYPEWRITER EFFECT
    const ele = document.getElementById("typewriter-effect");
    if (ele) {
      new Typewriter(ele, {
        strings: ["Hi", "Hello", "Houdy"],
        autoStart: true,
        loop: true,
      });
    }
  }
};

这里是 about.js

document.addEventListener("DOMContentLoaded", () => {
  Scripts.init();
});

var Scripts = {
  init: function () {
    const nextArrow = `<button class='nextArrow btn'><svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="currentColor" class="bi bi-arrow-right-short" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 8a.5.5 0 0 1 .5-.5h5.793L8.146 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L10.293 8.5H4.5A.5.5 0 0 1 4 8z"/></svg> </button>`;

const prevArrow = `<button class='prevArrow btn'><svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="currentColor" class="bi bi-arrow-left-short" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M12 8a.5.5 0 0 1-.5.5H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5a.5.5 0 0 1 .5.5z"/>
</svg></button>`;

    $(".carousel-slider").slick({
      dots: false,
      infinite: false,
      arrows: true,
      nextArrow,
      prevArrow,
      speed: 300,
      slidesToShow: 2.5,
      slidesToScroll: 1,
      responsive: [
        {
          breakpoint: 982,
          settings: {
            slidesToShow: 1.3,
          },
        },

        {
          breakpoint: 650,
          settings: {
            slidesToShow: 1,
          },
        },
      ],
    });
  },
};

这是footer.php

<?php

/**
 * Footer
 * 
 * @package WordPress
 * @subpackage website
 * @since My Theme 1.0
 */

?>
</div><!-- #main -->
</div><!-- #primary -->

</div><!-- #content -->

<footer>...</footer>

</div><!-- #page -->

<?php wp_footer(); ?>

</body>

</html>

以下是我遵循的教程:

通过参考上述教程,我能够解决我遇到的许多问题,但对于一些我无法使其工作。

如果有人帮助我理解我在这里做错了什么并告诉我如何解决这个问题,那将是一个很大的帮助。谢谢

4

1 回答 1

0

如果有人正在寻找一个好的解决方案,当他们的脚本标签在 barba-container 中时,我遇到了一个类似的问题,即 Web 组件(自定义 HTML 元素)没有初始化。

我想出了这个:

barba.init({
    ...whatever settings you have,
    transitions:[{
       name: : "your-transition-name",
       
       beforeEnter(data) {
           const nextEl = data.next.container;
           if (nextEl) { //Just a little check to make sure we don't run this on an error
               // Find all scripts in the next container
               const nextScripts = nextEl.querySelectorAll('script');
    
               //Iterate over incoming script tags
               nextScripts.forEach(nextScript => {
                  const src = nextScript.src;
                  //Duplicate check - no need to re-execute scripts that are already loaded.
                  if (document.head.querySelector('script[src="' + src + '"]') == undefined) {

                    //Have to create a new script element in order for the browser to execute the code
                    const newScript = document.createElement('script');
                    newScript.src = src;
                    newScript.async = true; 
                    document.head.append(newScript);

                    nextScript.remove(); // Cleaning up the script in the container;
                  }
           }
       },
       (...whatever other transition functions you need, like after(), once(), etc.)



});

我很确定这解决了脚本未执行的主要问题,方法是在正文中加载的每个脚本标签的标题中创建一个新的脚本标签。(似乎正文 HTML 正在以不会发生重新执行脚本的方式加载,这对于 AJAX 替换是正常的)。

于 2022-01-21T18:44:31.747 回答