xiangjsoncraft 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +180 -68
- package/config.json +205 -10
- package/index.html +43 -9
- package/package.json +14 -9
- package/renderJson.js +80 -21
package/README.md
CHANGED
|
@@ -1,17 +1,56 @@
|
|
|
1
|
+
# XiangJsonCraft 软件包 官方文档
|
|
1
2
|
|
|
2
3
|

|
|
3
4
|
|
|
5
|
+
XiangJsonCraft 是一个简单而强大的 JSON 配置与 HTML 页面渲染工具,由大学生董翔开发,专为前端开发者设计。通过简洁的 API,它允许你使用 JSON 配置文件来定义样式和内容,并将其应用到 HTML 页面中,实现动态页面的快速构建。
|
|
4
6
|
|
|
7
|
+
## 🚀 最新更新 (v1.1.0)
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
我们很高兴地宣布 XiangJsonCraft v1.1.0 版本发布!这个版本带来了重大功能升级,让 JSON 配置网页的能力得到质的飞跃:
|
|
10
|
+
|
|
11
|
+
### 核心增强
|
|
12
|
+
- **全面支持任意 CSS 选择器**:不再局限于预设元素,现在可通过 JSON 配置任何 CSS 选择器(类、ID、伪类、媒体查询等)
|
|
13
|
+
- **增强的渲染逻辑**:重构了渲染引擎,支持更复杂的样式结构和内容类型
|
|
14
|
+
- **响应式设计支持**:通过媒体查询配置,轻松实现不同屏幕尺寸的适配
|
|
15
|
+
- **HTML 内容支持**:不仅能设置文本内容,还可以配置 HTML 片段
|
|
7
16
|
|
|
8
|
-
|
|
17
|
+
### 配置示例升级
|
|
18
|
+
旧版本:
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"styles": {
|
|
22
|
+
"body": { ... },
|
|
23
|
+
"header": { ... }
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
新版本支持:
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"styles": {
|
|
32
|
+
".card": { ... },
|
|
33
|
+
"#hero-section": { ... },
|
|
34
|
+
"nav a:hover": { ... },
|
|
35
|
+
"@media (max-width: 768px)": { ... }
|
|
36
|
+
},
|
|
37
|
+
"content": {
|
|
38
|
+
".title": {
|
|
39
|
+
"value": "<strong>欢迎使用</strong>",
|
|
40
|
+
"isHtml": true
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
9
45
|
|
|
10
46
|
## 特性
|
|
11
47
|
|
|
12
48
|
- **简单易用**:只需几行代码即可完成页面渲染
|
|
13
49
|
- **灵活配置**:通过 JSON 文件定义样式和内容
|
|
14
50
|
- **轻量级**:无额外依赖,体积小巧
|
|
51
|
+
- **全面的选择器支持**:兼容所有 CSS 选择器语法
|
|
52
|
+
- **响应式设计**:轻松配置不同设备的显示效果
|
|
53
|
+
- **动态内容**:支持文本和 HTML 内容的动态注入
|
|
15
54
|
|
|
16
55
|
## 安装
|
|
17
56
|
|
|
@@ -23,37 +62,60 @@ npm install xiangjsoncraft
|
|
|
23
62
|
|
|
24
63
|
### 1. 创建 JSON 配置文件
|
|
25
64
|
|
|
26
|
-
|
|
65
|
+
创建 `config.json` 配置文件,定义页面的样式和内容:
|
|
27
66
|
|
|
28
67
|
```json
|
|
29
68
|
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"padding": "10px",
|
|
41
|
-
"backgroundColor": "azure"
|
|
42
|
-
},
|
|
43
|
-
"headerP": {
|
|
44
|
-
"color": "black",
|
|
45
|
-
"fontSize": "16px"
|
|
46
|
-
}
|
|
69
|
+
"styles": {
|
|
70
|
+
"*": {
|
|
71
|
+
"margin": "0",
|
|
72
|
+
"padding": "0",
|
|
73
|
+
"boxSizing": "border-box"
|
|
74
|
+
},
|
|
75
|
+
"body": {
|
|
76
|
+
"fontFamily": "Arial, sans-serif",
|
|
77
|
+
"lineHeight": "1.6",
|
|
78
|
+
"color": "#333"
|
|
47
79
|
},
|
|
48
|
-
"
|
|
49
|
-
|
|
80
|
+
".header": {
|
|
81
|
+
"backgroundColor": "#2c3e50",
|
|
82
|
+
"color": "white",
|
|
83
|
+
"padding": "1rem",
|
|
84
|
+
"textAlign": "center"
|
|
85
|
+
},
|
|
86
|
+
"nav ul": {
|
|
87
|
+
"display": "flex",
|
|
88
|
+
"listStyle": "none",
|
|
89
|
+
"justifyContent": "center",
|
|
90
|
+
"gap": "1rem"
|
|
91
|
+
},
|
|
92
|
+
"nav a:hover": {
|
|
93
|
+
"color": "#f39c12",
|
|
94
|
+
"textDecoration": "none"
|
|
95
|
+
},
|
|
96
|
+
"@media (max-width: 768px)": {
|
|
97
|
+
"nav ul": {
|
|
98
|
+
"flexDirection": "column",
|
|
99
|
+
"alignItems": "center"
|
|
100
|
+
}
|
|
50
101
|
}
|
|
102
|
+
},
|
|
103
|
+
"content": {
|
|
104
|
+
".header h1": {
|
|
105
|
+
"value": "我的网站",
|
|
106
|
+
"isHtml": false
|
|
107
|
+
},
|
|
108
|
+
"#intro": {
|
|
109
|
+
"value": "<p>欢迎访问我的网站</p>",
|
|
110
|
+
"isHtml": true
|
|
111
|
+
}
|
|
112
|
+
}
|
|
51
113
|
}
|
|
52
114
|
```
|
|
53
115
|
|
|
54
116
|
### 2. 创建 HTML 页面
|
|
55
117
|
|
|
56
|
-
|
|
118
|
+
创建 `index.html` 页面:
|
|
57
119
|
|
|
58
120
|
```html
|
|
59
121
|
<!DOCTYPE html>
|
|
@@ -61,84 +123,145 @@ npm install xiangjsoncraft
|
|
|
61
123
|
<head>
|
|
62
124
|
<meta charset="UTF-8">
|
|
63
125
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
64
|
-
<title>
|
|
65
|
-
<style id="
|
|
126
|
+
<title>XiangJsonCraft 示例</title>
|
|
127
|
+
<style id="dynamic-styles"></style>
|
|
66
128
|
</head>
|
|
67
129
|
<body>
|
|
68
|
-
<header>
|
|
69
|
-
<
|
|
130
|
+
<header class="header">
|
|
131
|
+
<h1></h1>
|
|
70
132
|
</header>
|
|
71
|
-
|
|
133
|
+
<nav>
|
|
134
|
+
<ul>
|
|
135
|
+
<li><a href="#">首页</a></li>
|
|
136
|
+
<li><a href="#">关于</a></li>
|
|
137
|
+
<li><a href="#">联系</a></li>
|
|
138
|
+
</ul>
|
|
139
|
+
</nav>
|
|
140
|
+
<div id="intro"></div>
|
|
141
|
+
|
|
72
142
|
<script type="module">
|
|
73
|
-
import {
|
|
74
|
-
|
|
143
|
+
import { renderJsonStyles } from './renderJson.js';
|
|
144
|
+
renderJsonStyles();
|
|
75
145
|
</script>
|
|
76
146
|
</body>
|
|
77
147
|
</html>
|
|
78
148
|
```
|
|
79
149
|
|
|
80
|
-
### 3.
|
|
150
|
+
### 3. 渲染逻辑
|
|
81
151
|
|
|
82
|
-
|
|
152
|
+
`renderJson.js` 中的渲染函数:
|
|
83
153
|
|
|
84
154
|
```javascript
|
|
85
|
-
// 定义 replaceCamelCase
|
|
155
|
+
// 定义 replaceCamelCase 方法,用于将驼峰式命名转换为连字符命名
|
|
86
156
|
String.prototype.replaceCamelCase = function (separator = '-') {
|
|
87
157
|
return this.replace(/[A-Z]/g, function (match) {
|
|
88
158
|
return separator + match.toLowerCase();
|
|
89
159
|
});
|
|
90
160
|
};
|
|
91
161
|
|
|
92
|
-
//
|
|
93
|
-
function
|
|
94
|
-
// 使用
|
|
162
|
+
// 封装通用JSON样式渲染函数,支持任意CSS选择器
|
|
163
|
+
function renderJsonStyles() {
|
|
164
|
+
// 使用fetch API获取JSON配置文件
|
|
95
165
|
fetch('./config.json')
|
|
96
166
|
.then(response => {
|
|
97
|
-
// 检查响应是否成功
|
|
98
167
|
if (!response.ok) {
|
|
99
|
-
throw new Error(
|
|
168
|
+
throw new Error(`网络响应失败: ${response.status}`);
|
|
100
169
|
}
|
|
101
|
-
// 将响应转换为 JSON 格式
|
|
102
170
|
return response.json();
|
|
103
171
|
})
|
|
104
172
|
.then(config => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
173
|
+
const styleBlock = document.getElementById('dynamic-styles') || createStyleBlock();
|
|
174
|
+
|
|
175
|
+
// 生成CSS规则
|
|
176
|
+
let cssRules = '';
|
|
177
|
+
|
|
178
|
+
// 处理所有选择器样式
|
|
179
|
+
if (config.styles && typeof config.styles === 'object') {
|
|
180
|
+
// 遍历所有选择器
|
|
181
|
+
Object.entries(config.styles).forEach(([selector, styles]) => {
|
|
182
|
+
// 生成该选择器的所有样式属性
|
|
183
|
+
const styleProperties = Object.entries(styles)
|
|
184
|
+
.map(([prop, value]) => {
|
|
185
|
+
// 将驼峰式属性名转换为CSS格式(如fontSize -> font-size)
|
|
186
|
+
const cssProp = prop.replaceCamelCase();
|
|
187
|
+
return `${cssProp}: ${value};`;
|
|
188
|
+
})
|
|
189
|
+
.join('\n ');
|
|
190
|
+
|
|
191
|
+
// 添加选择器及其样式到CSS规则
|
|
192
|
+
cssRules += `${selector} {\n ${styleProperties}\n}\n\n`;
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 处理内容配置
|
|
197
|
+
if (config.content && typeof config.content === 'object') {
|
|
198
|
+
Object.entries(config.content).forEach(([selector, content]) => {
|
|
199
|
+
const elements = document.querySelectorAll(selector);
|
|
200
|
+
elements.forEach(el => {
|
|
201
|
+
// 支持HTML内容或纯文本
|
|
202
|
+
if (content.isHtml) {
|
|
203
|
+
el.innerHTML = content.value;
|
|
204
|
+
} else {
|
|
205
|
+
el.textContent = content.value;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// 将生成的CSS应用到样式块
|
|
212
|
+
styleBlock.innerHTML = cssRules;
|
|
115
213
|
})
|
|
116
214
|
.catch(error => {
|
|
117
|
-
console.error('
|
|
215
|
+
console.error('处理样式配置时出错:', error);
|
|
118
216
|
});
|
|
119
217
|
}
|
|
120
218
|
|
|
219
|
+
// 创建样式块并添加到文档头部
|
|
220
|
+
function createStyleBlock() {
|
|
221
|
+
const style = document.createElement('style');
|
|
222
|
+
style.id = 'dynamic-styles';
|
|
223
|
+
document.head.appendChild(style);
|
|
224
|
+
return style;
|
|
225
|
+
}
|
|
226
|
+
|
|
121
227
|
// 导出渲染函数
|
|
122
|
-
export {
|
|
228
|
+
export { renderJsonStyles };
|
|
123
229
|
```
|
|
124
230
|
|
|
125
231
|
### 4. 运行项目
|
|
126
232
|
|
|
127
|
-
|
|
233
|
+
```bash
|
|
234
|
+
# 运行开发服务器
|
|
235
|
+
npm run dev
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
在浏览器中访问 `http://localhost:3000` 即可查看效果。
|
|
128
239
|
|
|
129
240
|
## API 文档
|
|
130
241
|
|
|
131
|
-
### `
|
|
242
|
+
### `renderJsonStyles()`
|
|
132
243
|
|
|
133
244
|
从 `config.json` 文件中读取样式和内容配置,并将其应用到 HTML 页面中。
|
|
134
245
|
|
|
135
246
|
#### 示例
|
|
136
247
|
|
|
137
248
|
```javascript
|
|
138
|
-
import {
|
|
139
|
-
|
|
249
|
+
import { renderJsonStyles } from './renderJson.js';
|
|
250
|
+
renderJsonStyles();
|
|
140
251
|
```
|
|
141
252
|
|
|
253
|
+
## 配置说明
|
|
254
|
+
|
|
255
|
+
配置文件结构:
|
|
256
|
+
|
|
257
|
+
- **`styles`**:包含所有CSS样式配置,键为CSS选择器,值为样式属性对象
|
|
258
|
+
- 支持所有CSS选择器(类、ID、伪类、媒体查询等)
|
|
259
|
+
- 样式属性支持驼峰命名(如`fontSize`会自动转换为`font-size`)
|
|
260
|
+
|
|
261
|
+
- **`content`**:包含所有内容配置,键为CSS选择器,值为内容对象
|
|
262
|
+
- `value`:要设置的内容(文本或HTML)
|
|
263
|
+
- `isHtml`:布尔值,指示内容是否为HTML片段
|
|
264
|
+
|
|
142
265
|
## 彩蛋
|
|
143
266
|
|
|
144
267
|
```markdown
|
|
@@ -156,21 +279,11 @@ renderJson();
|
|
|
156
279
|
对别人来说,改node_modules是“碰别人的代码”;但对我来说,改的是“自己写的工具”。知道怎么调整既不破坏核心功能,又能贴合朋友的习惯,这份底气,其实来自“开发者”这个身份最本质的掌控感。
|
|
157
280
|
|
|
158
281
|
所以如果你用的时候也有小想法,不用怕“改坏”——工具本身就为“灵活适配”留足了空间,而作为作者,我也始终在背后,为它的稳定和好用托底。
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
要不要我把这段花絮再调整得更口语化一些?或者补充一些你和朋友当时对话的细节,让整个故事更有画面感?
|
|
162
|
-
|
|
163
282
|
```
|
|
164
283
|
|
|
165
284
|
## 贡献指南
|
|
166
285
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
1. 克隆仓库:`git clone https://github.com/dxiang-wiki/xiangjsoncraft.git`
|
|
170
|
-
2. 创建新分支:`git checkout -b feature/your-feature`
|
|
171
|
-
3. 提交代码:`git commit -m "Add your feature"`
|
|
172
|
-
4. 推送分支:`git push origin feature/your-feature`
|
|
173
|
-
5. 创建 Pull Request
|
|
286
|
+
我们欢迎任何人贡献代码或提出建议。如果你想参与开发,请通过邮件联系我们。
|
|
174
287
|
|
|
175
288
|
## 许可证
|
|
176
289
|
|
|
@@ -200,7 +313,6 @@ SOFTWARE.
|
|
|
200
313
|
|
|
201
314
|
如果你有任何问题或建议,请通过以下方式联系我们:
|
|
202
315
|
|
|
203
|
-
- GitHub Issues: https://github.com/dxiang-wiki/xiangjsoncraft/issues
|
|
204
316
|
- Email: 3631247406@qq.com
|
|
205
317
|
|
|
206
|
-
感谢使用 XiangJsonCraft!
|
|
318
|
+
感谢使用 XiangJsonCraft!
|
package/config.json
CHANGED
|
@@ -1,23 +1,218 @@
|
|
|
1
1
|
{
|
|
2
2
|
"styles": {
|
|
3
|
-
"
|
|
3
|
+
"*": {
|
|
4
4
|
"margin": "0",
|
|
5
5
|
"padding": "0",
|
|
6
|
-
"boxSizing": "border-box"
|
|
6
|
+
"boxSizing": "border-box",
|
|
7
|
+
"fontFamily": "'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif"
|
|
8
|
+
},
|
|
9
|
+
"body": {
|
|
10
|
+
"backgroundColor": "#f0f4f8",
|
|
11
|
+
"color": "#334e68",
|
|
12
|
+
"lineHeight": "1.6",
|
|
13
|
+
"transition": "backgroundColor 0.5s ease",
|
|
14
|
+
"minHeight": "100vh"
|
|
15
|
+
},
|
|
16
|
+
".welcome-container": {
|
|
17
|
+
"maxWidth": "1200px",
|
|
18
|
+
"margin": "0 auto",
|
|
19
|
+
"padding": "20px"
|
|
20
|
+
},
|
|
21
|
+
".welcome-header": {
|
|
22
|
+
"textAlign": "center",
|
|
23
|
+
"padding": "60px 20px",
|
|
24
|
+
"marginBottom": "40px",
|
|
25
|
+
"borderRadius": "12px",
|
|
26
|
+
"background": "linear-gradient(135deg, #4299e1, #63b3ed)",
|
|
27
|
+
"color": "white",
|
|
28
|
+
"boxShadow": "0 10px 25px -5px rgba(66, 153, 225, 0.3)",
|
|
29
|
+
"transition": "transform 0.5s ease, boxShadow 0.5s ease"
|
|
7
30
|
},
|
|
8
|
-
"header": {
|
|
31
|
+
".welcome-header:hover": {
|
|
32
|
+
"transform": "translateY(-5px)",
|
|
33
|
+
"boxShadow": "0 15px 30px -8px rgba(66, 153, 225, 0.4)"
|
|
34
|
+
},
|
|
35
|
+
".logo-container": {
|
|
36
|
+
"marginBottom": "30px"
|
|
37
|
+
},
|
|
38
|
+
".logo": {
|
|
39
|
+
"width": "120px",
|
|
40
|
+
"height": "120px",
|
|
41
|
+
"margin": "0 auto",
|
|
42
|
+
"backgroundColor": "white",
|
|
43
|
+
"borderRadius": "50%",
|
|
9
44
|
"display": "flex",
|
|
45
|
+
"alignItems": "center",
|
|
10
46
|
"justifyContent": "center",
|
|
47
|
+
"fontSize": "48px",
|
|
48
|
+
"color": "#4299e1",
|
|
49
|
+
"boxShadow": "0 4px 12px rgba(0, 0, 0, 0.1)"
|
|
50
|
+
},
|
|
51
|
+
".logo::after": {
|
|
52
|
+
"content": "'J'",
|
|
53
|
+
"fontWeight": "bold"
|
|
54
|
+
},
|
|
55
|
+
".main-title": {
|
|
56
|
+
"fontSize": "2.5rem",
|
|
57
|
+
"marginBottom": "15px",
|
|
58
|
+
"textShadow": "0 2px 4px rgba(0, 0, 0, 0.1)"
|
|
59
|
+
},
|
|
60
|
+
"@media (maxWidth: 768px)": {
|
|
61
|
+
".main-title": {
|
|
62
|
+
"fontSize": "2rem"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
".subtitle": {
|
|
66
|
+
"fontSize": "1.1rem",
|
|
67
|
+
"opacity": "0.9",
|
|
68
|
+
"maxWidth": "600px",
|
|
69
|
+
"margin": "0 auto"
|
|
70
|
+
},
|
|
71
|
+
".features-section": {
|
|
72
|
+
"display": "grid",
|
|
73
|
+
"gridTemplateColumns": "repeat(auto-fit, minmax(300px, 1fr))",
|
|
74
|
+
"gap": "30px",
|
|
75
|
+
"marginBottom": "60px"
|
|
76
|
+
},
|
|
77
|
+
".feature-card": {
|
|
78
|
+
"backgroundColor": "white",
|
|
79
|
+
"borderRadius": "12px",
|
|
80
|
+
"padding": "30px",
|
|
81
|
+
"boxShadow": "0 4px 12px rgba(0, 0, 0, 0.05)",
|
|
82
|
+
"transition": "transform 0.3s ease, boxShadow 0.3s ease"
|
|
83
|
+
},
|
|
84
|
+
".feature-card:hover": {
|
|
85
|
+
"transform": "translateY(-8px)",
|
|
86
|
+
"boxShadow": "0 12px 20px rgba(0, 0, 0, 0.08)"
|
|
87
|
+
},
|
|
88
|
+
".feature-icon": {
|
|
89
|
+
"width": "60px",
|
|
90
|
+
"height": "60px",
|
|
91
|
+
"borderRadius": "12px",
|
|
92
|
+
"backgroundColor": "#ebf8ff",
|
|
93
|
+
"color": "#4299e1",
|
|
94
|
+
"display": "flex",
|
|
11
95
|
"alignItems": "center",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
96
|
+
"justifyContent": "center",
|
|
97
|
+
"fontSize": "24px",
|
|
98
|
+
"marginBottom": "20px"
|
|
99
|
+
},
|
|
100
|
+
".feature-title": {
|
|
101
|
+
"fontSize": "1.3rem",
|
|
102
|
+
"marginBottom": "15px",
|
|
103
|
+
"color": "#2d3748"
|
|
14
104
|
},
|
|
15
|
-
"
|
|
16
|
-
"color": "
|
|
17
|
-
"
|
|
18
|
-
}
|
|
105
|
+
".feature-description": {
|
|
106
|
+
"color": "#718096",
|
|
107
|
+
"lineHeight": "1.7"
|
|
108
|
+
},
|
|
109
|
+
".action-section": {
|
|
110
|
+
"textAlign": "center",
|
|
111
|
+
"marginBottom": "80px"
|
|
112
|
+
},
|
|
113
|
+
".primary-button": {
|
|
114
|
+
"backgroundColor": "#4299e1",
|
|
115
|
+
"color": "white",
|
|
116
|
+
"border": "none",
|
|
117
|
+
"borderRadius": "8px",
|
|
118
|
+
"padding": "14px 32px",
|
|
119
|
+
"fontSize": "1rem",
|
|
120
|
+
"fontWeight": "600",
|
|
121
|
+
"cursor": "pointer",
|
|
122
|
+
"transition": "all 0.3s ease",
|
|
123
|
+
"boxShadow": "0 4px 6px rgba(66, 153, 225, 0.2)"
|
|
124
|
+
},
|
|
125
|
+
".primary-button:hover": {
|
|
126
|
+
"backgroundColor": "#3182ce",
|
|
127
|
+
"transform": "translateY(-2px)",
|
|
128
|
+
"boxShadow": "0 6px 10px rgba(66, 153, 225, 0.3)"
|
|
129
|
+
},
|
|
130
|
+
".additional-info": {
|
|
131
|
+
"marginTop": "15px",
|
|
132
|
+
"color": "#718096",
|
|
133
|
+
"fontSize": "0.95rem"
|
|
134
|
+
},
|
|
135
|
+
".page-footer": {
|
|
136
|
+
"textAlign": "center",
|
|
137
|
+
"paddingTop": "30px",
|
|
138
|
+
"borderTop": "1px solid #e2e8f0",
|
|
139
|
+
"color": "#718096"
|
|
140
|
+
},
|
|
141
|
+
".copyright": {
|
|
142
|
+
"marginBottom": "15px",
|
|
143
|
+
"fontSize": "0.9rem"
|
|
144
|
+
},
|
|
145
|
+
".social-links": {
|
|
146
|
+
"display": "flex",
|
|
147
|
+
"justifyContent": "center",
|
|
148
|
+
"gap": "15px"
|
|
149
|
+
},
|
|
150
|
+
".social-icon": {
|
|
151
|
+
"color": "#718096",
|
|
152
|
+
"fontSize": "1.2rem",
|
|
153
|
+
"transition": "color 0.3s ease"
|
|
154
|
+
},
|
|
155
|
+
".social-icon:hover": {
|
|
156
|
+
"color": "#4299e1"
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
"body:not(.loaded) .welcome-header": {
|
|
160
|
+
"opacity": "0",
|
|
161
|
+
"transform": "translateY(20px)"
|
|
162
|
+
},
|
|
163
|
+
"body.loaded .welcome-header": {
|
|
164
|
+
"opacity": "1",
|
|
165
|
+
"transform": "translateY(0)",
|
|
166
|
+
"transition": "opacity 0.8s ease, transform 0.8s ease"
|
|
167
|
+
},
|
|
168
|
+
"body:not(.loaded) .feature-card": {
|
|
169
|
+
"opacity": "0",
|
|
170
|
+
"transform": "scale(0.95)"
|
|
171
|
+
},
|
|
172
|
+
"body.loaded .feature-card": {
|
|
173
|
+
"opacity": "1",
|
|
174
|
+
"transform": "scale(1)",
|
|
175
|
+
"transition": "opacity 0.6s ease, transform 0.6s ease"
|
|
176
|
+
},
|
|
177
|
+
"body.loaded .feature-card:nth-child(1)": { "transitionDelay": "0.2s" },
|
|
178
|
+
"body.loaded .feature-card:nth-child(2)": { "transitionDelay": "0.4s" },
|
|
179
|
+
"body.loaded .feature-card:nth-child(3)": { "transitionDelay": "0.6s" }
|
|
19
180
|
},
|
|
20
181
|
"content": {
|
|
21
|
-
"
|
|
182
|
+
".main-title": "Welcome to xiangjsoncraft",
|
|
183
|
+
".subtitle": "Create beautiful web pages with simple JSON configuration",
|
|
184
|
+
".primary-button": "Get Started",
|
|
185
|
+
".additional-info": "Join thousands of developers using our JSON configuration system",
|
|
186
|
+
".copyright": "© 2025 Dong Xiang. All rights reserved."
|
|
187
|
+
},
|
|
188
|
+
"features": {
|
|
189
|
+
"selectorPrefix": "#feature",
|
|
190
|
+
"items": [
|
|
191
|
+
{
|
|
192
|
+
"iconClass": "fas fa-code",
|
|
193
|
+
"title": "Simple Configuration",
|
|
194
|
+
"description": "Define your entire page style and content with easy-to-understand JSON"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"iconClass": "fas fa-paint-brush",
|
|
198
|
+
"title": "Beautiful Designs",
|
|
199
|
+
"description": "Create stunning interfaces without writing complex CSS code"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"iconClass": "fas fa-mobile-alt",
|
|
203
|
+
"title": "Responsive by Default",
|
|
204
|
+
"description": "Your pages will look great on all devices with built-in responsiveness"
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
"icons": {
|
|
209
|
+
"selector": ".social-links",
|
|
210
|
+
"items": [
|
|
211
|
+
{ "class": "fab fa-github", "url": "#" },
|
|
212
|
+
{ "class": "fab fa-twitter", "url": "#" },
|
|
213
|
+
{ "class": "fab fa-linkedin", "url": "#" },
|
|
214
|
+
{ "class": "fab fa-instagram", "url": "#" }
|
|
215
|
+
]
|
|
22
216
|
}
|
|
23
217
|
}
|
|
218
|
+
|
package/index.html
CHANGED
|
@@ -1,19 +1,53 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
+
|
|
3
4
|
<head>
|
|
4
5
|
<meta charset="UTF-8">
|
|
5
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>
|
|
7
|
-
<
|
|
7
|
+
<title>Welcome Page</title>
|
|
8
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
9
|
+
<style id="dynamic-styles"></style>
|
|
8
10
|
</head>
|
|
11
|
+
|
|
9
12
|
<body>
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
<div class="welcome-container">
|
|
14
|
+
<header class="welcome-header">
|
|
15
|
+
<div class="logo-container">
|
|
16
|
+
<div class="logo"></div>
|
|
17
|
+
</div>
|
|
18
|
+
<h1 class="main-title"></h1>
|
|
19
|
+
<p class="subtitle"></p>
|
|
20
|
+
</header>
|
|
21
|
+
|
|
22
|
+
<main class="features-section">
|
|
23
|
+
<div class="feature-card" id="feature-1"></div>
|
|
24
|
+
<div class="feature-card" id="feature-2"></div>
|
|
25
|
+
<div class="feature-card" id="feature-3"></div>
|
|
26
|
+
</main>
|
|
27
|
+
|
|
28
|
+
<section class="action-section">
|
|
29
|
+
<a href="https://www.npmjs.com/package/xiangjsoncraft">
|
|
30
|
+
<button class="primary-button"></button>
|
|
31
|
+
</a>
|
|
32
|
+
<p class="additional-info"></p>
|
|
33
|
+
</section>
|
|
34
|
+
|
|
35
|
+
<footer class="page-footer">
|
|
36
|
+
<p class="copyright"></p>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class="social-links">
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
</footer>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
14
46
|
<script type="module">
|
|
15
|
-
import {
|
|
16
|
-
|
|
47
|
+
import { renderJsonStyles } from './renderJson.js';
|
|
48
|
+
// 页面加载完成后渲染
|
|
49
|
+
window.addEventListener('DOMContentLoaded', renderJsonStyles);
|
|
17
50
|
</script>
|
|
18
51
|
</body>
|
|
19
|
-
|
|
52
|
+
|
|
53
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xiangjsoncraft",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Create beautiful web pages with simple JSON configuration",
|
|
5
5
|
"main": "renderJson.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
+
"dev": "npx live-server . --port=3000"
|
|
8
9
|
},
|
|
9
|
-
"keywords": [
|
|
10
|
+
"keywords": [
|
|
11
|
+
"json",
|
|
12
|
+
"css",
|
|
13
|
+
"html",
|
|
14
|
+
"configuration",
|
|
15
|
+
"ui",
|
|
16
|
+
"web"
|
|
17
|
+
],
|
|
10
18
|
"author": "",
|
|
11
|
-
"license": "
|
|
12
|
-
"type": "
|
|
13
|
-
"__npminstall_done": true,
|
|
14
|
-
"_from": "xiangjsoncraft@1.0.3",
|
|
15
|
-
"_resolved": "https://registry.npmmirror.com/xiangjsoncraft/-/xiangjsoncraft-1.0.3.tgz"
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"type": "module"
|
|
16
21
|
}
|
package/renderJson.js
CHANGED
|
@@ -1,38 +1,97 @@
|
|
|
1
|
-
//
|
|
1
|
+
// 定义驼峰式命名转换方法
|
|
2
2
|
String.prototype.replaceCamelCase = function (separator = '-') {
|
|
3
3
|
return this.replace(/[A-Z]/g, function (match) {
|
|
4
4
|
return separator + match.toLowerCase();
|
|
5
5
|
});
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
function
|
|
10
|
-
|
|
8
|
+
// 创建样式块工具函数
|
|
9
|
+
function createStyleBlock() {
|
|
10
|
+
const style = document.createElement('style');
|
|
11
|
+
style.id = 'dynamic-styles';
|
|
12
|
+
document.head.appendChild(style);
|
|
13
|
+
return style;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 渲染图标函数
|
|
17
|
+
function renderIcons(selector, icons) {
|
|
18
|
+
const container = document.querySelector(selector);
|
|
19
|
+
if (!container) return;
|
|
20
|
+
|
|
21
|
+
container.innerHTML = icons.map(icon => `
|
|
22
|
+
<a href="${icon.url}" class="social-icon" target="_blank" rel="noopener">
|
|
23
|
+
<i class="${icon.class}"></i>
|
|
24
|
+
</a>
|
|
25
|
+
`).join('');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 渲染特性卡片函数
|
|
29
|
+
function renderFeatureCards(selectorPrefix, features) {
|
|
30
|
+
features.forEach((feature, index) => {
|
|
31
|
+
const card = document.querySelector(`${selectorPrefix}-${index + 1}`);
|
|
32
|
+
if (card) {
|
|
33
|
+
card.innerHTML = `
|
|
34
|
+
<div class="feature-icon"><i class="${feature.iconClass}"></i></div>
|
|
35
|
+
<h3 class="feature-title">${feature.title}</h3>
|
|
36
|
+
<p class="feature-description">${feature.description}</p>
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 主渲染函数
|
|
43
|
+
export function renderJsonStyles() {
|
|
11
44
|
fetch('./config.json')
|
|
12
45
|
.then(response => {
|
|
13
|
-
// 检查响应是否成功
|
|
14
46
|
if (!response.ok) {
|
|
15
|
-
throw new Error(
|
|
47
|
+
throw new Error(`网络响应失败: ${response.status}`);
|
|
16
48
|
}
|
|
17
|
-
// 将响应转换为 JSON 格式
|
|
18
49
|
return response.json();
|
|
19
50
|
})
|
|
20
51
|
.then(config => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
52
|
+
const styleBlock = document.getElementById('dynamic-styles') || createStyleBlock();
|
|
53
|
+
let cssRules = '';
|
|
54
|
+
|
|
55
|
+
// 处理所有样式
|
|
56
|
+
if (config.styles && typeof config.styles === 'object') {
|
|
57
|
+
Object.entries(config.styles).forEach(([selector, styles]) => {
|
|
58
|
+
const styleProperties = Object.entries(styles)
|
|
59
|
+
.map(([prop, value]) => `${prop.replaceCamelCase()}: ${value};`)
|
|
60
|
+
.join('\n ');
|
|
61
|
+
|
|
62
|
+
cssRules += `${selector} {\n ${styleProperties}\n}\n\n`;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 应用CSS规则
|
|
67
|
+
styleBlock.innerHTML = cssRules;
|
|
68
|
+
|
|
69
|
+
// 处理文本内容
|
|
70
|
+
if (config.content && typeof config.content === 'object') {
|
|
71
|
+
Object.entries(config.content).forEach(([selector, content]) => {
|
|
72
|
+
const elements = document.querySelectorAll(selector);
|
|
73
|
+
elements.forEach(el => {
|
|
74
|
+
el.textContent = content;
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 渲染图标
|
|
80
|
+
if (config.icons) {
|
|
81
|
+
renderIcons(config.icons.selector, config.icons.items);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 渲染特性卡片
|
|
85
|
+
if (config.features) {
|
|
86
|
+
renderFeatureCards(config.features.selectorPrefix, config.features.items);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 添加页面载入动画类
|
|
90
|
+
document.body.classList.add('loaded');
|
|
91
|
+
|
|
31
92
|
})
|
|
32
93
|
.catch(error => {
|
|
33
|
-
console.error('
|
|
94
|
+
console.error('处理配置时出错:', error);
|
|
34
95
|
});
|
|
35
96
|
}
|
|
36
|
-
|
|
37
|
-
// 导出渲染函数
|
|
38
|
-
export { renderJson };
|
|
97
|
+
|