Search code examples
javascripthtmlcssqueryselector

Why is the tilde ~ not working in Javascript querySelector but works in CSS?


How can I select the sibling of textarea tag pre in javascript's querySelector? I have been able to select it in CSS using the ~ selector. But that doesn't seem to work in Javascript?

I know I can use the textarea.parentNode.querySelector('pre')) way but why is the sibling selector ~ not working in JS but works in CSS?

I have this simple test case setup:

https://jsfiddle.net/jqdh4ruL/1/

<div>
  <textarea id="name" placeholder="Full Name">$This is a long text for full name</textarea>
  <pre></pre>
</div>


textarea ~ pre {
  background: rgba(255, 0, 0, 0.372);
}

pre {
  width: 100px;
  height: 100px;
}

var textarea = document.getElementById('name')
console.log(textarea.outerHTML)// returns the correct texture

console.log(textarea.parentNode.querySelector('pre'))//returns correct pre tag

console.log(textarea.querySelector('* ~ pre'))//returns null

Solution

  • Use document instead of textarea, because when you use textarea.querySelector(), this can only select the children.

    Also you can use + instead of ~

    const textarea = document.getElementById('name')
    console.log(textarea.outerHTML)// returns the correct texture
    
    console.log(textarea.parentNode.querySelector('pre'))//returns correct pre tag
    
    console.log(document.querySelector('textarea + pre'))//returns correct pre tag
    <div>
      <textarea id="name" placeholder="Full Name">This is a long text for full name</textarea>
      <pre></pre>
    </div>

    UPDATE

    I am aware of the document way. I was just wondering why tilde can't work? then what's the point of the sibling selector using tilde ~? I read this and it seems to indicate it should work?

    You can use ~ with query selector but the targeted element must be a children in that case

    Here's a example when ~ works with querySelector()

    const textarea = document.getElementById('name')
    const div = document.querySelector('div')
    
    console.log(div.querySelector('textarea + pre'))
    console.log(div.querySelector('pre ~ pre'))
    <div>
      <textarea id="name" placeholder="Full Name">This is a long text for full name</textarea>
      <pre>+</pre>
      <div>text</div>
      <pre>~</pre>
    </div>