2016-05-05 2 views
1

Ich versuche ein Overlay zu erstellen, das sich an einen vorhandenen DOM-Knoten anfügt und seinen gesamten Inhaltsbereich abdeckt. Dies sollte unabhängig davon funktionieren, ob dieser Knoten der Hauptteil der Seite oder ein tief verschachteltes div ist. Es ist wichtig, dass sich das Layout der Seite, die ich überlagere, nicht ändert. Irgendwann wird mein Code als eine Browsererweiterung auf vorhandenen HTML-Seiten ausgeführt.Erstellen einer unauffälligen Überlagerung für ein beliebiges HTML-Dokument

Ich stoße auf ein Problem in dem sehr einfachen Fall, in dem ich versuche, eine Seite mit Text (oder alles, was Platz braucht) direkt im Dokumentkörper verschachtelt. Ich habe keine andere Wahl, als mein Overlay div als weiteren Kindknoten des Körpers anzuhängen und seine Position auf absolut und seine Breite/Höhe auf 100% zu setzen. In dem Fall, in dem der Körper statisch positioniert ist (Standard), wird mein div in das Ansichtsfenster und nicht in den Inhalt des Körpers skaliert. Wenn der Inhalt überläuft, wird mein Overlay nicht alles abdecken: \.

Alle anderen Antworten schlagen vor, die Position des übergeordneten div (der Körper in meinem Fall) zu setzen, um es als den Positionierungskontext zu definieren. Ich kann das aber nicht tun. Das Ändern der Position des Dokumentkörpers in "relativ" könnte beispielsweise das Layout des Inhalts des Körpers ändern und den Zweck einer unauffälligen Überlagerung vereiteln. Was ist zu tun?

Erweiterungsspezifische Vorschläge sind willkommen. Als Referenz dient die Erweiterung für Chrome.

Hier ist ein jsfiddle mit einer hypothetischen Seite, die ich überlagern muss. Beachten Sie, dass die ursprüngliche Seite zwar seltsam formatiert ist, sie aber nicht von meiner Überlagerung geändert werden kann.

