我正在为价格范围实现一个双滑块。当用户滑动以选择特定范围时,需要显示该值。为此,我使用了运行良好的 innerHTML。但是有一个错误说
"Uncaught TypeError: Cannot read property 'nodeType' of null
at NodePart._setText (lit-html.ts:657)
at NodePart.setValue (lit-html.ts:616)
at TemplateInstance.update (lit-html.ts:810)
at render (shady-render.ts:159)
at HTMLElement._applyRender (lit-element.ts:286)
at HTMLElement._propertiesChanged (lit-element.ts:218)
at HTMLElement._flushProperties (properties-changed.js:387)
at HTMLElement._flushProperties (lit-element.ts:232)
at properties-changed.js:334
at MutationObserver.microtaskFlush (async.js:41)".
我搜索了很多,得到的答案是,一个是如果在加载DOM之前调用的函数,另一个是在lit-html中没有使用innerHTML。请帮助我摆脱该错误。
import {LitElement, html} from '@polymer/lit-element';
import {connect} from 'pwa-helpers/connect-mixin.js';
import {store} from '../../redux/store.js';
import {style} from './genie-flex-css.js';
import {repeat} from 'lit-html/lib/repeat';
export class GenieSlider extends connect(store)(LitElement) {
static get is() {
return 'genie-slider';
}
static get properties() {
// TODO: declare the properties here.
return {
minimum: Number,
maximum: Number
};
}
constructor() {
super();
// TODO: Initialize the properties here
this.minimum = 0;
this.maximum = 10000;
}
requestRender() {
this._invalidateProperties();
}
_invalidateProperties() {
this.__isInvalid = true;
super._invalidateProperties();
}
minPrice(e) {
this.dispatchEvent(new CustomEvent('GG:minPriceChanged', {
bubbles: false,
detail: {
event: e,
value: e.currentTarget.value
}
}));
e.stopPropagation();
this.selectedOption = e.currentTarget.value;
this.minimum = this.selectedOption;
this.requestRender();
}
maxPrice(e) {
this.dispatchEvent(new CustomEvent('GG:maxPriceChanged', {
bubbles: false,
detail: {
event: e,
value: e.currentTarget.value
}
}));
e.stopPropagation();
this.selectedOption = e.currentTarget.value;
this.maximum = this.selectedOption;
this.requestRender();
}
_firstRendered() {
}
_render(properties) {
return html `
<style>
${style}
[slider] {
width: 270px;
position: relative;
}
[slider] > div {
position: absolute;
left: 13px;
right: 15px;
height: 5px;
}
[slider] > div > [inverse-left],[slider] > div > [inverse-right] {
position: absolute;
height: 3px;
border-radius: 10px;
background-color: #CCC;
margin: 0 7px;
}
[slider] > div > [inverse-left] {
left: 0;
}
[slider] > div > [inverse-right] {
right: 0;
}
[slider] > div > [range] {
position: absolute;
left: 0;
height: 3px;
border-radius: 14px;
background-color: #d02128;
}
[slider] > div > [thumb] {
position: absolute;
top: -8px;
z-index: 2;
height: 20px;
width: 20px;
text-align: left;
margin-left: -11px;
cursor: pointer;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4);
background-color: #FFF;
border-radius: 50%;
outline: none;
}
[slider] > input[type=range] {
position: absolute;
pointer-events: none;
-webkit-appearance: none;
z-index: 3;
height: 14px;
top: -2px;
width: 100%;
opacity: 0;
}
div[slider] > input[type=range]:focus::-webkit-slider-runnable-track {
background: transparent;
border: transparent;
}
div[slider] > input[type=range]:focus {
outline: none;
}
div[slider] > input[type=range]::-ms-thumb {
pointer-events: all;
width: 28px;
height: 28px;
border-radius: 0px;
border: 0 none;
background: red;
}
div[slider] > input[type=range]::-moz-range-thumb {
pointer-events: all;
width: 28px;
height: 28px;
border-radius: 0px;
border: 0 none;
background: red;
}
div[slider] > input[type=range]::-webkit-slider-thumb {
pointer-events: all;
width: 28px;
height: 28px;
border-radius: 0px;
border: 0 none;
background: red;
-webkit-appearance: none;
}
div[slider] > input[type=range]::-ms-fill-lower {
background: transparent;
border: 0 none;
}
div[slider] > input[type=range]::-ms-fill-upper {
background: transparent;
border: 0 none;
}
div[slider] > input[type=range]::-ms-tooltip {
display: none;
}
[slider] > div > [sign] {
opacity: 0;
position: absolute;
margin-left: -11px;
top: -39px;
z-index:3;
background-color: #d02128;
color: #fff;
width: 28px;
height: 28px;
border-radius: 28px;
-webkit-border-radius: 28px;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
text-align: center;
}
[slider] > div > [sign]:after {
position: absolute;
content: '';
left: 0;
border-radius: 16px;
top: 19px;
border-left: 14px solid transparent;
border-right: 14px solid transparent;
border-top-width: 16px;
border-top-style: solid;
border-top-color: #d02128;
}
[slider] > div > [sign] > span {
font-size: 10px;
font-weight: 700;
line-height: 28px;
}
[slider]:hover > div > [sign] {
opacity: 1;
}
}
</style>
<div slider id="slider-distance">
<div>
<div inverse-left style="width:70%;"></div>
<div inverse-right style="width:70%;"></div>
<div range style="left:${this.minimum? (this.minimum/100)+'%': 0+'%' };right:${this.maximum? 100 - (this.maximum/100)+'%': 0+'%' }"></div>
<span thumb style="left:${this.minimum? (this.minimum/100)+'%': 0+'%' }"></span>
<span thumb style="left:${this.maximum? (this.maximum/100)+'%': 100+'%' }"></span>
<div sign style="left:${this.minimum? (this.minimum/100)+'%': 0+'%' }">
<span id="minResult">${this.minimum}</span>
</div>
<div sign style="left:${this.maximum? (this.maximum/100)+'%': 100+'%' }">
<span id="maxResult">${this.maximum}</span>
</div>
</div>
<input type="range" value="0" max="${this.maximum}" min="0" step="100" oninput="
this.value=Math.min(this.value,this.parentNode.childNodes[5].value-500);
let value = (this.value/parseInt(this.max))*100
var children = this.parentNode.childNodes[1].childNodes;
children[1].style.width=value+'%';
children[5].style.left=value+'%';
children[7].style.left=value+'%';children[11].style.left=value+'%';
children[11].childNodes[1].innerHTML=this.value;" onchange="${e => {this.minPrice(e)}}"/>
<input type="range" value="10000" max="10000" min="${this.minimum}" step="100" oninput="
this.value=Math.max(this.value,this.parentNode.childNodes[3].value-(-500));
let value = (this.value/parseInt(this.max))*100
var children = this.parentNode.childNodes[1].childNodes;
children[3].style.width=(100-value)+'%';
children[5].style.right=(100-value)+'%';
children[9].style.left=value+'%';children[13].style.left=value+'%';
children[13].childNodes[1].innerHTML=this.value;" onchange="${e => {this.maxPrice(e)}}"/>
</div>
`;
}
_stateChanged(state) {
// TODO Set the state dependent properties here
}
}
customElements.define(GenieSlider.is, GenieSlider);