|
@@ -0,0 +1,204 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="en">
|
|
|
+
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
+ <title>Document</title>
|
|
|
+ <script src="./babel.min.js"></script>
|
|
|
+ <script src="./react.development.js"></script>
|
|
|
+ <script src="./react-dom.development.js"></script>
|
|
|
+</head>
|
|
|
+
|
|
|
+<body>
|
|
|
+ <div id="root"></div>
|
|
|
+ <script type="text/babel">
|
|
|
+ const root = ReactDOM.createRoot(document.getElementById("root"));
|
|
|
+ function App() {
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <EmojiPicker />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ class EmojiPicker extends React.Component {
|
|
|
+ constructor(props) {
|
|
|
+ super(props);
|
|
|
+ this.state = {
|
|
|
+ // 选中的表情索引,-1表示未选择
|
|
|
+ selectedIndex: -1,
|
|
|
+ // 悬停的表情索引,-1表示无悬停
|
|
|
+ hoverIndex: -1
|
|
|
+ };
|
|
|
+
|
|
|
+ // 绑定事件处理函数
|
|
|
+ this.handleSelect = this.handleSelect.bind(this);
|
|
|
+ this.handleHover = this.handleHover.bind(this);
|
|
|
+ this.handleLeave = this.handleLeave.bind(this);
|
|
|
+ this.clearSelection = this.clearSelection.bind(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表情数据
|
|
|
+ emojis = [
|
|
|
+ { symbol: '😊', name: '开心' },
|
|
|
+ { symbol: '😍', name: '爱慕' },
|
|
|
+ { symbol: '😂', name: '大笑' },
|
|
|
+ { symbol: '😢', name: '难过' },
|
|
|
+ { symbol: '😠', name: '生气' },
|
|
|
+ { symbol: '😲', name: '惊讶' },
|
|
|
+ { symbol: '😴', name: '困倦' },
|
|
|
+ { symbol: '🤔', name: '思考' }
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 选择表情
|
|
|
+ handleSelect(index) {
|
|
|
+ this.setState({
|
|
|
+ selectedIndex: index
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 鼠标悬停表情
|
|
|
+ handleHover(index) {
|
|
|
+ this.setState({
|
|
|
+ hoverIndex: index
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 鼠标离开表情
|
|
|
+ handleLeave() {
|
|
|
+ this.setState({
|
|
|
+ hoverIndex: -1
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清除选择
|
|
|
+ clearSelection() {
|
|
|
+ this.setState({
|
|
|
+ selectedIndex: -1
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ render() {
|
|
|
+ const { selectedIndex, hoverIndex } = this.state;
|
|
|
+ const selectedEmoji = selectedIndex !== -1 ? this.emojis[selectedIndex] : null;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div style={containerStyle}>
|
|
|
+ <h2 style={titleStyle}>表情选择器</h2>
|
|
|
+
|
|
|
+ {/* 表情选择区域 */}
|
|
|
+ <div style={emojiGridStyle}>
|
|
|
+ {this.emojis.map((emoji, index) => (
|
|
|
+ <div
|
|
|
+ key={index}
|
|
|
+ onClick={() => this.handleSelect(index)}
|
|
|
+ onMouseEnter={() => this.handleHover(index)}
|
|
|
+ onMouseLeave={this.handleLeave}
|
|
|
+ style={{
|
|
|
+ ...emojiItemStyle,
|
|
|
+ // 选中或悬停时的样式
|
|
|
+ transform: (selectedIndex === index || hoverIndex === index)
|
|
|
+ ? 'scale(1.2)'
|
|
|
+ : 'scale(1)',
|
|
|
+ backgroundColor: selectedIndex === index ? '#e3f2fd' : 'transparent',
|
|
|
+ borderColor: selectedIndex === index ? '#2196F3' : '#eee'
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <span style={emojiSymbolStyle}>{emoji.symbol}</span>
|
|
|
+ <span style={emojiNameStyle}>{emoji.name}</span>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 选择结果 */}
|
|
|
+ {selectedEmoji && (
|
|
|
+ <div style={selectionResultStyle}>
|
|
|
+ <p>你选择了:{selectedEmoji.symbol} {selectedEmoji.name}</p>
|
|
|
+ <button
|
|
|
+ onClick={this.clearSelection}
|
|
|
+ style={clearButtonStyle}
|
|
|
+ >
|
|
|
+ 清除选择
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {!selectedEmoji && (
|
|
|
+ <p style={instructionStyle}>请点击一个表情来表达你的心情</p>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 样式定义
|
|
|
+ const containerStyle = {
|
|
|
+ maxWidth: '600px',
|
|
|
+ margin: '20px auto',
|
|
|
+ padding: '20px',
|
|
|
+ textAlign: 'center',
|
|
|
+ fontFamily: 'Arial, sans-serif',
|
|
|
+ border: '1px solid #e0e0e0',
|
|
|
+ borderRadius: '10px',
|
|
|
+ boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
|
|
+ };
|
|
|
+
|
|
|
+ const titleStyle = {
|
|
|
+ color: '#333',
|
|
|
+ marginBottom: '25px'
|
|
|
+ };
|
|
|
+
|
|
|
+ const emojiGridStyle = {
|
|
|
+ display: 'grid',
|
|
|
+ gridTemplateColumns: 'repeat(4, 1fr)',
|
|
|
+ gap: '15px',
|
|
|
+ marginBottom: '25px'
|
|
|
+ };
|
|
|
+
|
|
|
+ const emojiItemStyle = {
|
|
|
+ padding: '15px 10px',
|
|
|
+ border: '1px solid #eee',
|
|
|
+ borderRadius: '8px',
|
|
|
+ cursor: 'pointer',
|
|
|
+ transition: 'all 0.2s ease',
|
|
|
+ };
|
|
|
+
|
|
|
+ const emojiSymbolStyle = {
|
|
|
+ fontSize: '32px',
|
|
|
+ display: 'block',
|
|
|
+ marginBottom: '5px'
|
|
|
+ };
|
|
|
+
|
|
|
+ const emojiNameStyle = {
|
|
|
+ fontSize: '14px',
|
|
|
+ color: '#666'
|
|
|
+ };
|
|
|
+
|
|
|
+ const selectionResultStyle = {
|
|
|
+ padding: '15px',
|
|
|
+ backgroundColor: '#f8f9fa',
|
|
|
+ borderRadius: '8px',
|
|
|
+ marginBottom: '10px'
|
|
|
+ };
|
|
|
+
|
|
|
+ const clearButtonStyle = {
|
|
|
+ padding: '6px 12px',
|
|
|
+ marginTop: '10px',
|
|
|
+ backgroundColor: '#f44336',
|
|
|
+ color: 'white',
|
|
|
+ border: 'none',
|
|
|
+ borderRadius: '4px',
|
|
|
+ cursor: 'pointer',
|
|
|
+ fontSize: '14px'
|
|
|
+ };
|
|
|
+
|
|
|
+ const instructionStyle = {
|
|
|
+ color: '#666',
|
|
|
+ fontStyle: 'italic'
|
|
|
+ };
|
|
|
+
|
|
|
+ root.render(<App />);
|
|
|
+ </script>
|
|
|
+</body>
|
|
|
+
|
|
|
+</html>
|