组件拆分
This commit is contained in:
parent
6428d81818
commit
573e40f4e2
20
index.js
20
index.js
@ -1,4 +1,5 @@
|
||||
import { div, span, pre, h1, p, ul, li } from './main.js'
|
||||
import { div, span, pre, h1, p, ul, li, button } from './main.js'
|
||||
import { Dialog } from './wigets/dialog.js'
|
||||
|
||||
// 动画三阶段
|
||||
// 1. 初始状态
|
||||
@ -12,13 +13,26 @@ document.body.appendChild(div.cursor_pointer.bg_red_500.overflow_clip.w_128.h_64
|
||||
h1.m('2rem').p({ top: '2rem' }).text('Widgets!'),
|
||||
p.m('2rem').p({ top: '2rem' }).text('是什么, 为什么, 怎么做?'),
|
||||
ul.m('2rem').p({ top: '2rem' }).childs([
|
||||
li.text('我们需要让事情变简单和直观, 只使用纯粹的js代码, 整个项目只有js文件, 而不必在 js 和 html 和 css 文件之间跳来跳去'),
|
||||
li.text('也许你需要让事情变简单直观, 只使用纯粹的js代码, 整个项目只有js文件, 而不必在 js 和 html 和 css 文件之间跳来跳去'),
|
||||
li.text('汲取了 pug 和 winicss 的灵感, 以及 flutter 的嵌套布局方式, pug 减少 html 冗余, winicss 减少 css 冗余'),
|
||||
li.text('这个库的唯一作用就是给dom对象添加了额外的操作方法, 且每个方法的返回值都是dom自身, 从而实现对dom对象的链式操作')
|
||||
]),
|
||||
|
||||
new button({
|
||||
textContent: '模态窗口 dialog',
|
||||
onclick: event => {
|
||||
document.body.appendChild(Dialog({
|
||||
children: [
|
||||
new span({ textContent: 'Hello world!' }),
|
||||
new span({ textContent: 'Hello world!' }),
|
||||
]
|
||||
}))
|
||||
}
|
||||
}),
|
||||
|
||||
//span.css('bg-red').m('2rem').p({ top: '2rem' }).text('Hello world!'),
|
||||
new span({ textContent: 'Hello world!' }),
|
||||
|
||||
|
||||
// 三类参数
|
||||
p.text(`
|
||||
span 是一个类(class), 直接实例化 (new span()) 将创建一个 span 元素(DOM对象). 实例化时可以传递参数, 它对应DOM对象的属性.
|
||||
|
98
main.js
98
main.js
@ -14,11 +14,10 @@ export function createElement({ innerText, innerHTML, textContent, readOnly, chi
|
||||
if (children) children.forEach(child => element.appendChild(child))
|
||||
|
||||
// 生成样式
|
||||
console.log('name:', __name)
|
||||
if (__name) console.log('name:', __name)
|
||||
|
||||
// 分解类名, 生成样式, 直接将样式赋予元素
|
||||
__name.split('.').map(name => name.split('_')).forEach(item => {
|
||||
console.log('item:', item)
|
||||
// 两个参数的情况下, 第一个参数是样式名, 第二个参数是样式值
|
||||
if (item.length === 2) {
|
||||
const [key, value] = item
|
||||
@ -62,10 +61,18 @@ export function createElement({ innerText, innerHTML, textContent, readOnly, chi
|
||||
return
|
||||
}
|
||||
|
||||
if (key === 'radius') {
|
||||
// TODO 支持颜色输入
|
||||
if (key === 'color') {
|
||||
element.style.color = value
|
||||
return
|
||||
}
|
||||
|
||||
// TODO 支持各角和单边圆角
|
||||
if (key === 'radius' || key === 'rounded') {
|
||||
element.style.borderRadius = value
|
||||
return
|
||||
}
|
||||
|
||||
if (key === 'font') {
|
||||
element.style.font = value
|
||||
return
|
||||
@ -79,27 +86,8 @@ export function createElement({ innerText, innerHTML, textContent, readOnly, chi
|
||||
return
|
||||
}
|
||||
}
|
||||
// px py mx my
|
||||
// p-1 p-2 p-3 p-4
|
||||
// m-1 m-2 m-3 m-4
|
||||
// w h z bg
|
||||
})
|
||||
|
||||
//const className = __name.split('.').map(name => name.replace(/_/g, '-')).join(' ')
|
||||
//console.log('className:', className, element.classList)
|
||||
//if (className) element.classList.add(...className.split(' '))
|
||||
//// 获取全局样式表, 如果不存在则添加一个
|
||||
//if (!document.styleSheets.length) {
|
||||
// document.head.appendChild(document.createElement('style'))
|
||||
//}
|
||||
//// 检查全局是否已经存在 cursor-pointer, 如果不存在则添加
|
||||
//const rules = Array.from(document.styleSheets[0].cssRules)
|
||||
//const styleSheet = document.styleSheets[0]
|
||||
//if (!rules.some(rule => rule.selectorText === '.cursor-pointer')) {
|
||||
// styleSheet.insertRule('.cursor-pointer { cursor: pointer; }')
|
||||
// console.log('insertRule:', styleSheet.cssRules)
|
||||
//}
|
||||
|
||||
// 为元素添加链式操作方法
|
||||
element.w = (width) => { element.style.width = width; return element }
|
||||
element.h = (height) => { element.style.height = height; return element }
|
||||
@ -225,9 +213,10 @@ export class BaseElement {
|
||||
export const proxy = new Proxy(BaseElement, {
|
||||
get(target, property) {
|
||||
if (property in target) {
|
||||
// 如果调用的是静态方法则在结尾附上 __name 参数
|
||||
const __name = this.__name || ''
|
||||
console.log('name:', __name)
|
||||
if (typeof target[property] === 'function') {
|
||||
console.log('function:', property)
|
||||
return function (...args) {
|
||||
return target[property](...args, __name)
|
||||
}
|
||||
@ -235,7 +224,6 @@ export const proxy = new Proxy(BaseElement, {
|
||||
return target[property]
|
||||
} else {
|
||||
const __name = this.__name ? this.__name + '.' + property : property
|
||||
console.log('__name:', __name)
|
||||
return new Proxy(target, { __name, get: this.get })
|
||||
}
|
||||
}
|
||||
@ -696,65 +684,3 @@ export class canvas extends BaseElement {
|
||||
super(options)
|
||||
}
|
||||
}
|
||||
|
||||
export function Avatar(options) {
|
||||
const element = createElement(options, 'img')
|
||||
element.onerror = () => element.src = '/favicon.ico'
|
||||
return element
|
||||
}
|
||||
|
||||
export function Dialog(options) {
|
||||
const element = createElement({
|
||||
tabIndex: 0,
|
||||
style: {
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 1000,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backdropFilter: 'blur(5px)',
|
||||
duration: '0.5s',
|
||||
transition: 'all 0.5s'
|
||||
},
|
||||
onclick: async event => {
|
||||
if (event.target !== event.currentTarget) return
|
||||
await event.target.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 100 }).finished
|
||||
await event.target.remove()
|
||||
},
|
||||
onkeydown: async event => {
|
||||
if (event.key !== 'Escape') return
|
||||
await event.target.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 100 }).finished
|
||||
await event.target.remove()
|
||||
},
|
||||
children: [
|
||||
createElement({
|
||||
...options,
|
||||
style: {
|
||||
position: 'fixed',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: '150px',
|
||||
boxShadow: '0 0 1em #ccc',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
...options.style,
|
||||
}
|
||||
})
|
||||
]
|
||||
})
|
||||
const observer = new MutationObserver(mutationsList => {
|
||||
for (const mutation of mutationsList) {
|
||||
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
|
||||
element.focus()
|
||||
element.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 100 }).finished
|
||||
return observer.disconnect()
|
||||
}
|
||||
}
|
||||
})
|
||||
observer.observe(document.body, { childList: true, subtree: true })
|
||||
return element
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@laniakeasupercluster/widgets",
|
||||
"description": "A simple widgets tracker",
|
||||
"version": "1.1.5",
|
||||
"version": "1.1.6",
|
||||
"type": "module",
|
||||
"main": "main.js",
|
||||
"author": "Laniakea Supercluster <huan0016@gmail.com>",
|
||||
|
7
wigets/avatar.js
Normal file
7
wigets/avatar.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { createElement } from '../main.js'
|
||||
|
||||
export function Avatar(options) {
|
||||
const element = createElement(options, 'img')
|
||||
element.onerror = () => element.src = '/favicon.ico'
|
||||
return element
|
||||
}
|
57
wigets/dialog.js
Normal file
57
wigets/dialog.js
Normal file
@ -0,0 +1,57 @@
|
||||
import { createElement } from '../main.js'
|
||||
|
||||
export function Dialog(options) {
|
||||
const element = createElement({
|
||||
tabIndex: 0,
|
||||
style: {
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 1000,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backdropFilter: 'blur(5px)',
|
||||
duration: '0.5s',
|
||||
transition: 'all 0.5s'
|
||||
},
|
||||
onclick: async event => {
|
||||
if (event.target !== event.currentTarget) return
|
||||
await event.target.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 100 }).finished
|
||||
await event.target.remove()
|
||||
},
|
||||
onkeydown: async event => {
|
||||
if (event.key !== 'Escape') return
|
||||
await event.target.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 100 }).finished
|
||||
await event.target.remove()
|
||||
},
|
||||
children: [
|
||||
createElement({
|
||||
...options,
|
||||
style: {
|
||||
position: 'fixed',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: '150px',
|
||||
boxShadow: '0 0 1em #ccc',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
...options.style,
|
||||
}
|
||||
})
|
||||
]
|
||||
})
|
||||
const observer = new MutationObserver(mutationsList => {
|
||||
for (const mutation of mutationsList) {
|
||||
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
|
||||
element.focus()
|
||||
element.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 100 }).finished
|
||||
return observer.disconnect()
|
||||
}
|
||||
}
|
||||
})
|
||||
observer.observe(document.body, { childList: true, subtree: true })
|
||||
return element
|
||||
}
|
7
wigets/navbar.js
Normal file
7
wigets/navbar.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { nav } from '../main.js'
|
||||
|
||||
export default function navbar(options) {
|
||||
return nav.bg_gray_500.w_full.h_12.childs([
|
||||
new span({ textContent: 'Hello world!' }),
|
||||
])
|
||||
}
|
Loading…
Reference in New Issue
Block a user