Valeri173

DomashnoReact

Jan 24th, 2022
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.05 KB | None | 0 0
  1. //HTML
  2. <div id="errors" style="
  3. background: #c00;
  4. color: #fff;
  5. display: none;
  6. margin: -20px -20px 20px;
  7. padding: 20px;
  8. white-space: pre-wrap;
  9. "></div>
  10. <div id="root"></div>
  11. <script>
  12. window.addEventListener('mousedown', function(e) {
  13. document.body.classList.add('mouse-navigation');
  14. document.body.classList.remove('kbd-navigation');
  15. });
  16. window.addEventListener('keydown', function(e) {
  17. if (e.keyCode === 9) {
  18. document.body.classList.add('kbd-navigation');
  19. document.body.classList.remove('mouse-navigation');
  20. }
  21. });
  22. window.addEventListener('click', function(e) {
  23. if (e.target.tagName === 'A' && e.target.getAttribute('href') === '#') {
  24. e.preventDefault();
  25. }
  26. });
  27. window.onerror = function(message, source, line, col, error) {
  28. var text = error ? error.stack || error : message + ' (at ' + source + ':' + line + ':' + col + ')';
  29. errors.textContent += text + '\n';
  30. errors.style.display = '';
  31. };
  32. console.error = (function(old) {
  33. return function error() {
  34. errors.textContent += Array.prototype.slice.call(arguments).join(' ') + '\n';
  35. errors.style.display = '';
  36. old.apply(this, arguments);
  37. }
  38. })(console.error);
  39. </script>
  40.  
  41. //CSS
  42. body {
  43. font: 14px "Century Gothic", Futura, sans-serif;
  44. margin: 20px;
  45. }
  46.  
  47. ol, ul {
  48. padding-left: 30px;
  49. }
  50.  
  51. .board-row:after {
  52. clear: both;
  53. content: "";
  54. display: table;
  55. }
  56.  
  57. .status {
  58. margin-bottom: 10px;
  59. }
  60.  
  61. .square {
  62. background: #fff;
  63. border: 1px solid #999;
  64. float: left;
  65. font-size: 24px;
  66. font-weight: bold;
  67. line-height: 34px;
  68. height: 34px;
  69. margin-right: -1px;
  70. margin-top: -1px;
  71. padding: 0;
  72. text-align: center;
  73. width: 34px;
  74. }
  75.  
  76. .square:focus {
  77. outline: none;
  78. }
  79.  
  80. .kbd-navigation .square:focus {
  81. background: #ddd;
  82. }
  83.  
  84. .game {
  85. display: flex;
  86. flex-direction: row;
  87. }
  88.  
  89. .game-info {
  90. margin-left: 20px;
  91. }
  92.  
  93. //JavaScript
  94. function Square(props) {
  95. return (
  96. <button className="square" onClick={props.onClick}>
  97. {props.value}
  98. </button>
  99. );
  100. }
  101.  
  102. class Board extends React.Component {
  103. renderSquare(i) {
  104. return (
  105. <Square
  106. value={this.props.squares[i]}
  107. onClick={() => this.props.onClick(i)}
  108. />
  109. );
  110. }
  111.  
  112. render() {
  113. return (
  114. <div>
  115. <div className="board-row">
  116. {this.renderSquare(0)}
  117. {this.renderSquare(1)}
  118. {this.renderSquare(2)}
  119. </div>
  120. <div className="board-row">
  121. {this.renderSquare(3)}
  122. {this.renderSquare(4)}
  123. {this.renderSquare(5)}
  124. </div>
  125. <div className="board-row">
  126. {this.renderSquare(6)}
  127. {this.renderSquare(7)}
  128. {this.renderSquare(8)}
  129. </div>
  130. </div>
  131. );
  132. }
  133. }
  134.  
  135. class Game extends React.Component {
  136. constructor(props) {
  137. super(props);
  138. this.state = {
  139. history: [
  140. {
  141. squares: Array(9).fill(null)
  142. }
  143. ],
  144. stepNumber: 0,
  145. xIsNext: true
  146. };
  147. }
  148.  
  149. handleClick(i) {
  150. const history = this.state.history.slice(0, this.state.stepNumber + 1);
  151. const current = history[history.length - 1];
  152. const squares = current.squares.slice();
  153. if (calculateWinner(squares) || squares[i]) {
  154. return;
  155. }
  156. squares[i] = this.state.xIsNext ? "X" : "O";
  157. this.setState({
  158. history: history.concat([
  159. {
  160. squares: squares
  161. }
  162. ]),
  163. stepNumber: history.length,
  164. xIsNext: !this.state.xIsNext
  165. });
  166. }
  167.  
  168. jumpTo(step) {
  169. this.setState({
  170. stepNumber: step,
  171. xIsNext: (step % 2) === 0
  172. });
  173. }
  174.  
  175. render() {
  176. const history = this.state.history;
  177. const current = history[this.state.stepNumber];
  178. const winner = calculateWinner(current.squares);
  179.  
  180. const moves = history.map((step, move) => {
  181. const desc = move ?
  182. 'Go to move #' + move :
  183. 'Go to game start';
  184. return (
  185. <li key={move}>
  186. <button onClick={() => this.jumpTo(move)}>{desc}</button>
  187. </li>
  188. );
  189. });
  190.  
  191. let status;
  192. if (winner) {
  193. status = "Winner: " + winner;
  194. } else {
  195. status = "Next player: " + (this.state.xIsNext ? "X" : "O");
  196. }
  197.  
  198. return (
  199. <div className="game">
  200. <div className="game-board">
  201. <Board
  202. squares={current.squares}
  203. onClick={i => this.handleClick(i)}
  204. />
  205. </div>
  206. <div className="game-info">
  207. <div>{status}</div>
  208. <ol>{moves}</ol>
  209. </div>
  210. </div>
  211. );
  212. }
  213. }
  214.  
  215. // ========================================
  216.  
  217. ReactDOM.render(<Game />, document.getElementById("root"));
  218.  
  219. function calculateWinner(squares) {
  220. const lines = [
  221. [0, 1, 2],
  222. [3, 4, 5],
  223. [6, 7, 8],
  224. [0, 3, 6],
  225. [1, 4, 7],
  226. [2, 5, 8],
  227. [0, 4, 8],
  228. [2, 4, 6]
  229. ];
  230. for (let i = 0; i < lines.length; i++) {
  231. const [a, b, c] = lines[i];
  232. if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
  233. return squares[a];
  234. }
  235. }
  236. return null;
  237. }
Advertisement
Add Comment
Please, Sign In to add comment