首页 > 解决方案 > 如何在反应组件中运行自执行 JS 脚本?

问题描述

我是 React 的新手,这也是我在任何其他框架中都不需要做的事情,所以我可以使用任何和所有建议:)

我正在尝试制作一个复制/封装此处显示的响应功能的 React 组件: https ://www.adtile.me/fixed-nav/ 这是用普通 JS 制作的(到目前为止,我对 JS 的了解有限这是我的劫持)。

到目前为止,我所做的基本上是从链接上提到的 github 复制 index.html 文件,并在我的 App.js 主组件中呈现该组件。我现在遇到的问题是,在通常包含在标签中的情况下,我无法弄清楚导入 JS 脚本的 React 方法。在他们的 repo 中,他们总共使用了 4 个脚本来实现网页的响应性,全部加载在 index.html 中:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Adtile Fixed Nav</title>
    <meta name="author" content="Adtile">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="css/styles.css">
    <!--[if lt IE 9]>
      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
      <link rel="stylesheet" href="css/ie.css">
    <![endif]-->
    <script src="js/responsive-nav.js"></script>
  </head>
  <body>

    <header>
      <a href="#home" class="logo" data-scroll>Fixed Nav</a>
      <nav class="nav-collapse">
        <ul>
          <li class="menu-item active"><a href="#home" data-scroll>Home</a></li>
          <li class="menu-item"><a href="#about" data-scroll>About</a></li>
          <li class="menu-item"><a href="#projects" data-scroll>Projects</a></li>
          <li class="menu-item"><a href="#blog" data-scroll>Blog</a></li>
          <li class="menu-item"><a href="http://www.google.com" target="_blank">Google</a></li>
        </ul>
      </nav>
    </header>

    <section id="home">
      <h1>Fixed Nav</h1>
      <p>The code and examples are hosted on GitHub and can be <a href="https://github.com/adtile/fixed-nav">found from here</a>. Read more about the approach from&nbsp;<a href="http://blog.adtile.me/2014/03/03/responsive-fixed-one-page-navigation/">our&nbsp;blog</a>.</p>
    </section>

    <section id="about">
      <h1>About</h1>
    </section>

    <section id="projects">
      <h1>Projects</h1>
    </section>

    <section id="blog">
      <h1>Blog</h1>
    </section>

    <script src="js/fastclick.js"></script>
    <script src="js/scroll.js"></script>
    <script src="js/fixed-responsive-nav.js"></script>
  </body>
</html>

我尝试在我的 NavBar 组件(在 jsx 模板中)中以相同的方式加载它们,但我认为它们加载不正确,因为响应性质不起作用。

我还尝试将脚本作为自己的文件放在我的项目中(就像他们拥有它一样),然后在导入 React 之前在我的 NavBar 组件中导入“responsive-nav.js”。这让我觉得我到了某个地方,但是当以这种方式导入时,脚本会产生许多编译时错误:

编译失败。

./src/components/NavBar/fixed-responsive-nav.js 第 28:5 行:'FastClick' 未定义 no-undef 第 31:5 行:'smoothScroll' 未定义 no-undef 第 34:22 行:'responsiveNav ' 未定义 no-undef 第 136:11 行:意外使用 'history' no-restricted-globals 第 137:9 行:意外使用 'history' no-restricted-globals 第 160:11 行:意外使用 'location' no-restricted-globals 第 165:15 行:意外使用“历史”无限制全局第 166:13 行:意外使用“历史”无限制全局

这是尝试导入脚本之一(fixed-responsive-nav.js)时的输出。我认为我可以通过导入我认为它试图引用的脚本 fastclick.js 来解决诸如“FastClick”之类的错误。然而,这并没有解决任何冲突。这是fixed-responsive-nav.js,以了解我正在使用哪种脚本(以上链接中提供的所有脚本):

/* =============================================
 *
 *   FIXED RESPONSIVE NAV
 *
 *   (c) 2014 @adtileHQ
 *   http://www.adtile.me
 *   http://twitter.com/adtilehq
 *
 *   Free to use under the MIT License.
 *
 * ============================================= */

