

Don't manipulate DOM elements outside the component |
You should not manipulate DOM elements outside your component, as SharePoint DOM can change breaking your customization
CheckId | SPF050802 |
---|---|
TypeName | DontManipulateDomElementsOutsideComponent |
Severity | CriticalWarning |
Type | JavaScriptFile |
When building SharePoint Framework solutions, you should avoid manipulating the DOM outside the component. SharePoint DOM should not be treated as an API and changes regularly. When it does, it breaks your solution that relies on the specific DOM structure of the page.
When building SharePoint Framework client-side web parts your solution should work with the domElement assigned to the web part:
// ...
export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
public render(): void {
this.domElement.innerHTML = `
<div class="${styles.helloWorld}">
<div class="${styles.container}">
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
<span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span>
<p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.</p>
<p class="ms-font-l ms-fontColor-white">${escape(this.properties.description)}</p>
<a href="https://aka.ms/spfx" class="${styles.button}">
<span class="${styles.label}">Learn more</span>
</a>
</div>
</div>
</div>
</div>`;
}
// ...
}
export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
public render(): void {
this.domElement.innerHTML = `
<div class="${styles.helloWorld}">
<div class="${styles.container}">
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
<span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span>
<p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.</p>
<p class="ms-font-l ms-fontColor-white">${escape(this.properties.description)}</p>
<a href="https://aka.ms/spfx" class="${styles.button}">
<span class="${styles.label}">Learn more</span>
</a>
</div>
</div>
</div>
</div>`;
}
// ...
}
When using jQuery, you should scope its queries to select elements only within the domElement:
// ...
export default class WeatherWebPart extends BaseClientSideWebPart<IWeatherWebPartProps> {
private container: JQuery;
public render(): void {
if (this.renderedOnce === false) {
this.domElement.innerHTML = `<div class="${styles.weather}"></div>`;
}
this.container = jQuery(`.${styles.weather}`, this.domElement);
// ...
}
// ...
}
export default class WeatherWebPart extends BaseClientSideWebPart<IWeatherWebPartProps> {
private container: JQuery;
public render(): void {
if (this.renderedOnce === false) {
this.domElement.innerHTML = `<div class="${styles.weather}"></div>`;
}
this.container = jQuery(`.${styles.weather}`, this.domElement);
// ...
}
// ...
}
When building field customizers, you should work with the DIV assigned to the cell of the associated field:
// ...
export default class HelloWorldFieldCustomizer
extends BaseFieldCustomizer<IHelloWorldProperties> {
// ...
@override
public onRenderCell(event: IFieldCustomizerCellEventParameters): void {
const text: string = '[' + CellFormatter.renderAsText(this.context.column, event.cellValue) + ']';
event.cellDiv.innerText = text;
event.cellDiv.classList.add(styles.cell);
}
// ...
}
export default class HelloWorldFieldCustomizer
extends BaseFieldCustomizer<IHelloWorldProperties> {
// ...
@override
public onRenderCell(event: IFieldCustomizerCellEventParameters): void {
const text: string = '[' + CellFormatter.renderAsText(this.context.column, event.cellValue) + ']';
event.cellDiv.innerText = text;
event.cellDiv.classList.add(styles.cell);
}
// ...
}
In application customizers you can add markup to the DOM using known placeholders:
import {
Placeholder
} from '@microsoft/sp-application-base';
// ...
export default class HelloWorldApplicationCustomizer
extends BaseApplicationCustomizer<IHelloWorldApplicationCustomizerProperties> {
// ...
@override
public onRender(): void {
const headerPlaceholder: Placeholder = this.context.placeholders.tryAttach(
'PageHeader',
{
onDispose: this.onDispose
});
if (headerPlaceholder) {
headerPlaceholder.domElement.innerHTML = `
<div class="${styles.app}">
<div class="ms-bgColor-themeDark ms-fontColor-white ${styles.header}">
<i class="ms-Icon ms-Icon--Info" aria-hidden="true"></i> ${escape(this.properties.header)}
</div>
</div>`;
}
}
private onDispose(): void {
}
}
Placeholder
} from '@microsoft/sp-application-base';
// ...
export default class HelloWorldApplicationCustomizer
extends BaseApplicationCustomizer<IHelloWorldApplicationCustomizerProperties> {
// ...
@override
public onRender(): void {
const headerPlaceholder: Placeholder = this.context.placeholders.tryAttach(
'PageHeader',
{
onDispose: this.onDispose
});
if (headerPlaceholder) {
headerPlaceholder.domElement.innerHTML = `
<div class="${styles.app}">
<div class="ms-bgColor-themeDark ms-fontColor-white ${styles.header}">
<i class="ms-Icon ms-Icon--Info" aria-hidden="true"></i> ${escape(this.properties.header)}
</div>
</div>`;
}
}
private onDispose(): void {
}
}
Disclaimer: The views and opinions expressed in this documentation and in SPCAF do not necessarily reflect the opinions and recommendations of Microsoft or any member of Microsoft. SPCAF and RENCORE are registered trademarks of Rencore. All other trademarks, service marks, collective marks, copyrights, registered names, and marks used or cited by this documentation are the property of their respective owners.