React按钮仅在Chrome/Edge检查模式下显示的问题排查
问题描述
我开发了一个获取数据并展示系列待解决问题的程序,其中问题流程的按钮仅在Chrome和Edge浏览器的检查模式下才会显示。尝试为div容器添加CSS样式来让按钮正常显示,但没有效果。相关代码如下:
HTML代码
<!DOCTYPE html> <meta name="viewport" content="width=device-width, initial-scale=1"> <html> <style> html, body { margin: 0; height: 100%; } </style> <head> <meta charset="utf-8" /> <title>Maxwell Cognitive Problem Launcher</title> </head> <body> <h1 ID:prob_identifier>ID: 96543210</h1> <h2 ID:student_id>1</h2> </body> <div id="maxwell_container"></div> <div id="app"></div> <div id="feedback"></div> <!-- Note: when deploying, replace "development.js" with "production.min.js". --> <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script> <script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <!-- Load our React component. --> <script type="text/babel" src="./maxwell/app/components/MaxwellCore.jsx" crossorigin ></script> </html>
初始化代码
let props = ''; let html_tag = '#maxwell_container'; let student_id = document.getElementById("student_id"); console.log(student_id); let pg = SVG().addTo(html_tag).viewbox(0,0,10000,5000).size(`100%`, `100%`); pg.data({'finalAnswer':0}); let stuffout = new ProbProfile(props, pg); stuffout.getData(pg);
数据获取代码
class ProbProfile extends React.Component { constructor(props, pg) { super(props); this.state = {ProbID:'', ProbDesc:'', userID:''}; } getData(pg) { let request = new XMLHttpRequest(); console.log("Inside getData method"); request.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { // console.log(this.responseText); if (this.responseText != '') { let stuff = new Stuff(pg, this.responseText); problem_page(stuff); } } }; request.open('GET', 'http://localhost:8081/maxwellData', true); request.send(); request.onload; //console.log(request.responseText); } render() { return( '<div>'+ '<h2>Getting data</h2>' +'{this.getData()}' +'</div>' ); } }
按钮渲染代码
function problem_page(stuff) { const sleep = ms => new Promise(r => setTimeout(r, ms)); console.log("Started problem_runner") let dbg = 0; let inpd = JSON.parse(stuff.stuffout); let inpdd = inpd.data; const RepeaterWithContinue = () => { console.log("Repeater with Continue"); const evaluateRef = React.useRef(false); const continueRef = React.useRef(false); const started = React.useRef(false); const DIMS = new Layout(104, 141, 21, 6 ); let i = 0; const start = async () => { if (started.current) {return;}; let done = 0; for (const element of inpdd) { console.log("Problem set "+element.problem_id); let inpda = new Array(element.algorithm); for (let j = 0; j < inpda.length; j++) { console.log("Problem number "+j); let probs = inpda[j].Problems; for (const element of probs){ done = 0; let pp = stuff.pg; let PS_in = element.spec; let PS = new ProbSpec(PS_in.free, PS_in.color, PS_in.shape, PS_in.size, PS_in.rotation); // (algorithm, levels, depth, shapelimit, spec) let PD = new ProbDef(element.algorithm, element.levels, element.depth, probs[j].shapelimit, PS); console.log('PD is: ',PD); let soln = problem(PD, pp, DIMS); let problemRef = i+'_'+j; while (done == 0) { if (evaluateRef.current) { evaluate(soln, pp, problemRef, DIMS); while (!(continueRef.current)) { await sleep(10000); } done = 1; pp.clear(); evaluateRef.current = false; pp.data({'finalAnswer':-1}); break; } i++; // console.log("time = "+i) await sleep(1000); } } } } }; return ( <div style={{ display: "block"}}> <button type="button" onClick={() => {start();started.current = true; }}>Start</button> <button type="button" onClick={() => evaluateRef.current = true}> Evaluate </button> <button type="button" onClick={() => continueRef.current = true}> Continue </button> </div> ); }; ReactDOM.createRoot(document.querySelector("#app")) .render(<RepeaterWithContinue />) }
原因分析
- SVG容器完全遮挡按钮容器:初始化代码中创建的SVG元素设置了
size(100%, 100%),会占满#maxwell_container的全部空间。由于#maxwell_container未设置高度限制,且位于#app之前,SVG会占据整个视口高度,导致#app容器被挤出视口或完全遮挡。只有在浏览器检查模式下,元素层级被临时调整,按钮才会显现。 - HTML属性语法错误:
<h1 ID:prob_identifier>和<h2 ID:student_id>的ID属性写法不符合标准,正确格式应为id="xxx",虽不直接导致按钮隐藏,但属于无效语法,可能引发布局异常。 - React组件渲染逻辑违规:
ProbProfile的render方法返回字符串而非合法JSX,且在render中调用异步方法getData,不符合React渲染规范,可能导致渲染时序混乱。
解决方案
1. 调整SVG容器尺寸,预留按钮空间
修改初始化代码中的SVG尺寸,同时给容器添加CSS限制:
// 初始化代码修改:用80vh代替100%高度,为按钮留空间 let pg = SVG().addTo(html_tag).viewbox(0,0,10000,5000).size(`100%`, `80vh`);
添加对应CSS:
<style> html, body { margin: 0; height: 100%; } #maxwell_container { height: 80vh; overflow: auto; /* 内容超出时滚动 */ } #app { height: 20vh; padding: 10px; position: relative; z-index: 10; /* 确保按钮在SVG之上 */ } </style>
2. 修正HTML的ID属性写法
将错误的ID格式改为标准写法:
<body> <h1 id="prob_identifier">ID: 96543210</h1> <h2 id="student_id">1</h2> </body>
3. 修复React组件渲染逻辑
ProbProfile组件需返回合法JSX,并在生命周期钩子中执行异步请求:
class ProbProfile extends React.Component { constructor(props) { super(props); this.state = {ProbID:'', ProbDesc:'', userID:''}; } // 组件挂载后执行数据请求 componentDidMount() { this.getData(this.props.pg); } getData(pg) { // 原异步请求代码不变 } render() { return ( <div> <h2>Getting data</h2> </div> ); } } // 初始化时正确渲染组件 ReactDOM.createRoot(document.querySelector("#maxwell_container")).render(<ProbProfile pg={pg} />);
4. 增强按钮容器显示优先级
在按钮组件中添加明确样式,确保不被隐藏:
// 修改RepeaterWithContinue组件的返回样式 return ( <div style={{ display: "block", position: "relative", zIndex: 10, padding: "10px" }}> <button type="button" onClick={() => {start();started.current = true; }}>Start</button> <button type="button" onClick={() => evaluateRef.current = true}> Evaluate </button> <button type="button" onClick={() => continueRef.current = true}> Continue </button> </div> );
内容的提问来源于stack exchange,提问作者Blue Wizard
相关产品推荐
相关产品推荐

