前端:简易备忘录

本程序为基于网页的安卓程序,通过HBuilder打包。这是一个传统的方法,总体来说非常的简单易上手。试试吧,相信你也可以的。

步骤概述

程序共包含三个文件:

  1. HTML文件:页面的基本结构包括事件和截止日期的输入、添加事件的按钮和显示事件的部分。
  2. CSS文件:包含页面的样式与布局。应用样式是为了确保应用程序看起来干净,并满足基于截止日期突出显示事件的要求。
  3. JavaScript文件:负责实现具体功能。该脚本处理添加、删除和显示事件。

调试
此部分主要借助HTML/CSS/JS 在线工具(https://www.jyshare.com/front-end/61/)完成。只要将三个代码在对应的文本框中,就可以预览程序。其实时预览的功能和简洁明了的操作界面令人难忘。

打包
此部分使用Hbuilder(https://dcloud.io/hbuilderx.html)。貌似该软件并不支持本地打包,但也许可能是我不会用,总之需要注册并实名认证Dcloud社区(https://dcloud.io/index.html)。

  1. 新建项目:文件>>新建>>1.项目
  2. 准备文件:打开新建文件夹位置。仅保留manifest.josn,其余删除。新建index.html,scripts.js,styles.css,分别对应html文件,JavaScript文件和css文件。
  3. 配置程序:在HBuilder中查看manifest.josn。
    基础配置:应用名
    图标配置:在ICOFINDER(https://www.iconfinder.com/)中下载1024x1024的图标即可自动生成其他大小的图标。
    启动界面:个人偏向于选择一个纯白图片。主要原因有二,其一相比于黑屏,摆平可以暗示应用正在启动而不是手机关了,其二制作三个大小的启动图太麻烦了。
    模块配置:去掉不必要的模块,可以减少权限索取。这有利于在减少程序性能开销的同时,通过程序权限索取少暗示提高用户对程序的好感(这种暗示的效果因人而异,一般需要一个或两个权限索取作为暗示前提,本程序中使用隐私协议代替)
    其他:根据需要自行调整。调不明白就别瞎动,保持默认。
  4. 打包程序:发行>>App-Android/iOS-云打包
    Android证书:测试打包则使用公共测试证书。发行则需要生成证书(https://ask.dcloud.net.cn/article/35777
    广告:记得取消勾选,没有开屏广告会藏家用户好感度。
    选择传统打包并打包。等待打包完成后,根据控制台提示下载APK安装包即可。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ToDo List</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>ToDO List</h1>
<form id="todoForm">
<div class="add-event">
<input type="text" id="eventInput" placeholder="Event">
<input type="date" id="deadlineInput">
<button type="button" onclick="addEvent()">Add Event</button>
</div>
</form>
<div id="todoList"></div>
<p class="author">by @Berny-DIf</p>
</div>
<script src="scripts.js"></script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 20px;
}

.container {
width: 100%; /* 初始设置为100%宽度 */
max-width: 600px; /* 最大宽度限制为600px */
margin: auto;
background: white;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* 使用媒体查询调整大屏幕上的最大宽度 */
@media (min-width: 768px) {
.container {
max-width: 80%; /* 在中等及以上屏幕宽度时,使用80%的宽度 */
}
}

@media (min-width: 1024px) {
.container {
max-width: 600px; /* 在大屏幕时,恢复最大宽度为600px */
}
}

h1 {
text-align: center;
}

#todoForm {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
}

.add-event {
display: flex;
flex-direction: column;
justify-content: center; /* 垂直居中 */
width: 100%; /* 确保占满父容器的宽度 */
}

#todoForm input[type="text"], #todoForm input[type="date"] {
width: 100%; /* 父容器的全宽 */
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box; /* 确保padding包含在宽度内 */
}

#todoForm button {
padding: 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
width: 100%; /* 父容器的全宽 */
}

#todoForm button:hover {
background-color: #0056b3;
}

/* 其余样式保持不变 */

.todo-item {
position: relative; /* 添加相对定位 */
padding: 10px 30px; /* 增加右侧内边距以确保按钮不遮挡内容 */
border-bottom: 1px solid #ddd;
}