<body> 
    <style> 
    .overlay { 
     position: absolute; 
     top: 0px; 
     left: 0px; 
     width: 100%; 
     height: 100% 
     /*some magic I am unaware of*/ 
    } 
    </style> 
    <!-- begin original document (stupid hypothetical scenario) --> 
    <div style="position:absolute;top:0px;width:100%;height:100%;background-color:red;"> 
    <!-- this div is part of the original html document I want to overlay. 
    It should behave as it did originally, i.e size to the viewport of the document--> 
    </div> 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id tellus vehicula, tincidunt est fermentum, hendrerit dui. Nullam lacinia, justo sed porta hendrerit, nisl quam blandit nunc, ut imperdiet nibh metus in ante. Pellentesque viverra egestas 
    nulla eu dictum. Aliquam ac accumsan leo. Integer ut tellus odio. Duis blandit venenatis venenatis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum vel lorem egestas, tincidunt sem vel, venenatis 
    ipsum. Donec vitae blandit nibh. Curabitur cursus nunc arcu, id tempor massa gravida ut. Integer vulputate libero in placerat vestibulum. Duis quis turpis vel lectus venenatis rhoncus. Sed congue est consequat, dapibus odio sit amet, sollicitudin arcu. 
    Praesent hendrerit massa velit, vel pretium erat viverra quis. Proin non enim facilisis, venenatis dolor ut, dapibus nulla. Morbi vestibulum mollis felis ut venenatis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus 
    mus. Ut mollis velit nulla, et tristique sapien auctor eu. Phasellus tincidunt mauris elit, vel fringilla leo consectetur a. Vivamus a porta magna. Mauris hendrerit leo eget sapien aliquet dignissim. Nunc id sem est. Integer sed lacus est. Nulla sit 
    amet sapien et ex aliquam malesuada quis vel eros. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus turpis ligula, elementum sit amet sapien nec, malesuada fringilla nibh. Duis euismod, purus semper viverra aliquam, ligula sem 
    vehicula mi, sit amet cursus mauris augue vel enim. Donec lacinia diam quis sapien laoreet vulputate in eu est. Proin consequat, ex vitae molestie pellentesque, libero purus pellentesque arcu, id porttitor orci sem a lectus. Morbi mattis in metus quis 
    euismod. Nam arcu augue, imperdiet eu felis eu, rhoncus facilisis lectus. Nullam placerat, tortor non tincidunt tristique, purus magna cursus leo, vitae sagittis odio turpis sodales nisi. Nullam vehicula erat nisl, ac venenatis massa rutrum sed. Mauris 
    massa tortor, volutpat vel nisl a, consectetur molestie sapien. Quisque eu elit nulla. Praesent at eros vehicula, lobortis purus quis, efficitur velit. Donec eget faucibus nisl. Praesent pharetra mattis porta. Donec volutpat lacinia dui non maximus. 
    Vivamus eu sodales leo. Ut eu ipsum scelerisque, consectetur turpis condimentum, malesuada elit. Proin tincidunt mauris metus, eu tincidunt ex ultrices ut. Sed sollicitudin leo nunc, in pharetra ligula egestas ut. Etiam suscipit eget ligula ut convallis. 
    Ut tempus tellus id ultrices rutrum. Nam accumsan fermentum metus, tristique gravida eros ultricies eget. Integer tortor diam, posuere ut ornare quis, bibendum ut tellus. Maecenas imperdiet lacus vitae felis viverra, nec dignissim lacus volutpat. Curabitur 
    et elit vehicula ipsum luctus tempor et sed enim. Fusce ultrices eget ante nec consectetur. Donec commodo nunc eget diam tristique, at euismod nisl commodo. Fusce felis neque, vulputate ut tincidunt sed, commodo in risus. Quisque sed magna sodales tortor 
    condimentum aliquam. Phasellus mattis justo eget diam tincidunt luctus. Cras pharetra ultrices sem, sed sollicitudin purus feugiat sed. Vivamus vitae tempor velit. 
    <!-- end original document --> 
    <div class='overlay'> 
    <!-- this div is my overlay. It should size to the content of the document body, not the viewport. Careful setting the body's position to relative, the other div will change!--> 
    </div> 
</body> 
+0

* "Wenn Inhalt überläuft, wird mein Overlay nicht alles abdecken: \." * - Ja, ich denke, das wird schwer zu lösen sein.Auf der anderen Seite sollte etwas, das den gesamten Inhaltsbereich abdeckt, nicht so schwer sein, aber ich nehme an, Sie meinen, dass es diesen Bereich * eng * abdecken sollte, mit anderen Worten, es sollte nicht größer sein, als es sein müsste dieser Bereich. – GolezTrol

+0

Das stimmt. Wie in, ich möchte nicht eine Überlagerung haben, die behoben wird. Ich möchte ein Overlay, das die Größe des fraglichen Knotens hat und seinem Scroll-/Größenänderungsverhalten folgt. –

+0

Können wir das Overlay mit jQuery dimensionieren und positionieren? – Lesley

Antwort

0

Ich denke, dass Sie am besten ein Element an den Körper anhängen (wenn Sie Zugriff auf ein höheres gestapeltes Element für Erweiterungen haben) und einfach die element.getClientBoundingRect() verwenden, um die Position und Abmessungen zu erhalten.

function applyStyle(element, styles) { 
 
    for (var key in styles) { 
 
    element.style[key] = styles[key]; 
 
    } 
 
} 
 

 
var overlay = document.body.appendChild(document.createElement('div')), 
 
    indicator = overlay.appendChild(document.createElement('div')); 
 

 
// apply the styles 
 
