0

I've been looking at IntersectionObserver for detecting when en element is visible to the user by checking if it is inside the viewport. However, if another element covers the "target" element, it appears we can only detect this if we know which elements to watch specifically, as the observer always takes a target and a root to compare against:

function createObserver() {
  var options = {
    root: document.querySelector('#container'),
    threshold: 0
  };

  var observer = new IntersectionObserver(callback, options);
  observer.observe(document.querySelector('#box'));
}

What I need to do is specify a target to watch and then detect when any other element covers it, which seems to not be possible using IntersectionObserver. Thanks to anyone who can help!

tripRev
  • 830
  • 3
  • 12
  • 27

1 Answers1

2

There's no direct JS way to do this.

I've created a custom observer that also checks for mutations. Check the code:

// AllIntersectionObserver
function AllIntersectionObserver(callback, options) {
    this.options = options;
    this.observer = new IntersectionObserver(callback, this.options);
    this.observe(this.options.root);
    var mutationObserver = new MutationObserver(this.mutationCheck.bind(this));
    mutationObserver.observe(this.options.root, {
        childList: true,
        subtree: true
    });
}
AllIntersectionObserver.prototype.observe = function(el) {
    if (el.nodeType == 1) {
        this.observer.observe(el);
        for (var i = 0; i < el.childNodes.length; i++) {
            this.observe(el.childNodes[i]);
        }
    }
};
AllIntersectionObserver.prototype.mutationCheck = function(events) {
    for (var i = 0; i < events.length; i++) {
        var event = events[i];
        for (var ii = 0; ii < event.addedNodes.length; ii++) {
            this.observe(event.addedNodes[ii]);
        }
    }
};
// end AllIntersectionObserver

new AllIntersectionObserver(console.log, { root: document.querySelector("#c") });

document.querySelector("#add").addEventListener("click", function() {
    var sq = document.createElement("div");
    sq.className = "sq";
    document.querySelector("#c").appendChild(sq);
});

// Dragger
var dragging = null;
window.addEventListener("mousedown", function(event) {
 if (event.target.className == "sq") {
        dragging = {
            el: event.target,
            l: event.target.offsetLeft,
            t: event.target.offsetTop,
            ev: event
        };
        event.preventDefault();
    }
});
window.addEventListener("mousemove", function(event) {
 if (dragging) {
     dragging.el.style.left = (dragging.l + (event.pageX - dragging.ev.pageX)) + "px";
      dragging.el.style.top = (dragging.t + (event.pageY - dragging.ev.pageY)) + "px";
      event.preventDefault();
    }
});
window.addEventListener("mouseup", function(event) {
 dragging = null;
});
// Dragger
.c {
    position: relative;
    background-color: red;
    width: 100px;
    height: 100px;
}
.sq {
    position: absolute;
    left: 0;
    top: 0;
    background-color: blue;
    width: 10px;
    height: 10px;
}
<button id="add">Add square</button>
<div class="c" id="c">
    <div class="sq"></div>
</div>
Drag blue squares with mouse
Jorge Fuentes González
  • 11,568
  • 4
  • 44
  • 64