我自己的外部js代码在反应路由器中工作一次



请帮忙!

我的项目有 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>
);
}
}

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

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

如果我在"关于"页面http://localhost:3000/about并重新加载页面,我的 JavaScript 代码运行良好,但如果我更改路径并返回"关于",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);
}
}
};

你在window.onload上运行你的脚本,它只运行一次(第一页加载(。

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

方法1

在脚本中.js您可以将 main 函数分配给窗口对象,如下所示

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

在您的关于中.js将组件DidMount更改为如下所示的内容。

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.

从脚本.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>
);
}
}

我认为您应该尝试在"index.js">文件中导入外部js文件。

尝试使用BrowserRouter而不是Router

您可以使用import {BrowserRouter as Router, Switch, Route} from 'react-router'重命名导入

发生这种情况的原因是react-router加载index.html一次。之后的任何重定向只会重新绘制 DOM,而不会重新运行script标记中的任何代码。重新运行script标签的唯一方法是重新加载页面(您已弄清楚(。

一个建议是在组件挂载时附加脚本标记。不要忘记自己清理。

export default class About extends React.Component {
componentDidMount() {
document.title = 'About MA2WEB - Full-Stack Web Developer';
const script = document.createElement('script');
script.id = "myScript";
script.text = "alert('hello')";
document.body.appendChild(script);
}
componentWillUnmount() {
const script = document.getElementById("myScript");
script.parentNode.removeChild(script);
}
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>
);
}
}

我使用alert('hello')附加了一个示例。我建议alert('hello')弹出窗口根据需要显示,然后从那里进行调试。每个人的设置都不同,因此可能需要稍微调整此解决方案。但是,原则应该是相同的。

最新更新