0.0.9 • Published 5 months ago
element_marker v0.0.9
ElementMarker
Библиотека для выбора HTML элементов в области, указанной мышью
Для использования импортируем библиотеку:
import {ElementMarker } from 'element_marker'
создадим её инстанс:
const elementMarker = new ElementMarker()
а так же активируем:
elementMarker.switchActivity(true)
В DOM должна быть определена минимальная структура:
<div class='ElementMarkerWin'>
<div class='Elem'>Element 1</div>
<div class='Elem'>Element 2</div>
</div>
Слушаем события мыши:
document.addEventListener('mousedown', handlerMarking)
document.addEventListener('mouseup', handlerMarking)
document.addEventListener('mousemove', handlerMarking)
document.addEventListener('onElementMarker', e => handleAfterMarking(e))
Ищутся элементы с классом 'Elem' в родительском HTML элементе с классом 'ElementMarkerWin', при этом генерируется событие 'onElementMarker', в свойстве e.detail которого содержится массив с найденными HTML элементами.
Кастомизация: 'Elem' и 'ElementMarkerWin' являются классами по-умолчанию, но они могут быть переопределены:
elementMarker.settings = {winClassName: 'newParentClass', elemClassName: 'newElemClass'}
Дополнительно может быть задан цвет рамки и области выбора:
elementMarker.settings = {color: '#7fff00'}
Библиотека может быть легко использована с UI-библиотеками и фреймворками, например React:
app.tsx:
import {useEffect, useState} from "react"
import {ElementMarker } from 'element_marker'
import './style.scss'
const elementMarker = new ElementMarker()
const elemsSet = [
{id: 0, name: '0'},
{id: 1, name: '1'},
{id: 2, name: '2'},
{id: 3, name: '3'},
{id: 4, name: '4'},
{id: 5, name: '5'},
]
const App = () => {
const [elems] = useState(elemsSet)
const [markedElemIds, setMarkedElemIds] = useState<number[]>([])
const handlerMarking = (e: MouseEvent) => elementMarker.drawRect(e)
const handleAfterMarking = (e: CustomEvent<Element[]>) => {
const newMarkedElemIds = e.detail.map(el => +el.getAttribute('data-elem-id')!)
setMarkedElemIds(newMarkedElemIds)
}
useEffect(() => {
document.addEventListener('mousedown', handlerMarking)
document.addEventListener('mouseup', handlerMarking)
document.addEventListener('mousemove', handlerMarking)
document.addEventListener('onElementMarker', handleAfterMarking)
return () => {
document.removeEventListener('mousedown', handlerMarking)
document.removeEventListener('mouseup', handlerMarking)
document.removeEventListener('mousemove', handlerMarking)
document.removeEventListener('onElementMarker', handleAfterMarking)
}
}, [])
useEffect(() => {
elementMarker.settings = {winClassName: 'ElementMarkerWin', elemClassName: 'Elem', color: '#7fff00'}
elementMarker.switchActivity(true)
}, [])
return (
<div className={'ElementMarkerWin'}>
<div className={'interlayer'}>
{elems.map(el => {
const markedCls = markedElemIds.includes(el.id) ? 'marked' : ''
return <div key={el.id} className={`Elem ${markedCls}`} data-elem-id={el.id}>{el.name}</div>
})}
</div>
</div>
)
}
export default App
style.scss:
.ElementMarkerWin {
width: 98vw;
height: 98vh !important;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.Elem {
background-color: #bae6fd;
color: black;
display: flex;
justify-content: center;
align-items: center;
&.marked {
background-color: rgb(115, 255, 0);
}
}
.interlayer {
width: 500px;
height: 200px;
display: grid;
grid-template-columns: 200px 200px;
gap: 10px;
align-items: stretch;
}