首页 > 解决方案 > 我自己的外部 js 代码在 react-router 中工作一次

问题描述

请一些帮助!

我的项目有 4 页,其中之一是关于。我使用 react-router 更改此页面之间的路径和内容及其链接

import React from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import './App.css';
import "./js/script";
import Home from "./components/Home";
import About from "./components/About";
import Contact from "./components/Contact";
import Portfolio from "./components/Portfolio";

export default class App extends React.Component {
  render() {
    return(
      <Router>
        <div id="main-container-ma2web">
          <nav id="main-menu-ma2web">
            <ul>
              <li>
                <Link to='/' className="menu-link-ma2web">Home</Link>
              </li>
              <li>
                <Link to='/portfolio' className="menu-link-ma2web">Portfolio</Link>
              </li>
              <li>
                <Link to='/about' className="menu-link-ma2web">About</Link>
              </li>
              <li>
                <Link to='/contact' className="menu-link-ma2web">Contact</Link>
              </li>
            </ul>
          </nav>

          <Switch>
            <Route path='/about'>
              <About />
            </Route>
            <Route path='/contact'>
              <Contact />
            </Route>
            <Route path='/portfolio'>
              <Portfolio />
            </Route>
            <Route path='/'>
              <Home />
            </Route>
          </Switch>
        </div>
      </Router>
    );
  }
}

在 About 组件中,我对其中的一些对象使用了一些 JavaScript 代码。

我将我的外部 JavaScript 代码附加到使用不同方式的项目中,例如脚本标记index.html、函数、导入componentDidMount等等......

如果我在 About 页面http://localhost:3000/about并重新加载该页面,我的 JavaScript 代码运行良好,但如果我更改路径并返回 About,JavaScript 代码将不起作用!

我应该怎么办?

关于.js

import React from 'react';

export default class About extends React.Component {
    componentDidMount() {
        document.title = 'About MA2WEB - Full-Stack Web Developer';
    }
    render() {
        return (
            <section className="main-section about animate">
                <article className="about-contents-ma2web">
                    <h1 className="typing-ma2web">I have experience in <span
                    className="txt-rotate"
                    data-period="2000"
                    data-rotate='[ "JavaScript", "Reactjs", "Nodejs", "GSAP", "PHP", "MySQL", "Wordpress", "SEO" ]'>
                        </span>
                    </h1>
                    <p>
                        I can develop both client and server side languages.
                    </p>
                </article>
            </section>
        );
    }
}

脚本.js

var TxtRotate = function(el, toRotate, period) {
  this.toRotate = toRotate;
  this.el = el;
  this.loopNum = 0;
  this.period = parseInt(period, 10) || 2000;
  this.txt = '';
  this.tick();
  this.isDeleting = false;
};

TxtRotate.prototype.tick = function() {
  var i = this.loopNum % this.toRotate.length;
  var fullTxt = this.toRotate[i];

  if (this.isDeleting) {
    this.txt = fullTxt.substring(0, this.txt.length - 1);
  } else {
    this.txt = fullTxt.substring(0, this.txt.length + 1);
  }

  this.el.innerHTML = '<span class="wrap">'+this.txt+'</span>';

  var that = this;
  var delta = 300 - Math.random() * 100;

  if (this.isDeleting) { delta /= 2; }

  if (!this.isDeleting && this.txt === fullTxt) {
    delta = this.period;
    this.isDeleting = true;
  } else if (this.isDeleting && this.txt === '') {
    this.isDeleting = false;
    this.loopNum++;
    delta = 500;
  }

  setTimeout(function() {
    that.tick();
  }, delta);
};

window.onload = function() {
  var elements = document.getElementsByClassName('txt-rotate');
  for (var i=0; i<elements.length; i++) {
    var toRotate = elements[i].getAttribute('data-rotate');
    var period = elements[i].getAttribute('data-period');
    if (toRotate) {
      new TxtRotate(elements[i], JSON.parse(toRotate), period);
    }
  }
};

标签: javascriptreactjsreact-router

解决方案


您正在 window.onload 上运行脚本,该脚本仅运行一次(首页加载)。

要解决此问题,您应该在 componentDidMount 上手动调用该函数。

方法一

在您的 script.js 中,您可以将主要功能分配给窗口对象,如下所示

window.RotateText = function() {
  var elements = document.getElementsByClassName("txt-rotate");
  for (var i = 0; i < elements.length; i++) {
    var toRotate = elements[i].getAttribute("data-rotate");
    var period = elements[i].getAttribute("data-period");
    if (toRotate) {
      new TxtRotate(elements[i], JSON.parse(toRotate), period);
    }
  }
};

并在您的 About.js 中将 componentDidMount 更改为如下所示。

  componentDidMount() {
    document.title = "About MA2WEB - Full-Stack Web Developer";
    if(window && window.RotateText){
        window.RotateText();
    }
  }

完整的代码。

脚本.js

var TxtRotate = function(el, toRotate, period) {
  this.toRotate = toRotate;
  this.el = el;
  this.loopNum = 0;
  this.period = parseInt(period, 10) || 2000;
  this.txt = "";
  this.tick();
  this.isDeleting = false;
};