(function () {

  "use strict";

  // Feature test to rule out some older browsers
  if ("querySelector" in document && "addEventListener" in window) {

    // forEach method, that passes back the stuff we need
    var forEach = function (array, callback, scope) {
      for (var i = 0; i < array.length; i++) {
        callback.call(scope, i, array[i]);
      }
    };

    // Attach FastClick to remove the 300ms tap delay
    FastClick.attach(document.body);

    // Init smooth scrolling
    smoothScroll.init();

    // Init Responsive Nav
    var navigation = responsiveNav(".nav-collapse", {

      // Close the navigation when it's tapped
      closeOnNavClick: true
    });

    // Create a Mask
    var mask = document.createElement("div");
    mask.className = "mask";

    // Append the mask inside <body>
    document.body.appendChild(mask);

    // Disable mask transitions on Android to boost performance
    if (navigator.userAgent.match(/Android/i) !== null) {
      document.documentElement.className += " android";
    }

    // Find navigation links and save a reference to them
    var nav = document.querySelector(".nav-collapse ul"),
      links = nav.querySelectorAll("[data-scroll]");

    // "content" will store all the location cordinates
    var content;

    // Set up an array of locations which we store in "content"
    var setupLocations = function () {
      content = [];
      forEach(links, function (i, el) {
        var href = links[i].getAttribute("href").replace("#", "");
        content.push(document.getElementById(href).offsetTop + 200);
      });
    };

    // call locations set up once
    setupLocations();

    // Re-calculate locations on window resize and orientation change
    window.addEventListener("resize", function () {
      setupLocations();
    }, false);

    // Highlight active link on the navigation
    var selectActiveMenuItem = function (i) {
      forEach(links, function (i, el) {
        links[i].parentNode.className = links[i].parentNode.className.replace(/[\s]{0,}active/, "");
      });
      links[i].parentNode.className += links[i].parentNode.className ? " active" : "active";
    };

    // Highlight active link when scrolling
    var wasNavigationTapped = false;
    window.addEventListener("scroll", function () {

      // Determine viewport and body size
      var top = window.pageYOffset,
        body = document.body,
        html = document.documentElement,
        viewport = window.innerHeight,
        bodyheight = Math.max(
          body.scrollHeight,
          body.offsetHeight,
          html.clientHeight,
          html.scrollHeight,
          html.offsetHeight
        );

      // For each content link, when it's in viewport, highlight it
      if (!wasNavigationTapped) {
        forEach(content, function (i, loc) {
          if ((loc > top && (loc < top + 300 || (top + viewport) >= bodyheight))) {
            selectActiveMenuItem(i);
          }
        });
      }
    }, false);

    // Close navigation when tapping the mask under it
    mask.addEventListener("click", function (e) {
      e.preventDefault();
      navigation.close();
    }, false);

    // Clear wasNavigationTapped check after scrolling
    var clearTapCheck = function () {
      setTimeout(function () {
        wasNavigationTapped = false;
      }, 500);
    };

    // Select the right navigation item when tapping the logo
    document.querySelector(".logo").addEventListener("click", function (e) {
      e.preventDefault();
      wasNavigationTapped = true;

      // Select first navigation item
      selectActiveMenuItem(0);

      // Close navigation
      navigation.close();

      // Remove hash from the URL if pushState is supported
      if (history.pushState) {
        history.pushState("", document.title, window.location.pathname);
      }

      // Clear wasNavigationTapped check
      clearTapCheck();
    }, false);

    // When a navigation item is tapped, select it and begin scrolling
    forEach(links, function (i, el) {
      links[i].addEventListener("click", function (e) {
        e.preventDefault();
        wasNavigationTapped = true;

        // Select right navigation item (we are passing which one to select "i")
        selectActiveMenuItem(i);

        // Show the URL of the section on the address bar
        var thisID = this.getAttribute("href").replace("#", ""),
          pane = document.getElementById(thisID);

        // If the URL isn't "#home", change it
        if (thisID !== "home") {
          pane.removeAttribute("id");
          location.hash = "#" + thisID;
          pane.setAttribute("id", thisID);

        // If the URL is "#home", remove hash from the URL
        } else {
          if (history.pushState) {
            history.pushState("", document.title, window.location.pathname);
          }
        }

        // Clear wasNavigationTapped check
        clearTapCheck();
      }, false);
    });

  }

})();

标签: javascriptreactjs

解决方案


推荐阅读