如何将属性(不是事件)分配给稍后在 NodeList 之外创建的元素?

问题描述 投票:0回答:1
  • 当我们创建从类似元素分配此属性的代码时,我们可以将其称为方法。
  • 此功能可以随着日期输入的更改事件连续读取。
  • 我想用 MutationObserver 尝试一下,但在我看来,这与我一开始提到的方法调用它没有什么不同。
    <div class="inputs">
        <input type="date"/>
    </div>
    <button>Add</button>

document.querySelector('button').addEventListener('click', function () {
    let clone = `<input type="date"/>`;
    document.querySelector('.inputs').insertAdjacentHTML('beforeend', clone);
})
document.querySelectorAll('input[type=date]').forEach(input=>{
  input.max = new Date().toISOString().split("T")[0];
})

但是除了这些,有没有一种方法可以让我们在动态结构中运行的更流畅呢?

javascript element nodelist clonenode
1个回答
0
投票

在我看来,对于这个简单的操作 MutationObserver 来说太昂贵了。

您的代码的主要问题是

document.querySelectorAll('input[type=date]').forEach...
不是“反应性的”,而是在每次脚本标记/文件解析时只执行一次。 事实上,对于第一个输入,在您的 html 中静态添加(或服务器端)它有效,但对于其他使用按钮动态添加的输入,它不起作用。

所以你必须在

click
监听器内部操作,就像你做的那样。但不是简单地创建一个 html 字符串,您可以创建一个
HTMLInputElement
, 直接设置你想要的任何属性并附加它。

    const inputs = document.querySelector('.inputs');
    /**
     * We can create only once our `dateInput` prototype with all the attributes, 
     * and than clone it each time we need. ( You could use a clojure to, 
     * or put this 3 lines directly in the listener, but this should be a little more efficient)
     **/
    const dateInput = document.createElement('input');
    dateInput.type = 'date';
    dateInput.max = new Date().toISOString().split("T")[0];
    
    document.querySelector('button').addEventListener('click', () =>
        inputs.append(dateInput.cloneNode()));

现在您必须管理页面中的输入。

  • 如果您的视图是由服务器脚本呈现的,您可以简单地在那里添加 max 属性。

  • 如果你想通过javascript添加它,你可以保留这一行,并且将对多个元素起作用:

   document.querySelectorAll('input[type=date]').forEach( input => {
      input.max = new Date().toISOString().split("T")[0];
   });

工作示例:

    const inputs = document.querySelector('.inputs');
    const dateInput = document.createElement('input');
    dateInput.type = 'date';
    dateInput.max = new Date().toISOString().split("T")[0];
    
    document.querySelector('button').addEventListener('click', () =>
        inputs.append(dateInput.cloneNode()));
    
    document.querySelectorAll('input[type=date]').forEach(input => {
        input.max = new Date().toISOString().split("T")[0];
    });
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="inputs">
        <input type="date"/>
    </div>
    <button>Add</button>
</body>
</html>

--编辑: 另一个例子,具有更一致的日期值:

    const inputs = document.querySelector('.inputs');
    /**
     * We can create only once our `dateInput` prototype with all the attributes we need, 
     * and than clone it every time we need. ( You could use a clojure to, 
     * or put this 2 lines directly in the listener, but this should be a little more efficient)
     **/
    const dateInput = document.createElement('input');
    dateInput.type = 'date';
    
    document.querySelector('button').addEventListener('click', () => {
        const newNode = dateInput.cloneNode();
        newNode.max = new Date().toISOString().split("T")[0];
        inputs.append(newNode);
    });
    
    document.querySelectorAll('input[type=date]').forEach( input => {
        input.max = new Date().toISOString().split("T")[0];
    });
© www.soinside.com 2019 - 2024. All rights reserved.