Modifier Les codes HTML et CSS suivants ne sont qu'un exemple , le cas d'utilisation réel implique un DOM complexe et devrait être suffisamment générique pour fonctionner sur différentes pages Web. La seule hypothèse valable est que tous les éléments sont rectangulaires.


Compte tenu des éléments suivants:

HTML

<div class="a" id="a">
A
</div>
<div class="b">
B
</div>
<div class="c">
  C
  <div class="d">
  D
  </div>
</div>

CSS

.a,.b,.c,.d{
  border: solid 1px black;
  opacity: 0.5;
  font-family: arial;
  position: absolute;
  font-size: 20px;
}

.a{
  width:300px;
  height:250px;
  top:30px;
  left:20px;
  background:green;
}

.b{
  width:300px;
  height:145px;
  top:10px;
  left:20px;
  background:blue;
}
.c{
  width:150px;
  height:300px;
  top:30px;
  left:60px;
  background:red;
}
.d{
  margin:10px;
  background:yellow;
  width:100px;
  height:200px
}

Produit le résultat suivant:
entrez la description de l'image ici


J'essaie de détecter le pourcentage du DIV "A" qui n'est pas masqué par d'autres éléments, IE: 25% dans l'exemple donné.

J'ai écrit le JS suivant (violon) qui scanne la zone rect du DIV "A" et collecte les éléments obscurcissants.

let el = document.getElementById("a");
let rect = el.getBoundingClientRect();
let right = rect.x + rect.width;
let bottom = rect.y + rect.height;
let elements = [];
for (let i = rect.x; i < right; i += 10) {
  for (let j = rect.y; j < bottom; j += 10) {
    let sampled = document.elementFromPoint(i, j);
    if (sampled && sampled !== el && elements.indexOf(sampled) === -1) {
      elements.push(sampled);
    }
  }
}

J'essaie maintenant de trouver le moyen le plus efficace de faire les calculs. J'ai essayé une autre approche de numérisation du rectangle pixel par pixel et de compter tous les pixels qui ne font pas partie du DIV principal, mais cette approche semble lente pour une solution acceptée.

Toute aide serait appréciée.

MISE À JOUR
Après avoir fait quelques recherches, je commence à penser que j'aurai besoin de l'algorithme de balayage, toujours pas exactement comment modifier le code pour s'adapter à mon problème.

Mise à jour 2
Lorsque vous utilisez pointer-events: none;, l'approche document.elementFromPoint ne fonctionnera pas, donc je recherche une meilleure solution.

9
Shlomi Schwartz 23 mai 2018 à 14:55

3 réponses

Meilleure réponse

Ajuster votre solution initiale, l'idée était de supprimer le style des événements de pointeur tout en utilisant la méthode elementFromPoint.

function addCSS(){
    let style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = '* {pointer-events: all !important;}';
    document.getElementsByTagName('head')[0].appendChild(style);

    Array.prototype.filter.call(document.querySelectorAll("[style]"),(node)=>{
      return node.style.pointerEvents;
    }).forEach((node)=>{
      node.style.pointerEvents = "all";
    })
}

Voir ce violon

1
Roni Gadot 28 mai 2018 à 09:02

Vous pouvez parcourir en boucle tous les éléments dom et collecter ceux qui sont obscurcissants. Cela donnerait une complexité de O(n) où n = nombre d'éléments au lieu de O(x * y)x et y sont respectivement la largeur et la hauteur des pixels du div.

let el = document.getElementById("a");
let rect = el.getBoundingClientRect();
let right = rect.x + rect.width;
let bottom = rect.y + rect.height;
let baseDepth = parseFloat(el.style.zIndex);
if (baseDepth === NaN) {
  baseDepth = 0;
}
let all = document.getElementsByTagName("*");
let obscuringElements = [];
for (var i=0, max=all.length; i < max; i++) {
    let sample = all[i];
    if (sample !== el && elements.indexOf(sample) === -1) {
      let subRect = sample.getBoundingClientRect();
      if (subRect.x <= right && subRect.x + subRect.width >= rect.x
        && subRect.y <= bottom && subRect.y + subRect.height >= rect.y) {
          obscuringElements.push(sample);
        }
    }
}

Vous pouvez maintenant utiliser les limites de obscuringElements pour déterminer la quantité de el visible.

0
Aaron Krajeski 27 mai 2018 à 08:43

Vous pouvez utiliser le Intersection Observer pour obtenir le pourcentage visible d'un élément dans un parent.

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

C'est expérimental cependant!

1
Kokodoko 27 mai 2018 à 08:26