skip to Main Content

I have some inputs that change according to content. But seems like the script only can handle one element only. I want it can handle multiple elements

Please note that I’m going to use custom elements in future

onInput(document.getElementById('input'), "lol");
document.getElementById('input').addEventListener('input', onInput)

function onInput(i, ii) {
  console.log('type')
  if (ii) {
    var spanElm = document.getElementById('measure');
    spanElm.textContent = i.getAttribute("placeholder");
    i.style.width = spanElm.offsetWidth + 'px';
  } else {
    var spanElm = document.getElementById('measure');
    if (this.value == "") {
      spanElm.textContent = this.getAttribute("placeholder");
      this.style.width = spanElm.offsetWidth + 'px';
    } else {
      spanElm.textContent = this.value;
      this.style.width = spanElm.offsetWidth + 'px';
    }
  }
};
<div class="input">
  ...
  <div class="input_box">
    <input type="text" placeholder="Value" id="input" />
    <span id="measure"></span>
  </div>
  ...
</div>

<div class="input">
  ...
  <div class="input_box">
    <input type="text" placeholder="Value" id="input" />
    <span id="measure"></span>
  </div>
  ...
</div>

2

Answers


  1. Chosen as BEST ANSWER

    I have tried this but seemed like the custom element wont work but div works

    function measure(element, init) {
      var span = element.nextElementSibling;
      if (init) {
        const inputs = document.querySelectorAll('#input, input-test');
        inputs.forEach(input => {
          console.log(input);
          if (input.tagName == "INPUT") {
            console.log(input);
            var span = input.nextElementSibling;
            span.textContent = input.getAttribute("placeholder");
            input.style.width = span.offsetWidth + 'px';
          }
          if (input.tagName == "INPUT-TEST") {
            console.log(input.shadowRoot.querySelector('#input'));
            var input = input.shadowRoot.querySelector('input');
            var span = input.nextElementSibling;
            span.textContent = input.getAttribute("placeholder");
            input.style.width = span.offsetWidth + 'px';
          }
        })
      }
      if (element.value == "") {
        span.textContent = element.getAttribute("placeholder");
        element.style.width = span.offsetWidth + 'px';
      } else {
        span.textContent = element.value;
        element.style.width = span.offsetWidth + 'px';
      }
    }
    
    
    document.querySelectorAll('#input, input-test').forEach(input =>
      input.addEventListener('input', function(i) {
        if (i.target.tagName == "INPUT-TEST") {
          measure(i.target.shadowRoot.querySelector('input'));
        } else {
          measure(i.target);
        }
      })
    )
    <div class="input">
      <div class="input_box">
        <input type="text" placeholder="Value" id="input" />
        <span id="measure"></span>
      </div>
    </div>

    Seems like it cant detect shadowroot


  2. First, select all the elements by using querySelectorAll which has the advantage of returning a Node List that can be iterated with the usage of forEach.

    Then use an event delegation by adding an element parameter (you can name it as you like) to the function within the addEventListener.

    Then you can use element.target to reference that clicked element within the function:

    const BUTTONS = document.querySelectorAll('button');
    
    BUTTONS.forEach(button =>
      button.addEventListener('click', function(element) {
        let clickedButtonId = element.target.id;
        console.log(clickedButtonId);
      })
    )
    <button id="btn-1">Button 1</button>
    <button id="btn-2">Button 2</button>
    <button id="btn-3">Button 3</button>
    <button id="btn-4">Button 4</button>
    <button id="btn-5">Button 5</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search