Skip to content

Commit 5e26109

Browse files
committed
use a slot to project the light DOM img into the shadowDOM
1 parent 67b1fa8 commit 5e26109

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

lightning-image.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@
99
template.innerHTML = `
1010
1111
<style>
12-
:host(lightning-image) {
12+
:host {
1313
display: inline; /* if display: contents is not supported, then use the same default display style as an img tag */
1414
display: contents; /* treat the lightning-image container as if it isn't there */
1515
}
1616
</style>
1717
18-
`;
19-
18+
<!-- We want the img element to live outside of the shadowDOM so that it is fully query-able, style-able, etc as if it wasn't
19+
inside the shadowDOM at all. The <slot> element allows us to accomplish this. -->
20+
<slot></slot>
2021
22+
`;
2123

2224

2325
/**
@@ -38,6 +40,11 @@
3840
// https://developers.google.com/web/fundamentals/web-components/best-practices#create-your-shadow-root-in-the-constructor
3941
this.attachShadow({mode: 'open'});
4042
this.shadowRoot.appendChild(this.template());
43+
44+
// store the img, so that we can directly reference it in the future
45+
this.img = this.createImg();
46+
// insert the img element directly into the light DOM, and have it project to the shadowDOM via the <slot> element.
47+
this.appendChild(this.img);
4148
}
4249

4350
get src() {
@@ -69,6 +76,10 @@
6976
// https://developers.google.com/web/fundamentals/web-components/customelements#shadowdom
7077
const cloned = template.content.cloneNode(true);
7178

79+
return cloned;
80+
}
81+
82+
createImg() {
7283
// we want to create an img tag element that is the same as the lightning-image
7384
// component, except it has a src that will not cause any additional network requests
7485
const tpl = document.createElement('template');
@@ -85,10 +96,7 @@
8596
imgTag.src = LightningImage.PIXEL_BASE_64;
8697
}
8798

88-
// add the dynamic img into our static template
89-
cloned.appendChild(imgTag);
90-
91-
return cloned;
99+
return imgTag;
92100
}
93101

94102
supportsNativeLazyLoading() {
@@ -99,22 +107,16 @@
99107
const observer = new IntersectionObserver(entries => {
100108
entries.forEach(entry => {
101109
if (entry.isIntersecting) {
102-
this.insertOriginalImage();
110+
// here we are replacing the pixel image with the original image
111+
this.img.src = this.src;
112+
103113
observer.unobserve(this);
104114
}
105115
})
106116
}, { rootMargin: '0px' });
107117

108118
// observe our pixel image
109-
observer.observe(this.getImgElement());
110-
}
111-
112-
getImgElement() {
113-
return this.shadowRoot.querySelector('img');
114-
}
115-
116-
insertOriginalImage() {
117-
this.getImgElement().src = this.src;
119+
observer.observe(this.img);
118120
}
119121
}
120122

0 commit comments

Comments
 (0)