请帮忙!
我的项目有 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')
弹出窗口根据需要显示,然后从那里进行调试。每个人的设置都不同,因此可能需要稍微调整此解决方案。但是,原则应该是相同的。