fix: page

This commit is contained in:
xion 2024-12-08 12:54:57 +08:00
parent a4f03c76eb
commit b5dde4e823
4 changed files with 114 additions and 9 deletions

View File

@ -11,6 +11,89 @@
<h1>Welcome to the Demo Page</h1> <h1>Welcome to the Demo Page</h1>
<p>This is a basic HTML template.</p> <p>This is a basic HTML template.</p>
<script src="./src/index.ts" type="module"></script> <script src="./src/index.ts" type="module"></script>
<form action="/submit" method="POST">
<label for="browser">选择浏览器:</label>
<input list="browsers" id="browser" name="browser" />
<datalist id="browsers">
<option value="Chrome">
<option value="Firefox">
<option value="Safari">
<option value="Edge">
</datalist>
<button type="submit">提交</button>
</form>
<style>
.custom-datalist-wrapper {
position: relative;
width: 200px;
}
.custom-datalist-input {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.custom-datalist-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
border: 1px solid #ccc;
border-radius: 4px;
max-height: 150px;
overflow-y: auto;
display: none;
z-index: 1000;
}
.custom-datalist-dropdown.active {
display: block;
}
.custom-datalist-item {
padding: 8px;
cursor: pointer;
}
.custom-datalist-item:hover {
background-color: #f0f0f0;
}
</style>
<div class="custom-datalist-wrapper">
<input type="text" class="custom-datalist-input" placeholder="选择或输入..." oninput="filterDatalist(this)" />
<div class="custom-datalist-dropdown" id="datalist-dropdown">
<div class="custom-datalist-item" onclick="selectDatalistItem(this)">Apple</div>
<div class="custom-datalist-item" onclick="selectDatalistItem(this)">Banana</div>
<div class="custom-datalist-item" onclick="selectDatalistItem(this)">Cherry</div>
<div class="custom-datalist-item" onclick="selectDatalistItem(this)">Date</div>
</div>
</div>
<script>
function filterDatalist(input) {
const filter = input.value.toLowerCase();
const dropdown = document.getElementById('datalist-dropdown');
const items = dropdown.querySelectorAll('.custom-datalist-item');
dropdown.classList.add('active');
items.forEach(item => {
item.style.display = item.textContent.toLowerCase().includes(filter) ? 'block' : 'none';
});
}
function selectDatalistItem(item) {
const input = document.querySelector('.custom-datalist-input');
input.value = item.textContent;
const dropdown = document.getElementById('datalist-dropdown');
dropdown.classList.remove('active');
}
</script>
</body> </body>
</html> </html>

View File

@ -4,9 +4,15 @@ import { Page } from '@kevisual/store/page';
const page = new Page({ const page = new Page({
isListen: true, isListen: true,
}); });
page.addPage('/', 'home');
page.addPage('/:id', 'user'); page.addPage('/:id', 'user');
page.subscribe(
'home',
(params, state) => {
console.log('home', params, 'state', state);
return;
},
);
page.subscribe('user', (params, state) => { page.subscribe('user', (params, state) => {
console.log('user', params, 'state', state); console.log('user', params, 'state', state);
return; return;

View File

@ -1,12 +1,13 @@
{ {
"name": "@kevisual/store", "name": "@kevisual/store",
"version": "0.0.1-alpha.4", "version": "0.0.1-alpha.5",
"main": "dist/store.js", "main": "dist/store.js",
"module": "dist/store.js", "module": "dist/store.js",
"types": "dist/store.d.ts", "types": "dist/store.d.ts",
"private": false, "private": false,
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "rollup -c -w",
"build": "npm run clean && rollup -c", "build": "npm run clean && rollup -c",
"build:app": "npm run build && rsync dist/* ../deploy/dist", "build:app": "npm run build && rsync dist/* ../deploy/dist",
"clean": "rm -rf dist" "clean": "rm -rf dist"

View File

@ -38,12 +38,22 @@ export class Page {
this.listen(); this.listen();
} }
} }
popstate(event?: PopStateEvent, manual?: boolean) { popstate(event?: PopStateEvent, manualOpts?: { id?: string; type: 'singal' | 'all' }) {
const pathname = window.location.pathname; const pathname = window.location.pathname;
if (manualOpts) {
if (manualOpts.type === 'singal') {
const item = this.callbacks.find((item) => item.id === manualOpts.id);
if (item) {
const result = this.check(item.key, pathname);
result && item.fn?.(result.params, event.state, { event });
}
return;
}
}
// manual 为true时表示手动调用不需要检查是否相等 // manual 为true时表示手动调用不需要检查是否相等
this.callbacks.forEach((item) => { this.callbacks.forEach((item) => {
const result = this.check(item.key, pathname); const result = this.check(item.key, pathname);
result && item.fn?.(result.params, event.state, { event, manual }); result && item.fn?.(result.params, event.state, { event, manualOpts });
}); });
} }
listen() { listen() {
@ -118,7 +128,12 @@ export class Page {
} }
this.callbacks.push({ key, fn, id: id, path }); this.callbacks.push({ key, fn, id: id, path });
if (runImmediately) { if (runImmediately) {
this.popstate({ state: window.history.state } as any, true); const location = window.location;
const pathname = opts?.pathname ?? location.pathname;
const result = this.check(key, pathname);
if (result) {
this.popstate({ state: window.history.state } as any, { id, type: 'singal' });
}
} }
return () => { return () => {
this.callbacks = this.callbacks.filter((item) => item.id !== id); this.callbacks = this.callbacks.filter((item) => item.id !== id);
@ -169,18 +184,18 @@ export class Page {
window.history.pushState(state, '', this.basename + path); window.history.pushState(state, '', this.basename + path);
let _check = check ?? true; let _check = check ?? true;
if (_check) { if (_check) {
this.popstate({ state } as any, true); this.popstate({ state } as any, { type: 'all' });
} }
} }
replace(path: string, state?: any, check?: boolean) { replace(path: string, state?: any, check?: boolean) {
let _check = check ?? true; let _check = check ?? true;
window.history.replaceState(state, '', this.basename + path); window.history.replaceState(state, '', this.basename + path);
if (_check) { if (_check) {
this.popstate({ state } as any, true); this.popstate({ state } as any, { type: 'all' });
} }
} }
refresh() { refresh() {
const state = window.history.state; const state = window.history.state;
this.popstate({ state } as any, true); this.popstate({ state } as any, { type: 'all' });
} }
} }