iframe Attributes
The iframe element supports several key attributes for file preview functionality:
src: Specifies the file path to displayframeborder: Cnotrols border visibility (set to "0" to hide)scrolling: Manages scrollbar behavior ("no" hides native scrollbars)heightandwidth: Define element dimensions
Advantages and Disadvantages
Advantages
- Renders embedded content exactly as it appears in the source
- Centralized content updates—if the same content appears across multiple pages, modifying the iframe source uppdates all instances
- Promotes code reuse through consistent layout structures like headers and footers embedded once
- Isolates third-party content (icons, advertisements) to prevent blocking the main document load
Disadvantages
- Search engine crawlers cannot properly index iframe content
- May introduce unwanted scrollbars within the frame
- Navigation links require careful configuration in frame-based layouts
- Each iframe generates an additional HTTP request to the server
Implementation in Dialog Component
For modal-style file preview, wrap the iframe within a dialog component:
<el-dialog
:visible.sync='displayFile'
:before-close="onDialogClose"
custom-class="file-preview">
<iframe
id="previewFrame"
@load="adjustFrameDimensions()"
height="100%"
:src="currentFileUrl"
frameborder="0"
scrolling="no">
</iframe>
</el-dialog>
The load handler dynamically resizes the iframe based on its content:
adjustFrameDimensions() {
const frameElement = document.getElementById('previewFrame');
const frameDocument = frameElement.contentWindow.document.body;
const frameStyles = 'height:100%;display:flex;justify-content:center;align-items:center;';
frameDocument.style.cssText = frameStyles;
const firstChild = frameDocument.childNodes[0];
if (firstChild) {
const elementType = firstChild.nodeName.toLowerCase();
if (elementType === 'img') {
frameElement.style.height = `${firstChild.naturalHeight}px`;
frameElement.style.width = `${firstChild.naturalWidth}px`;
} else if (elementType === 'embed') {
// PDF and similar embedded content
frameElement.style.height = '500px';
frameElement.style.width = '700px';
}
} else {
frameElement.style.height = '150px';
frameElement.style.width = '300px';
}
},
onDialogClose() {
this.displayFile = false;
// Clear the source to prevent flash of old content on next open
this.currentFileUrl = '';
}
CSS styling for the dialog:
::v-deep .q-dialog.file-preview {
.q-dialog__body {
min-height: $s-30;
display: flex;
justify-content: center;
align-items: center;
}
}
Full-Screen Overlay Implementation
For a page-covering preview with a close button:
<div v-if="currentFileUrl" id="previewOverlay" class="preview-wrapper">
<iframe
id="previewFrame"
height="100%"
:src="currentFileUrl"
frameborder="0"
scrolling="no"
class="preview-frame"
@load="adjustFrameDimensions()">
</iframe>
<button class="preview-close" @click="closePreview">
<i class="q-icon-circle-close"></i>
</button>
</div>
JavaScript for overlay handling:
adjustFrameDimensions() {
const frameElement = document.getElementById('previewFrame');
const frameBody = frameElement.contentWindow.document.body;
frameBody.style.cssText = 'height:100%;display:flex;justify-content:center;align-items:center;';
const firstChild = frameBody.childNodes[0];
if (firstChild) {
const nodeType = firstChild.nodeName.toLowerCase();
if (nodeType === 'pre') {
// Code content detected
const overlay = document.getElementById('previewOverlay');
overlay.style.backgroundColor = 'white';
}
}
},
closePreview() {
this.currentFileUrl = '';
}
Overlay styles:
.preview-wrapper {
position: fixed;
z-index: 3;
top: $s-zero;
bottom: $s-zero;
left: $s-zero;
right: $s-zero;
background: rgba(0, 0, 0, 0.5);
.preview-frame {
height: 100%;
width: 100%;
}
.preview-close {
top: $s-6;
right: $s-6;
width: $s-10;
height: $s-10;
font-size: $s-10;
color: rgb(51, 51, 51);
position: absolute;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
opacity: 0.8;
cursor: pointer;
}
}
Content Detection Strategy
The implementation inspects the iframe's DOM after loading to determine content type:
- Images: Uses
naturalHeightandnaturalWidthto set exact dimensions - PDFs: Detected via
embedtag, applies fixed dimensions - Plain text: Identified by
pretag, triggers white background for readability
Clearing the src attribute between sessions prevents content flash during transitions.