TxtRotate.prototype.tick = function() {
  var i = this.loopNum % this.toRotate.length;
  var fullTxt = this.toRotate[i];

  if (this.isDeleting) {
    this.txt = fullTxt.substring(0, this.txt.length - 1);
  } else {
    this.txt = fullTxt.substring(0, this.txt.length + 1);
  }

  this.el.innerHTML = '<span class="wrap">' + this.txt + "</span>";

  var that = this;
  var delta = 300 - Math.random() * 100;

  if (this.isDeleting) {
    delta /= 2;
  }

  if (!this.isDeleting && this.txt === fullTxt) {
    delta = this.period;
    this.isDeleting = true;
  } else if (this.isDeleting && this.txt === "") {
    this.isDeleting = false;
    this.loopNum++;
    delta = 500;
  }

  setTimeout(function() {
    that.tick();
  }, delta);
};

window.RotateText = function() {
  var elements = document.getElementsByClassName("txt-rotate");
  for (var i = 0; i < elements.length; i++) {
    var toRotate = elements[i].getAttribute("data-rotate");
    var period = elements[i].getAttribute("data-period");
    if (toRotate) {
      new TxtRotate(elements[i], JSON.parse(toRotate), period);
    }
  }
};

window.onload = window.RotateText;

关于.js

import React from "react";

export default class About extends React.Component {
  componentDidMount() {
    document.title = "About MA2WEB - Full-Stack Web Developer";
    if(window && window.RotateText){
        window.RotateText();
    }
  }
  render() {
    return (
      <section className="main-section about animate">
        <article className="about-contents-ma2web">
          <h1 className="typing-ma2web">
            I have experience in{" "}
            <span
              className="txt-rotate"
              data-period="2000"
              data-rotate='[ "JavaScript", "Reactjs", "Nodejs", "GSAP", "PHP", "MySQL", "Wordpress", "SEO" ]'
            ></span>
          </h1>
          <p>I can develop both client and server side languages.</p>
        </article>
      </section>
    );
  }
}

方法 2。

从 script.js 导出默认函数。

export default function() {
  var elements = document.getElementsByClassName("txt-rotate");
  for (var i = 0; i < elements.length; i++) {
    var toRotate = elements[i].getAttribute("data-rotate");
    var period = elements[i].getAttribute("data-period");
    if (toRotate) {
      new TxtRotate(elements[i], JSON.parse(toRotate), period);
    }
  }
}

在您需要的任何组件中导入函数。

import rotateText from "../js/script";

调用componentDidMount中的函数。

  componentDidMount() {
    document.title = "About MA2WEB - Full-Stack Web Developer";
    if(window){
        rotateText();
    }
  }

完整代码

脚本.js

var TxtRotate = function(el, toRotate, period) {
  this.toRotate = toRotate;
  this.el = el;
  this.loopNum = 0;
  this.period = parseInt(period, 10) || 2000;
  this.txt = "";
  this.tick();
  this.isDeleting = false;
};

TxtRotate.prototype.tick = function() {
  var i = this.loopNum % this.toRotate.length;
  var fullTxt = this.toRotate[i];

  if (this.isDeleting) {
    this.txt = fullTxt.substring(0, this.txt.length - 1);
  } else {
    this.txt = fullTxt.substring(0, this.txt.length + 1);
  }

  this.el.innerHTML = '<span class="wrap">' + this.txt + "</span>";

  var that = this;
  var delta = 300 - Math.random() * 100;

  if (this.isDeleting) {
    delta /= 2;
  }

  if (!this.isDeleting && this.txt === fullTxt) {
    delta = this.period;
    this.isDeleting = true;
  } else if (this.isDeleting && this.txt === "") {
    this.isDeleting = false;
    this.loopNum++;
    delta = 500;
  }

  setTimeout(function() {
    that.tick();
  }, delta);
};

export default function() {
  var elements = document.getElementsByClassName("txt-rotate");
  for (var i = 0; i < elements.length; i++) {
    var toRotate = elements[i].getAttribute("data-rotate");
    var period = elements[i].getAttribute("data-period");
    if (toRotate) {
      new TxtRotate(elements[i], JSON.parse(toRotate), period);
    }
  }
}

关于.js

import React from "react";
import rotateText from "../js/script";

export default class About extends React.Component {
  componentDidMount() {
    document.title = "About MA2WEB - Full-Stack Web Developer";
    if(window){
        rotateText();
    }
  }
  render() {
    return (
      <section className="main-section about animate">
        <article className="about-contents-ma2web">
          <h1 className="typing-ma2web">
            I have experience in{" "}
            <span
              className="txt-rotate"
              data-period="2000"
              data-rotate='[ "JavaScript", "Reactjs", "Nodejs", "GSAP", "PHP", "MySQL", "Wordpress", "SEO" ]'
            ></span>
          </h1>
          <p>I can develop both client and server side languages.</p>
        </article>
      </section>
    );
  }
}

推荐阅读