Я работаю над библиотекой, которая скрывает и отображает DOM на основе других элементов DOM.
Я написал базовую c структуру для библиотеки.
Ниже приведен код для обработки элементов DOM, скрывающихся, когда флажок установлен и снят.
Моя общая цель - сделать эту библиотеку расширяемой и обслуживаемой.
Соблюдаю ли я принципы SOLID? Есть ли лучший способ сделать это? Есть ли какие-то шаблоны дизайна для подражания?
// basic data structure of config object
var rules = [
{
sourceId: 'mainCheckbox',
targetId: 'exampleDiv1',
ruleType: 'onlyOnChecked',
targetVisibilityOnChecked: 'hide', // show / hide
targetVisibilityOnUnchecked: 'show',
doNotReset: false
}
]
var ruleToProcessorMap = {
onlyOnChecked: OnlyOnCheckedRuleProcessor
}
var RuleEngine = {}
RuleEngine.run = function(rules) {
var ruleIndex
for (ruleIndex = 0; ruleIndex < rules.length; rules++) {
this.processRule(rules[ruleIndex])
}
}
RuleEngine.processRule = function(ruleObj) {
var ruleProcessor = new ruleToProcessorMap[ruleObj.ruleType](ruleObj)
ruleProcessor.process()
}
function OnlyOnCheckedRuleProcessor(options) {
this.options = options || {}
}
OnlyOnCheckedRuleProcessor.prototype.process = function() {
var $sourceId = $id(this.options.sourceId),
ctx = this
$sourceId.on('click', onSourceClick)
function onSourceClick() {
var elementVisibilityHandler = new ElementVisibilityHandler({
elementId: ctx.options.targetId,
doNotReset: ctx.options.doNotReset
}),
show = elementVisibilityHandler.show,
hide = elementVisibilityHandler.hide
var visibilityMap = {
show: show,
hide: hide
}
var onCheckedFunc = visibilityMap[ctx.options.targetVisibilityOnChecked]
var onUncheckedFunc = visibilityMap[ctx.options.targetVisibilityOnUnchecked]
if ($sourceId.is(':checked')) {
onCheckedFunc.call(elementVisibilityHandler)
} else {
onUncheckedFunc.call(elementVisibilityHandler)
}
}
}
function ElementVisibilityHandler(options) {
this.options = options || {}
this.$element = $id(options.elementId)
}
ElementVisibilityHandler.prototype.show = function() {
if (isContainerElement(this.$element)) {
if (this.options.doNotReset) {
simpleShow(this.$element)
} else {
showWithChildren(this.$element)
}
}
}
ElementVisibilityHandler.prototype.hide = function() {
if (isContainerElement(this.$element)) {
if (this.options.doNotReset) {
simpleHide(this.$element)
} else {
hideAndResetChildren(this.$element)
}
}
}
function simpleHide($element) {
return $element.hide()
}
function hideAndResetChildren($element) {
var $children = simpleHide($element)
.children()
.hide()
$children.find('input:checkbox').prop('checked', false)
$children.find('textarea, input').val('')
}
function simpleShow($element) {
return $element.show()
}
function showWithChildren($element) {
simpleShow($element)
.children()
.show()
}
function $id(elementId) {
return $('#' + elementId)
}
function isContainerElement($element) {
if (typeof $element === 'string') {
$element = $id($element)
}
return $element.prop('tagName').toLowerCase()
}
// execution starts here
RuleEngine.run(rules)