性能:侦听所有表单元素更改以将所有动态属性与新数据同步

Performance: listen to all form elements changes to sync all dynamic attributes with new data

有一个简单的形式:

<form>
    <input type="checkbox" name="checkbox"> Checkbox
    <input type="email" name="email">
    <button>Submit</button>
</form>

任务是:email 字段只有在选中 checkboxbutton[=54= 时才必须显示] 仅当 email filled

时才必须显示

所以,我决定这样实现:

  1. emailbutton 必须有 data-visible 属性 with display conditions
  2. checkboxemail 输入必须收听更改
  3. 任何 checkboxemail 更改都应 运行 检查以根据条件显示|隐藏 data-visible 元素

结果是:

// inputs to listen based on id attr (temp solution)
let inputs = form.querySelectorAll('[id]');

// elements to set/unset visibility
let visibles = form.querySelectorAll('[data-visible]');

// Loop all data-visible elements to toggle display: block|none based on evaluated condition
function sync() {
    for (let v of visibles) {
        if(eval(v.getAttribute('data-visible'))) {
            v.style.display = 'block';
        } else {
            v.style.display = 'none';
        }
    }
}

// Listen to all inputs changes and sync with new data
for (let input of inputs) {
    input.addEventListener('change', function(e) {
        sync()
    });
}

sync() // Hide everything that must be hidden on init
<form id="form">
    <input type="checkbox" name="checkbox" id="checkbox"> Checkbox
    <input data-visible="checkbox.checked" type="email" name="email" id="email">
    <button data-visible="email.value">Submit</button>
</form>

codepen

所以,实际上,这只是一种方法,required/disabled/class 属性也必须根据表单数据的变化进行切换

基本上,我想要实现的是实现简单的类似 MVVM 的方法,但依赖于表单数据而不是 JS 模型

事实证明,在实际任务中,可能会监听约 20 个所有表单元素的所有更改,并且每次更改都会立即评估所有约 20 个条件以 set/unset 某些属性

所以,问题是 - 它会导致一些严重的 memory/cpu 问题吗?或者一切都很好,MVVM 框架做的几乎一样?我可以一起去吗?

我以前也做过类似的事情,不推荐你现在走的路。

原因:

  • 您正在使用 eval -- 有一个表达式:"eval is evil" 这大部分是正确的,您应该只在没有其他选择的情况下使用 eval。
  • 您每次都在遍历所有输入,即使其中大部分没有任何变化。如您所述,这将对浏览器造成不必要的负载

解决方法:

  • 尝试将字段放入 HTML 内的 JSON 编码块中 - 如:

<input data-visible="{ 'checkbox-id': { 'prop': 'checked', 'regex': true } }" ... >

  • 以上允许对每个元素进行多次检查(您可以选择 AND/OR 它们一起)
  • 使用JSON.Parse
  • 解析数据
  • 根据任何给定输入的 ID 构建反向查找对象——查找所有依赖于输入的对象(如果这是动态的,这部分将是一个小问题)
  • 在输入更改时递归地循环遍历所有依赖项并show/hide它们

这是一个 fiddle 实现的类似于您正在寻找的东西:js-fiddle

如果这不是您要找的,请告诉我。