我试图在另一个画布上添加一个画布-我如何使这个函数等待开始,直到第一个画布被创建?

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;
    }

当前回答

如果你有权限访问创建画布的代码,只需在画布创建后调用函数即可。

如果您无法访问该代码(例如。如果它是第三方代码,如谷歌maps),那么你可以做的是在一个区间内测试是否存在:

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

但注意-很多时候第三方代码有一个选项来激活你的代码(通过回调或事件触发)当它完成加载。你可以把函数放在这里。区间解实际上是一个糟糕的解,只有在其他方法都不起作用的情况下才应该使用。

其他回答

只需使用递归的setTimeOut:

waitUntilElementIsPresent(callback: () => void): void {
    if (!this.methodToCheckIfElementIsPresent()) {
        setTimeout(() => this.waitUntilElementIsPresent(callback), 500);
        return;
    }
    callback();
}

用法:

this.waitUntilElementIsPresent(() => console.log('Element is present!'));

您可以限制尝试次数,因此当元素在限制之后不存在时将抛出错误:

waitUntilElementIsPresent(callback: () => void, attempt: number = 0): void {
    const maxAttempts = 10;
    if (!this.methodToCheckIfElementIsPresent()) {
        attempt++;
        setTimeout(() => this.waitUntilElementIsPresent(callback, attempt), 500);
        return;
    } else if (attempt >= maxAttempts) {
        return;
    }
    callback();
}

Iftah的另一种变体

var counter = 10;
var checkExist = setInterval(function() {
  console.log(counter);
  counter--
  if ($('#the-canvas').length || counter === 0) {
    console.log("by bye!");
    clearInterval(checkExist);
  }
}, 200);

以防元素从未显示,所以我们不进行无限检查。

也许我有点晚了:),但这里有一个很好的和简短的解决方案,由chrisjhoughton,它允许执行回调函数当等待结束。

https://gist.github.com/chrisjhoughton/7890303

var waitForEl = function(selector, callback) {
  if (jQuery(selector).length) {
    callback();
  } else {
    setTimeout(function() {
      waitForEl(selector, callback);
    }, 100);
  }
};

waitForEl(selector, function() {
  // work the magic
});

如果你需要将参数传递给回调函数,你可以这样使用它:

waitForEl("#" + elDomId, () => callbackFunction(param1, param2));

但是要小心!默认情况下,这个解决方案会陷入一个无限循环的陷阱。

在GitHub线程中还提供了对topicstarter建议的几个改进。

享受吧!

这只适用于现代浏览器,但我发现它更容易使用一个then,所以请先测试,但是:

ES5

function rafAsync() {
    return new Promise(resolve => {
        requestAnimationFrame(resolve); //faster than set time out
    });
}

function checkElement(selector) {
    if (document.querySelector(selector) === null) {
        return rafAsync().then(() => checkElement(selector));
    } else {
        return Promise.resolve(true);
    }
}

ES6

async function checkElement(selector) {
    const querySelector = null;
    while (querySelector === null) {
        await rafAsync();
        querySelector = document.querySelector(selector);
    }
    return querySelector;
}  

使用

checkElement('body') //use whichever selector you want
.then((element) => {
     console.info(element);
     //Do whatever you want now the element is there
});

这是对杰米·哈伯的回答的一个小小的改进

const checkElement = async selector => {
  while ( document.querySelector(selector) === null) {
    await new Promise( resolve =>  requestAnimationFrame(resolve) )
  }
  return document.querySelector(selector); 
};

使用方法:

checkElement('.myElement').then((selector) => {
  console.log(selector);
});