使函数等到元素存在

我试图添加一个canvas在另一个canvas上 – 我怎样才能使这个函数等待开始,直到第一个canvas创build?

function PaintObject(brush) { this.started = false; // get handle of the main canvas, as a DOM object, not as a jQuery Object. Context is unfortunately not yet // available in jquery canvas wrapper object. var mainCanvas = $("#" + brush).get(0); // Check if everything is ok if (!mainCanvas) {alert("canvas undefined, does not seem to be supported by your browser");} if (!mainCanvas.getContext) {alert('Error: canvas.getContext() undefined !');} // Get the context for drawing in the canvas var mainContext = mainCanvas.getContext('2d'); if (!mainContext) {alert("could not get the context for the main canvas");} this.getMainCanvas = function () { return mainCanvas; } this.getMainContext = function () { return mainContext; } // Prepare a second canvas on top of the previous one, kind of second "layer" that we will use // in order to draw elastic objects like a line, a rectangle or an ellipse we adjust using the mouse // and that follows mouse movements var frontCanvas = document.createElement('canvas'); frontCanvas.id = 'canvasFront'; // Add the temporary canvas as a second child of the mainCanvas parent. mainCanvas.parentNode.appendChild(frontCanvas); if (!frontCanvas) { alert("frontCanvas null"); } if (!frontCanvas.getContext) { alert('Error: no frontCanvas.getContext!'); } var frontContext = frontCanvas.getContext('2d'); if (!frontContext) { alert("no TempContext null"); } this.getFrontCanvas = function () { return frontCanvas; } this.getFrontContext = function () { return frontContext; } 

如果您可以访问创buildcanvas的代码 – 只需在创buildcanvas后直接调用该函数即可。

如果你没有访问该代码(例如,如果它是第三方代码,如谷歌地图),那么你可以做的是testing存在的时间间隔:

 var checkExist = setInterval(function() { if ($('#the-canvas').length) { console.log("Exists!"); clearInterval(checkExist); } }, 100); // check every 100ms 

但请注意 – 很多时候,第三方代码有一个选项来激活你的代码(通过callback或事件触发),当它完成加载。 这可能是你可以把你的function。 间隔解决scheme真的是一个不好的解决scheme,应该只有在没有其他的工作时才使用。

根据您需要支持的浏览器,可以selectMutationObserver 。

一些沿着这个线应该做的伎俩:

 // callback executed when canvas was found function handleCanvas(canvas) { ... } // set up the mutation observer var observer = new MutationObserver(function (mutations, me) { // `mutations` is an array of mutations that occurred // `me` is the MutationObserver instance var canvas = document.getElementById('my-canvas'); if (canvas) { handleCanvas(canvas); me.disconnect(); // stop observing return; } }); // start observing observer.observe(document, { childList: true, subtree: true }); 

NB我自己没有testing过这个代码,但是这是一般的想法。

你可以很容易地扩展它,只search改变的DOM部分。 为此,使用variables参数,它是一个MutationRecord对象的数组。

这非常简单 – 只要在你已经创build了canvas之前不要调用这个函数(即在这个click处理程序中执行)。

您可以通过设置一个超时直到它已经在dom中呈现来检查dom是否已经存在。

 var panelMainWrapper = document.getElementById('panelMainWrapper'); setTimeout(function waitPanelMainWrapper() { if (document.body.contains(panelMainWrapper)) { $("#panelMainWrapper").html(data).fadeIn("fast"); } else { setTimeout(waitPanelMainWrapper, 10); } }, 10); 

requestAnimationFrame中传递比在setTimeout更好。 这是我在es6模块中使用Promise的解决scheme。

es6,模块和承诺:

 // onElementReady.js const onElementReady = $element => ( new Promise((resolve) => { const waitForElement = () => { if ($element) { resolve($element); } else { window.requestAnimationFrame(waitForElement); } }; waitForElement(); }) ); export default onElementReady; // in your app import onElementReady from './onElementReady'; const $someElement = document.querySelector('.some-className'); onElementReady($someElement) .then(() => { // your element is ready } 

plain js and promises

 var onElementReady = function($element) { return new Promise((resolve) => { var waitForElement = function() { if ($element) { resolve($element); } else { window.requestAnimationFrame(waitForElement); } }; waitForElement(); }) }; var $someElement = document.querySelector('.some-className'); onElementReady($someElement) .then(() => { // your element is ready }