xiangjsoncraft 1.0.4 → 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 +201 -64
- 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,15 +1,56 @@
|
|
|
1
|
+
# XiangJsonCraft 软件包 官方文档
|
|
1
2
|
|
|
2
3
|

|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
XiangJsonCraft 是一个简单而强大的 JSON 配置与 HTML 页面渲染工具,由大学生董翔开发,专为前端开发者设计。通过简洁的 API,它允许你使用 JSON 配置文件来定义样式和内容,并将其应用到 HTML 页面中,实现动态页面的快速构建。
|
|
6
|
+
|
|
7
|
+
## 🚀 最新更新 (v1.1.0)
|
|
5
8
|
|
|
6
|
-
XiangJsonCraft
|
|
9
|
+
我们很高兴地宣布 XiangJsonCraft v1.1.0 版本发布!这个版本带来了重大功能升级,让 JSON 配置网页的能力得到质的飞跃:
|
|
10
|
+
|
|
11
|
+
### 核心增强
|
|
12
|
+
- **全面支持任意 CSS 选择器**:不再局限于预设元素,现在可通过 JSON 配置任何 CSS 选择器(类、ID、伪类、媒体查询等)
|
|
13
|
+
- **增强的渲染逻辑**:重构了渲染引擎,支持更复杂的样式结构和内容类型
|
|
14
|
+
- **响应式设计支持**:通过媒体查询配置,轻松实现不同屏幕尺寸的适配
|
|
15
|
+
- **HTML 内容支持**:不仅能设置文本内容,还可以配置 HTML 片段
|
|
16
|
+
|
|
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
|
+
```
|
|
7
45
|
|
|
8
46
|
## 特性
|
|
9
47
|
|
|
10
48
|
- **简单易用**:只需几行代码即可完成页面渲染
|
|
11
49
|
- **灵活配置**:通过 JSON 文件定义样式和内容
|
|
12
50
|
- **轻量级**:无额外依赖,体积小巧
|
|
51
|
+
- **全面的选择器支持**:兼容所有 CSS 选择器语法
|
|
52
|
+
- **响应式设计**:轻松配置不同设备的显示效果
|
|
53
|
+
- **动态内容**:支持文本和 HTML 内容的动态注入
|
|
13
54
|
|
|
14
55
|
## 安装
|
|
15
56
|
|
|
@@ -21,37 +62,60 @@ npm install xiangjsoncraft
|
|
|
21
62
|
|
|
22
63
|
### 1. 创建 JSON 配置文件
|
|
23
64
|
|
|
24
|
-
|
|
65
|
+
创建 `config.json` 配置文件,定义页面的样式和内容:
|
|
25
66
|
|
|
26
67
|
```json
|
|
27
68
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
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"
|
|
79
|
+
},
|
|
80
|
+
".header": {
|
|
81
|
+
"backgroundColor": "#2c3e50",
|
|
82
|
+
"color": "white",
|
|
83
|
+
"padding": "1rem",
|
|
84
|
+
"textAlign": "center"
|
|
45
85
|
},
|
|
46
|
-
"
|
|
47
|
-
|
|
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
|
+
}
|
|
48
101
|
}
|
|
102
|
+
},
|
|
103
|
+
"content": {
|
|
104
|
+
".header h1": {
|
|
105
|
+
"value": "我的网站",
|
|
106
|
+
"isHtml": false
|
|
107
|
+
},
|
|
108
|
+
"#intro": {
|
|
109
|
+
"value": "<p>欢迎访问我的网站</p>",
|
|
110
|
+
"isHtml": true
|
|
111
|
+
}
|
|
112
|
+
}
|
|
49
113
|
}
|
|
50
114
|
```
|
|
51
115
|
|
|
52
116
|
### 2. 创建 HTML 页面
|
|
53
117
|
|
|
54
|
-
|
|
118
|
+
创建 `index.html` 页面:
|
|
55
119
|
|
|
56
120
|
```html
|
|
57
121
|
<!DOCTYPE html>
|
|
@@ -59,93 +123,167 @@ npm install xiangjsoncraft
|
|
|
59
123
|
<head>
|
|
60
124
|
<meta charset="UTF-8">
|
|
61
125
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
62
|
-
<title>
|
|
63
|
-
<style id="
|
|
126
|
+
<title>XiangJsonCraft 示例</title>
|
|
127
|
+
<style id="dynamic-styles"></style>
|
|
64
128
|
</head>
|
|
65
129
|
<body>
|
|
66
|
-
<header>
|
|
67
|
-
<
|
|
130
|
+
<header class="header">
|
|
131
|
+
<h1></h1>
|
|
68
132
|
</header>
|
|
69
|
-
|
|
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
|
+
|
|
70
142
|
<script type="module">
|
|
71
|
-
import {
|
|
72
|
-
|
|
143
|
+
import { renderJsonStyles } from './renderJson.js';
|
|
144
|
+
renderJsonStyles();
|
|
73
145
|
</script>
|
|
74
146
|
</body>
|
|
75
147
|
</html>
|
|
76
148
|
```
|
|
77
149
|
|
|
78
|
-
### 3.
|
|
150
|
+
### 3. 渲染逻辑
|
|
79
151
|
|
|
80
|
-
|
|
152
|
+
`renderJson.js` 中的渲染函数:
|
|
81
153
|
|
|
82
154
|
```javascript
|
|
83
|
-
// 定义 replaceCamelCase
|
|
155
|
+
// 定义 replaceCamelCase 方法,用于将驼峰式命名转换为连字符命名
|
|
84
156
|
String.prototype.replaceCamelCase = function (separator = '-') {
|
|
85
157
|
return this.replace(/[A-Z]/g, function (match) {
|
|
86
158
|
return separator + match.toLowerCase();
|
|
87
159
|
});
|
|
88
160
|
};
|
|
89
161
|
|
|
90
|
-
//
|
|
91
|
-
function
|
|
92
|
-
// 使用
|
|
162
|
+
// 封装通用JSON样式渲染函数,支持任意CSS选择器
|
|
163
|
+
function renderJsonStyles() {
|
|
164
|
+
// 使用fetch API获取JSON配置文件
|
|
93
165
|
fetch('./config.json')
|
|
94
166
|
.then(response => {
|
|
95
|
-
// 检查响应是否成功
|
|
96
167
|
if (!response.ok) {
|
|
97
|
-
throw new Error(
|
|
168
|
+
throw new Error(`网络响应失败: ${response.status}`);
|
|
98
169
|
}
|
|
99
|
-
// 将响应转换为 JSON 格式
|
|
100
170
|
return response.json();
|
|
101
171
|
})
|
|
102
172
|
.then(config => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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;
|
|
113
213
|
})
|
|
114
214
|
.catch(error => {
|
|
115
|
-
console.error('
|
|
215
|
+
console.error('处理样式配置时出错:', error);
|
|
116
216
|
});
|
|
117
217
|
}
|
|
118
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
|
+
|
|
119
227
|
// 导出渲染函数
|
|
120
|
-
export {
|
|
228
|
+
export { renderJsonStyles };
|
|
121
229
|
```
|
|
122
230
|
|
|
123
231
|
### 4. 运行项目
|
|
124
232
|
|
|
125
|
-
|
|
233
|
+
```bash
|
|
234
|
+
# 运行开发服务器
|
|
235
|
+
npm run dev
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
在浏览器中访问 `http://localhost:3000` 即可查看效果。
|
|
126
239
|
|
|
127
240
|
## API 文档
|
|
128
241
|
|
|
129
|
-
### `
|
|
242
|
+
### `renderJsonStyles()`
|
|
130
243
|
|
|
131
244
|
从 `config.json` 文件中读取样式和内容配置,并将其应用到 HTML 页面中。
|
|
132
245
|
|
|
133
246
|
#### 示例
|
|
134
247
|
|
|
135
248
|
```javascript
|
|
136
|
-
import {
|
|
137
|
-
|
|
249
|
+
import { renderJsonStyles } from './renderJson.js';
|
|
250
|
+
renderJsonStyles();
|
|
138
251
|
```
|
|
139
252
|
|
|
140
|
-
##
|
|
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片段
|
|
141
264
|
|
|
142
|
-
|
|
265
|
+
## 彩蛋
|
|
266
|
+
|
|
267
|
+
```markdown
|
|
268
|
+
# 工具背后的小插曲:“敢改包”的底气来源
|
|
269
|
+
其实XiangJsonCraft的诞生,还藏着一段有趣的小场景——
|
|
270
|
+
|
|
271
|
+
某天,朋友在Vue项目里用这个包时,遇到了个不符合自己编程习惯的小细节,对着node_modules里的代码犯愁:“老师说这地方不能随便改,容易牵一发而动全身。”
|
|
272
|
+
|
|
273
|
+
我当时笑着回了句:“没事,改不坏。”朋友反问:“你怎么这么自信?难道你会用?”
|
|
274
|
+
|
|
275
|
+
我故意顿了顿,笑着说:“哼?我会吗……”
|
|
276
|
+
|
|
277
|
+
其实不是“会用”,是“会造”——整个包的每一行代码,都是我从0到1敲出来的。哪里是样式配置的核心逻辑,哪部分是内容渲染的关键节点,甚至每个变量命名的小心思,早就刻在脑子里了。
|
|
278
|
+
|
|
279
|
+
对别人来说,改node_modules是“碰别人的代码”;但对我来说,改的是“自己写的工具”。知道怎么调整既不破坏核心功能,又能贴合朋友的习惯,这份底气,其实来自“开发者”这个身份最本质的掌控感。
|
|
280
|
+
|
|
281
|
+
所以如果你用的时候也有小想法,不用怕“改坏”——工具本身就为“灵活适配”留足了空间,而作为作者,我也始终在背后,为它的稳定和好用托底。
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## 贡献指南
|
|
143
285
|
|
|
144
|
-
|
|
145
|
-
2. 创建新分支:`git checkout -b feature/your-feature`
|
|
146
|
-
3. 提交代码:`git commit -m "Add your feature"`
|
|
147
|
-
4. 推送分支:`git push origin feature/your-feature`
|
|
148
|
-
5. 创建 Pull Request
|
|
286
|
+
我们欢迎任何人贡献代码或提出建议。如果你想参与开发,请通过邮件联系我们。
|
|
149
287
|
|
|
150
288
|
## 许可证
|
|
151
289
|
|
|
@@ -175,7 +313,6 @@ SOFTWARE.
|
|
|
175
313
|
|
|
176
314
|
如果你有任何问题或建议,请通过以下方式联系我们:
|
|
177
315
|
|
|
178
|
-
- GitHub Issues: https://github.com/dxiang-wiki/xiangjsoncraft/issues
|
|
179
316
|
- Email: 3631247406@qq.com
|
|
180
317
|
|
|
181
|
-
感谢使用 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
|
+
|