.delete-button { /* 删除按钮的样式 */
position: absolute;
top: 50%;
right: 10px;
transform: translateY(-50%);
background-color: #c1c4ad; /* 灰色背景 */
color: white;
border: none;
border-radius: 5px;
padding: 5px 10px;
cursor: pointer;
}

.delete-button:hover {
background-color: #c82333; /* 悬停时的红色加深 */
}

.today {
background-color: #ffeb3b;
}

.past, .future {
border-left: 5px solid transparent;
}

.past {
border-left-color: #191970;
}

.future {
border-left-color: #ffa000;
}

.divider {
height: 1px;
background-color: #ddd;
margin: 20px 0;
}

.author {
text-align: center;
font-size: 0.8em;
color: #777;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

document.addEventListener('DOMContentLoaded', () => {
const todoList = document.getElementById('todoList');
const todoForm = document.getElementById('todoForm');
let todos = JSON.parse(localStorage.getItem('todos')) || [];

//I want to build an Android todolist app, so generate mobile response code with HTML, CSS and Javascript
// Function to render the todo list
function renderTodoList() {
todoList.innerHTML = '';

todos.sort((a, b) => new Date(a.deadline) - new Date(b.deadline));

const today = new Date().toISOString().split('T')[0];

let todayItems = [], futureItems = [], pastItems = [];

todos.forEach(todo => {
const todoDate = new Date(todo.deadline).toISOString().split('T')[0];

if (todoDate === today) {
todayItems.push(todo);
} else if (todoDate > today) {
futureItems.push(todo);
} else {
const daysAgo = Math.round(((new Date(today) - new Date(todoDate)) / (1000 * 60 * 60 * 24)));
if (daysAgo >= 32) {
const index = todos.indexOf(todo);
if (index > -1) {
todos.splice(index, 1);
}
} else {
pastItems.push(todo);
}
}
});

// Render Today's Items
renderSection(todayItems, 'Today', 'today');

// Divider for Future Items
if (todayItems.length > 0 && futureItems.length > 0) {
const divider = document.createElement('div');
divider.classList.add('divider');
todoList.appendChild(divider);
}

// Render Future Items
renderSection(futureItems, 'Future', 'future');

// Divider for Past Items (only if both today and future items exist)
if ((todayItems.length > 0 || futureItems.length > 0) && pastItems.length > 0) {
const divider = document.createElement('div');
divider.classList.add('divider');
todoList.appendChild(divider);
}

// Render Past Items
renderSection(pastItems, 'Past', 'past');

localStorage.setItem('todos', JSON.stringify(todos));
}

// Helper function to render sections
function renderSection(items, sectionName, className) {
if (items.length > 0) {
const header = document.createElement('h3');
header.textContent = sectionName;
todoList.appendChild(header);

items.forEach(todo => {
const div = document.createElement('div');
div.classList.add('todo-item', className);
div.textContent = `${todo.event} - ${todo.deadline}`;

// Add delete button
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.classList.add('delete-button');
deleteButton.onclick = () => {
todos = todos.filter(t => t !== todo);
renderTodoList();
};

div.appendChild(deleteButton);
todoList.appendChild(div);
});
}
}

// Add event listener to form
window.addEvent = function() {
const eventInput = document.getElementById('eventInput').value;
const deadlineInput = document.getElementById('deadlineInput').value;

if (eventInput && deadlineInput) {
todos.push({ event: eventInput, deadline: deadlineInput });
renderTodoList();
todoForm.reset();
}
};

function formatDate(dateStr) {
const date = new Date(dateStr);
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要加1
const day = String(date.getDate()).padStart(2, '0');
const year = date.getFullYear();
return `${month}-${day}-${year}`;
}

// Initial render
renderTodoList();
});

桌面显示效果
功能效果

其他打包方式:cordovahttps://cordova.apache.org/#getstarted,本次没有用到,记下留着下次再研究研究。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2025 John Doe
  • Visitors: | Views:

请我喝杯茶吧~

支付宝
微信