简体   繁体   English

无法将元素添加到DOM

[英]Can't add element to DOM

In component i have some snippet of code 在组件中,我有一些代码片段

  isLoaded($event) {
    console.log($event);
    this.visible = $event;
    console.log(this.visible);
    this.onClick();
  }

  onClick() {
    this.listImage = this.imageService.getImage();
    let span = document.createElement('span');
    span.innerHTML = ['<img class="thumb" src="', this.listImage[0],
      '" title="', '"/>'
    ].join('');
    document.getElementById('previewImg').insertBefore(span, null);
  }

In html code I have 在HTML代码中我有

<div *ngIf="visible">
<div id='previewImg' class="img_content"></div>

$event return true <=> visible = true, but i have error $ event返回true <=> visible = true,但是我有错误

 Cannot read property 'insertBefore' of null

without *ngIf site render fine. 没有* ng如果网站渲染正常。

Why is this happening? 为什么会这样呢?

As per my comment, your issue arises because of a race condition : when the visible property resolves to a truthy value, the ngIf directive will cause the nested DOM node to render. 根据我的评论,您的问题是由于争用条件引起的 :当visible属性解析为真实值时, ngIf指令将导致嵌套的DOM节点呈现。 However, this rendering is not completed when this.onClick() is called, meaning that the DOM nodes within in will return null when queried. 但是,当this.onClick()时,此渲染未完成,这意味着in中的DOM节点在查询时将返回null

In other words, your document.getElementById('previewImg') will return null , and this is the source of the error. 换句话说,您的document.getElementById('previewImg')将返回null ,这是错误的根源。

To circumvent this, you will have to ensure that the selector is executed at the end of the call stack: this can simply be done by using window.setTimeout(fn, 0) , eg: 为了避免这种情况,您必须确保选择器在调用堆栈的末尾执行:这可以简单地通过使用window.setTimeout(fn, 0)来完成,例如:

onClick() {

    // Other logic can happen since they do not depend on the updated DOM
    this.listImage = this.imageService.getImage();
    let span = document.createElement('span');
    span.innerHTML = ['<img class="thumb" src="', this.listImage[0],'" title="', '"/>'].join('');

    // Query at end of callstack
    window.setTimeout(function() {
        document.getElementById('previewImg').insertBefore(span, null);
    }, 0);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM