如何等待脚本加载

时间:2019-02-21 16:48:44

标签: javascript google-chrome-extension

我正在构建一个Chrome扩展程序,并且在我的contentScript中,我具有一个循环所有itemTapped(item) { this.selectedItem = item; this.selectedItem.wasClicked = true; console.log(this.selectedItem); this.addTable = true; this.refreshRows(); } refreshRows() { this.editRowIndex = null; this.selectedItem.service.find() .subscribe(data => { this.rows = data; console.log("The data id is: " + data.id); }); } cancelTapped() { this.addTable = false; } addTapped(event, cell, rowIndex) { const prompt = this.alertCtrl.create({ title: "Add " + this.selectedItem.label.slice(0, this.selectedItem.label.length-this.selectedItem.trimSingle), cssClass: 'buttonCss', enableBackdropDismiss: false, inputs: [ { name: 'name', } ], buttons: [ { text: 'Cancel', cssClass: 'item-button button button-md button-outline button-outline-md' }, { text: 'Save', handler: data => { this.saveNewRow(data); }, cssClass: 'buttonColor item-button button button-md button-default button-default-md button-md-pm-yellow' }, ], }); prompt.present(); console.log("You clicked on a detail."); } saveNewRow(data) { this.selectedItem.service.findOne({order: "id DESC"}).subscribe(result => { console.log('The result is ', result); this.editRowId = result.id+1; this.editRowData = { id: this.editRowId, name: data.name }; console.log('editRowData is ', this.editRowData); this.selectedItem.service.create(this.editRowData).subscribe(result => { this.refreshRows(); }); }) } saveRow(name) { let newName = name.nativeElement.value; if (newName !== this.editRowData["name"]) { this.editRowData["name"] = newName; this.selectedItem.service.updateAttributes(this.editRowData["id"], this.editRowData).subscribe(result => { let rows = this.rows; this.editRowIndex = null; this.rows = [...this.rows]; }) } } editRow(rowIndex) { this.editRowData = this.rows[rowIndex]; this.editRowId = this.rows[rowIndex].id; this.editRowName = this.rows[rowIndex].name; this.editRowIndex = rowIndex; setTimeout(() => this.name.nativeElement.focus(), 50); } cancelEditRow(rowIndex) { this.rows[rowIndex].name = this.editRowName; this.editRowIndex = null; } deleteRow(rowIndex) { this.selectedItem.service.deleteById(this.rows[rowIndex].id) .subscribe(result => { this.refreshRows() }, error => { console.log(error); const noDelete = this.alertCtrl.create({ title: this.rows[rowIndex].name + ' is in use and cannot be deleted.', // subTitle: 'You cannot delete this ' + this.selectedItem.label.slice(0, this.selectedItem.label.length-this.selectedItem.trimSingle), buttons: [ { text: 'Dismiss', cssClass: 'item-button button button-md button-outline button-outline-md' } ] }); noDelete.present(); }); } } 元素并检查其是否具有<link>属性的函数。如果为true,则扩展名的图标将更改。

contentScript在文档开始处运行并运行该功能。该函数运行rel="preconnect"。当prerender直接在HTML代码中时,该扩展程序可以正常工作。但是,当JS生成prerender时,图标不会更改。可能是因为发生onDomLoaded时脚本未完全加载。

但是,当我改用window.onload时,它确实很慢,并且图标会延迟更改,因为它等待脚本完全加载。如何处理这种情况并仅在需要时等待?

清单

onDomLoaded

ContentScript

content_scripts":
    [{
     "matches": ["https://*/*"],
     "run_at": "document_start",
     "js": ["js/contentScript.js"]
   }]

1 个答案:

答案 0 :(得分:2)

此任务的合适工具是MutationObserver,它监视DOM修改。

由于document_start上的MutationObserver可以减慢页面速度(即使只是一点点),因此我们只会观察到<head>元素,由于其中的元素数量很少,因此速度非常快。

// there's no HEAD yet at document-start, let's wait until we have it
new MutationObserver((mutations, observer) => {
  if (document.head) {
    observer.disconnect();
    monitorLinks();
  }
}).observe(document.documentElement, {childList: true});

function monitorLinks() {
  const onMutation = mutations => {
    for (const {addedNodes} of mutations) {
      for (const n of addedNodes) {
        if (n.nodeName === 'LINK' && n.rel === 'preconnect') {
          processLink(n);
        }
      }
    }
  };
  // the HEAD may have some children already
  onMutation([{
    addedNodes: document.getElementsByTagName('link'),
  }]);
  // watch for the newly added children of HEAD
  new MutationObserver(onMutation).observe(document.head, {childList: true});
}

function processLink(link) {
  console.log(link);
}