0

How can I use the relatively new Intersection Observer API to detect when input that’s currently focused goes outside the viewport, so that when it does, the focus on that input is removed?

The solution should work in Safari for iOS.


Here is my code so far:

document.addEventListener("DOMContentLoaded", _ => {
  const focusedInput = document.activeElement
  
  // ?
  focusedInput.blur()
})
html { height: 100% }

html, body, main, section {
  display: flex;
  flex-grow: 1
}

main { flex-direction: column }

section {
  justify-content: center;
  align-items: center;
  flex: 1 0 100%
}
<main>
  <section>
    <form action=submit method=post>
      <fieldset>
        <legend>Enter Your Details</legend>
        <label>Email<br><input type=email name=email placeholder=jane@example.com></label><hr>
        <label>Message<br><textarea name=briefing placeholder="Lorem ipsum dolor sit amet."></textarea></label><hr>
        <input type=submit value=Submit>
      </fieldset>
    </form>
  </section>
  <section>
    <h2>Second Page</h2>
  </section>
</main>
Tzar
  • 5,132
  • 4
  • 23
  • 57

2 Answers2

1

In doc you linked there is a fiddle Why don't you use it?

Just modify it to something like..

document.addEventListener("DOMContentLoaded", _ => {
    let observerOptions = {
        root: null,
        rootMargin: "0px",
        threshold: [0, 0.1, 0.99]
    };

    let intersectionCallback = (entries) => {
      entries.forEach((entry) => {
        if (entry.intersectionRatio == 0) { // fully invisible
          //document.activeElement.blur()
        }
        if (entry.intersectionRatio < 1) { // partially invisible
          document.activeElement.blur()
        }
      });
    }
    
    let observer = new IntersectionObserver(intersectionCallback, observerOptions);
    observer.observe(document.querySelector("#myForm"));
  
})
html { height: 100% }

html, body, main, section {
  display: flex;
  flex-grow: 1
}

main { flex-direction: column }

section {
  justify-content: center;
  align-items: center;
  flex: 1 0 100%
}
<main>
  <section>
    <form action=submit method=post id=myForm>
      <fieldset>
        <legend>Enter Your Details</legend>
        <label>Email<br><input type=email name=email placeholder=jane@example.com></label><hr>
        <label>Message<br><textarea name=briefing placeholder="Lorem ipsum dolor sit amet."></textarea></label><hr>
        <input type=submit value=Submit>
      </fieldset>
    </form>
  </section>
  <section>
    <h2>Second Page</h2>
  </section>
</main>
l00k
  • 1,525
  • 1
  • 19
  • 29
  • Checked on browserstack iOS13 Safari - it works. In fiddle it is implement only to form. you can easly extend it to specific fields. – l00k Nov 19 '19 at 10:26
1

I created a jsfiddle with the behavior you are describing:

var intersectionObserver = new IntersectionObserver(function(entries) {
  if (entries[0].intersectionRatio <= 0){
    console.log("the field is not visible");
    //Add your blur code here
  }else{
    console.log("the field is visible")
  }
});

// start observing
intersectionObserver.observe(document.querySelector('#emailtwo'));

The observer checks the intersectionRatio, if the ratio <= 0 it means the element is not on the screen.

JSFiddle: https://jsfiddle.net/0f9Lkbgc/1/

Merijndk
  • 1,674
  • 3
  • 18
  • 35