applyStyle(overlay, { 
 
    position: 'absolute', 
 
    top: 0, 
 
    left: 0, 
 
    right: 0, 
 
    bottom: 0, 
 
    zIndex: 2147483647, // it doesn't get higher than this 
 
    pointerEvents: 'none' 
 
}); 
 

 
applyStyle(indicator, { 
 
    position: 'absolute', 
 
    border: '1px dotted red', 
 
    backgroundColor: 'rgba(255,0,0,0.2)' 
 
}); 
 
     
 

 
window.addEventListener('mouseover', function(event) { 
 
    var bound = event.target.getBoundingClientRect(); 
 

 
    applyStyle(indicator, { 
 
    top: bound.top + 'px', 
 
    left: bound.left + 'px', 
 
    width: bound.width + 'px', 
 
    height: bound.height + 'px' 
 
    }); 
 
});
.foo { 
 
    position: absolute; 
 
    top: 30px; 
 
    left: 10px; 
 
    width: 300px; 
 
    border: 1px solid gold; 
 
} 
 

 
.bar { 
 
    position: relative; 
 
    width: 40%; 
 
    margin: 200px auto 0; 
 
    max-height: 10em; 
 
    overflow: hidden; 
 
    border: 1px solid green; 
 
}
<div class=foo> 
 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ut nibh dapibus tellus varius tristique vitae id elit. Fusce vestibulum neque a scelerisque pellentesque. Vestibulum eu odio risus. Aliquam id tellus in mauris sollicitudin vestibulum. Aenean vestibulum et massa vel dapibus. Pellentesque eu lectus odio. Aliquam vitae fermentum mauris. Pellentesque feugiat sem vel dolor imperdiet tempor. 
 
</div> 
 

 
<div class=bar> 
 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ut nibh dapibus tellus varius tristique vitae id elit. Fusce vestibulum neque a scelerisque pellentesque. Vestibulum eu odio risus. Aliquam id tellus in mauris sollicitudin vestibulum. Aenean vestibulum et massa vel dapibus. Pellentesque eu lectus odio. Aliquam vitae fermentum mauris. Pellentesque feugiat sem vel dolor imperdiet tempor. 
 
</div>

Die Bits von "List" in hier beinhalten:

  • mit der maximalen Z-Index kombiniert mit dem Overlay-Element das letzte Element ist innerhalb <body> es macht fast unmöglich für jede Seite darüber zu steigen
  • die wenig bekannte getBoundingClientRect Schatz
  • pointer-events: none css, die Interaktivität aus dem Overlay-Elemente zu entfernen (einfach pointer-events: auto auf der Anzeige in dem wieder aktivieren)

Wie Sie eine bestimmten Browser und eine (grünbleibend) zielen moderner Erstens, ich glaube nicht, dass Sie jQuery verwenden sollten. Du brauchst es nicht.

0

Ich weiß nicht, ob jQuery ist eine Option, aber ich konnte nicht widerstehen ... Hier ist, wie Sie jQuery Overlay, um Stil verwenden könnte

var $thingToOverlay = $('#someDivOrWhatever'); // use $(document) for whole page 
var $overlay = $('.overlay'); 

var getMaxZ = function($elements){ 
    var z; 
    return Math.max.apply(null, $elements.map(function(){   
     return isNaN(z = parseInt($(this).css("z-index"), 10)) ? 0 : z;  
    })); 
}; 

$overlay.css({ 
    'position': 'absolute', 
    'box-sizing': 'border-box', 
    'background-color': 'red', 
    'height': $thingToOverlay.height(), 
    'width': $thingToOverlay.width(), 
    'top': $thingToOverlay.offset().top, // don't use this for whole page (document), just set to 0 
    'left': $thingToOverlay.offset().left, // ditto 
    'z-index': getMaxZ($overlay.siblings()) // assuming overlay is last on page, no need to +1 
}); 

Dies wird sich natürlich um eine gewisse Logik brauchen Es hängt davon ab, ob das Overlay die ganze Seite oder nur ein div abdecken soll, aber Sie bekommen die Idee?

+0

Vergessen Sie nicht zIndex. – GolezTrol

+0

OP hatte '.overlay' als letztes div auf Seite, daher sollte z-index nicht benötigt werden. – Lesley

+0

Andere Elemente können einen expliziten Z-Index haben. – GolezTrol