加载innerHTML中的外部元素后的回调

时间:2017-10-15 09:28:03

标签: javascript html

我在javascript中有一个字符串,我想用它来实例化特定元素的子元素,例如:

let target = document.getElementById("target")
let string = ```
    <div>
        <img src="somewhere">

        <h1> This is a heading </h1>

        <p> And some text <p>
    </div>
```
target.innerHTML = string

后来,我想找到标题的偏移量:

// ...
// later
// ...

let heading = target.getElementByTagName("h1")
console.log(heading.offsetTop)

但有时它不正确,因为有时图像(或任何其他外部元素)已加载,有时它在我找到偏移之前没有加载。任何人都可以建议 jquery免费方式来确定target的内容何时完成加载所有外部资源?

2 个答案:

答案 0 :(得分:2)

您最好的选择可能是为每个可加载项添加一个load侦听器 在你的目标中,然后在它们全部加载时发出回调。

&#13;
&#13;
let onReady = (target, callback) => {
  // add any other tags you have that need to load to the selector
  // i.e. querySelectorAll('img, iframe'), etc.
  let loadables = [...target.querySelectorAll('img')];

  let total = loadables.length;
  let doneCount = 0;

  // since I'm using bind this needs to be a normal function, not an arrow function
  let loadObserver = function() {
    // remove the listener since we don't need it anymore
    this.removeEventListener('load', loadObserver);
    doneCount += 1;
    if (doneCount === total) {
      callback();
    }
  };

  loadables.forEach(el => {
    el.addEventListener('load', loadObserver.bind(el), true);
  });
};


  let target = document.getElementById("target");
  let string = `
  <div>
      <img id="i1" src="http://via.placeholder.com/350x50">
      <img id="i2">
      <img id="i3">
      <h1> This is a heading </h1>

      <p> And some text <p>
  </div>
  `;
  target.innerHTML = string;

  // note that you have to call onReady right away after setting the
  // innerHTML, since JS is single threaded calling it now will add the
  // load listeners before any of the images start to load. If you call
  // it later, after the event loop has run, it might not work.
  onReady(target, () => {
    let heading = target.querySelector("h1");
    console.log(heading.offsetTop);
  });






// simulate slow loading images
let loadAfter = (el, ms) => {
  setTimeout(() => {
     el.src = 'http://via.placeholder.com/350x50';
  }, ms);
};

loadAfter(document.getElementById('i2'), 2000);
loadAfter(document.getElementById('i3'), 3000);
&#13;
img {
  border: 1px solid #000;
  background: #ccc;
}

#target {
  border: 1px dashed #f00;
}
&#13;
<div id="target"></div>
&#13;
&#13;
&#13;

关于你的代码的其他一些注意事项,在JS template literals中只有一个反引号,而不像其他语言中的HEREDOC需要3.还使用了不存在的getElementByTagName方法。有getElementsByTagName方法(请注意元素中的 s ),但它返回一个集合,而不是单个节点。您可以使用target.getElementsByTagName('h1')[0]来获取您要查找的元素,但在我的代码中,我使用了querySelector,它总是返回一个元素。

答案 1 :(得分:-1)

t=# with v(a) as( values('12 2 NOELA PLACE ST MARYS NSW 2760 AU')
,('51 MALABAR ROAD SOUTH COOGEE NSW 2034 AU')
,('12 LISTER STREET WINSTON HILLS NSW 2153 AU')
)
select reverse(split_part(reverse(a),' ',1)), reverse(split_part(reverse(a),' ',3)), case when split_part(a,' ',2) ~ '\d' then split_part(a,' ',2) end st, split_part(a,' ',1) un from v;
 reverse | reverse | st | un
---------+---------+----+----
 AU      | NSW     | 2  | 12
 AU      | NSW     |    | 51
 AU      | NSW     |    | 12
(3 rows)

imageIsLoaded()可以是一个javascript函数。