Dominic
Helper to quickly build up dom in javascript object format
Basic feature list:
- Just dom
- Basic dom construction by javascript object format
- Event
- Template by function
And here's some code! :+1:
Basic
var root = CreateElement('div', {
className: 'root',
parent: document.body,
width: 300,
height: 300,
background: 'darkgreen',
items: [
{ tag: 'div', width: 50, height: 50, text: 'Intro', display: 'inline-block', background: 'yellowgreen' },
{ tag: 'div', width: 200, background: 'lightgreen',
items: [
{ tag: 'div', width: 20, height: 20, background: 'red' },
{ tag: 'div', width: 20, height: 20, background: 'orange' },
]
}
],
created: function () {
},
appended: function () {
}
})
Result
Basic 2: Function as item
var outerScopeDataSource = [
{ name: 'yellow' },
{ name: 'green' },
{ name: 'pink' }
]
var root = CreateElement('div', {
className: 'root',
parent: document.body,
width: 300,
height: 300,
background: 'darkgreen',
items: [
{ tag: 'div', width: 50, height: 50, text: 'Intro', display: 'inline-block', background: 'yellowgreen',
items: [
function () {
return outerScopeDataSource.map(function (data) {
return { tag: 'custom-el', text: data.name }
})
}
]
},
{ tag: 'div', width: 200, background: 'lightgreen',
items: ['color', 'material'].map(function (val) {
return { tag: 'span', text: val }
})
}
]
})
Result
Basic 3: Share configures
var root = CreateElement('div', {
className: 'root',
parent: document.body,
width: '100%',
height: '100%',
defaults: {
display: 'inline-block',
height: '100%',
className: 'default-class',
style: {
verticalAlign: 'top'
}
},
items: [
{ tag: 'div', className: 'sidebar', width: 200, ref: 'sidebar', background: 'lightgreen',
},
{ tag: 'div', className: 'main', width: 'calc(100% - 200px)', ref: 'main', background: 'lightblue',
defaults: {
background: 'tomato',
margin: 5,
height: 50,
width: 50,
display: 'inline-block'
},
items: [
{ tag: 'div', text: 1 },
{ tag: 'div', text: 2 },
[3,4,5,6].map(function (v) { return { tag: 'div', text: v } }),
function () {
return [5,6,7,8].map(function (v) { return { tag: 'div', text: v } })
}
]
},
{ tag: 'test' }
]
})
- All direct children of root will have
display = 'inline-block', height = '100%'
- Only last child of root will have
class = 'default-class'
Result
Basic 4: Condition if
/ hide
var root = CreateElement('div', {
className: 'root',
parent: document.body,
width: '100%',
height: '100%',
defaults: {
display: 'inline-block',
height: '100%',
className: 'default-class',
style: {
verticalAlign: 'top'
}
},
items: [
{ tag: 'div', className: 'sidebar', width: 200, ref: 'sidebar', background: 'lightgreen' },
{ tag: 'div', className: 'main',
width: 'calc(100% - 200px)',
ref: 'main',
background: 'lightblue',
defaults: {
background: 'tomato',
margin: 5,
height: 50,
width: 50,
display: 'inline-block'
},
items: [
{ tag: 'div', text: 'First' },
{ tag: 'div', text: 'Second' },
[3,4,5,6].map(function (v, i) { return { tag: 'div', text: 'Value is: ' + v, if: v < 4 } }),
function () {
return [5,6,7,8].map(function (v, i) { return { tag: 'div', text: v, hide: v > 6 } })
}
]
}
]
})
Result
Attributes
var root = CreateElement('div', {
className: 'root',
id: 'root',
parent: document.body,
width: 300,
height: 300,
background: 'darkgreen',
padding: 5,
attrs: {
class: 'original',
dataTooltip: 'halo this is tip',
'data-id': 5
}
})
Result
Reference
var root = CreateElement('div', {
className: 'root',
parent: document.body,
width: 300,
height: 300,
background: 'darkgreen',
items: [
{ tag: 'div', width: 50, height: 50, text: 'Intro', display: 'inline-block', background: 'yellowgreen' },
{ tag: 'div', width: 200, background: 'lightgreen', ref: 'orange',
items: [
{ tag: 'div', width: 20, height: 20, background: 'red',
ref: 'lightgreen'
},
{ tag: 'div', width: 20, height: 20, background: 'orange',
ref: 'orange', refScope: 'parent'
},
]
}
]
})
Events
Reserved keyword for events:
- Mouse:
click
mousedown
mouseup
mouseover
mouseout
mouseenter
mouseleave
- Drag:
dragstart
dragend
drag
dragover
dragenter
dragout
drop
- Focus:
blur
focus
- Keyboard:
keydown
keypress
keyup
- Form:
change
input
submit
- Touch:
touchstart
touchmove
touchend
- Scroll:
wheel
scroll
var root = CreateElement('div', {
className: 'root',
id: 'root',
parent: document.body,
width: 300,
height: 300,
background: 'darkgreen',
items: [
{ tag: 'div', width: 50, height: 50, text: 'Intro', display: 'inline-block', background: 'yellowgreen' },
{ tag: 'div', width: 200, background: 'lightgreen',
items: [
{ tag: 'div', className: 'red', width: 20, height: 20, background: 'red',
click: {
handler: function (e) {
console.log('This is:', this.localName + '.' + this.className)
}
}
},
{ tag: 'div', className: 'orange', width: 20, height: 20, background: 'orange',
click: {
scope: 'root',
handler: function (e) {
console.log('This is:', this.localName + '.' + this.className)
}
},
events: [
{ type: 'custom:event', handler: function () {
console.log('This is div.orange')
}}
]
},
{ tag: 'div', className: 'yellow', width: 20, height: 20, background: 'yellow',
click: {
scope: 'root',
handler: 'onClickYellow',
capture: true
}
}
]
}
],
onClickYellow: function (e) {
var t = e.target
console.log('From ', t.localName + '.' + t.className + ' to ' + this.localName + '.' + this.className)
},
events: [
{ type: 'mouseout', handler: function (e) {
console.log('Out of:', e.target)
}}
]
})
Template
for
: data sourceTplFn
: function (item, itemIndex)
- If data source provided is an array, item is record of array and itemIndex is record index
- If data source provided is an object, item is data object and itemIndex will be undefined
var root = CreateElement('div', {
className: 'root',
id: 'root',
parent: document.body,
width: 300,
height: 300,
background: 'darkgreen',
padding: 5,
items: {
for: [
{ name: 'apple', cost: 0.5 },
{ name: 'mango', cost: 0.5 },
{ name: 'grape', cost: 0.6, suppliers: {
data: [
{ name: 'US', time: 5 },
{ name: 'UK', time: 4 }
]}
}
],
tplFn: function (item, itemIdx) {
return { tag: 'div', text: item.name, padding: 5, margin: '5px 0 0 5px', background: 'tomato',
items: {
for: item.suppliers,
root: 'data',
tplFn: function (sup, supIdx) {
return { tag: 'div',
padding: 5,
background: 'lightblue',
text: sup.name + '. Time: ' + sup.time + ' days'
}
}
}
}
}
}
})
Result
Template with data change reaction
var src = [
{ name: 'apple', cost: 0.5 },
{ name: 'mango', cost: 0.5 },
{ name: 'grape', cost: 0.6, suppliers: {
data: [
{ name: 'US', time: 5 },
{ name: 'UK', time: 4 }
]}
}
]
var root = CreateElement('div', {
className: 'root',
id: 'root',
parent: document.body,
width: 300,
height: 300,
background: 'darkgreen',
padding: 5,
items: {
for: null,
update: {
observeProp: 'data'
},
tplFn: function (item, itemIdx) {
return { tag: 'div', text: item.name, padding: 5, margin: '5px 0 0 5px', background: 'tomato',
items: {
for: item.suppliers,
root: 'data',
tplFn: function (sup, supIdx) {
return {
tag: 'div',
padding: 5,
background: 'lightblue',
text: sup.name + '. Time: ' + sup.time + ' days',
click: { scope: 'root', handler: 'onClickSupplier' }
}
}
}
}
}
},
onClickSupplier: function (e) {
},
events: [
{ type: 'mouseout', handler: function (e) {
console.log('Out of:', e.target)
}}
]
})
Motivation
Prototyping some design and testing event/ interaction made a bit more convinient when
- No dependencies & everything in javascript
- There are Events & reference & template supports
Installation
<script src="dominic.min.js"></script>
npm i dominic
API
- Create new DOM element
CreateElement(name, opts)
name: String
opts: Object
return: DOM element
For Node:
Change global window object
CreateElement.setWindow(windowObj)
- Node class with same behavior of a normal HTML element (
appendChild
, removeChild
, etc...
) - document with
createElement
, createTextNode
methods which will create Node or TextNode
Plan
License
.MIT