|
9 | 9 | template.innerHTML = `
|
10 | 10 |
|
11 | 11 | <style>
|
12 |
| -:host(lightning-image) { |
| 12 | +:host { |
13 | 13 | display: inline; /* if display: contents is not supported, then use the same default display style as an img tag */
|
14 | 14 | display: contents; /* treat the lightning-image container as if it isn't there */
|
15 | 15 | }
|
16 | 16 | </style>
|
17 | 17 |
|
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> |
20 | 21 |
|
| 22 | +`; |
21 | 23 |
|
22 | 24 |
|
23 | 25 | /**
|
|
38 | 40 | // https://developers.google.com/web/fundamentals/web-components/best-practices#create-your-shadow-root-in-the-constructor
|
39 | 41 | this.attachShadow({mode: 'open'});
|
40 | 42 | 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); |
41 | 48 | }
|
42 | 49 |
|
43 | 50 | get src() {
|
|
69 | 76 | // https://developers.google.com/web/fundamentals/web-components/customelements#shadowdom
|
70 | 77 | const cloned = template.content.cloneNode(true);
|
71 | 78 |
|
| 79 | + return cloned; |
| 80 | + } |
| 81 | + |
| 82 | + createImg() { |
72 | 83 | // we want to create an img tag element that is the same as the lightning-image
|
73 | 84 | // component, except it has a src that will not cause any additional network requests
|
74 | 85 | const tpl = document.createElement('template');
|
|
85 | 96 | imgTag.src = LightningImage.PIXEL_BASE_64;
|
86 | 97 | }
|
87 | 98 |
|
88 |
| - // add the dynamic img into our static template |
89 |
| - cloned.appendChild(imgTag); |
90 |
| - |
91 |
| - return cloned; |
| 99 | + return imgTag; |
92 | 100 | }
|
93 | 101 |
|
94 | 102 | supportsNativeLazyLoading() {
|
|
99 | 107 | const observer = new IntersectionObserver(entries => {
|
100 | 108 | entries.forEach(entry => {
|
101 | 109 | 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 | + |
103 | 113 | observer.unobserve(this);
|
104 | 114 | }
|
105 | 115 | })
|
106 | 116 | }, { rootMargin: '0px' });
|
107 | 117 |
|
108 | 118 | // 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); |
118 | 120 | }
|
119 | 121 | }
|
120 | 122 |
|
|
0 commit comments