我试图在另一个画布上添加一个画布-我如何使这个函数等待开始,直到第一个画布被创建?
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;
}
这是一种纯粹的基于承诺的JavaScript方法,您可以知道需要等待多少毫秒。
const waitElementFor = function(query, ms = 3000) { // 3000 === 3 seconds
return new Promise((resolve) => {
var waited = 0;
var el = null;
var wi = setInterval(function() {
el = document.querySelector(query);
if (waited >= ms || el) {
clearInterval(wi);
if(el) {
resolve(el);
} else {
resolve(null);
}
}
waited += 10;
}, 10);
});
}
要使用该函数,只需在异步函数中使用以下代码。
var element = await waitElementFor('#elementID');
代码片段:
const waitElementFor = function(query, ms = 3000) { // 3000 === 3 seconds
return new Promise((resolve) => {
var waited = 0;
var el = null;
var wi = setInterval(function() {
el = document.querySelector(query);
if (waited >= ms || el) {
clearInterval(wi);
if(el) {
resolve(el);
} else {
resolve(null);
}
}
waited += 10;
}, 10);
});
}
async function snippetTestAyncFunction(){
var element = await waitElementFor('#elementID');
console.log(element);
}
snippetTestAyncFunction();
如果你有权限访问创建画布的代码,只需在画布创建后调用函数即可。
如果您无法访问该代码(例如。如果它是第三方代码,如谷歌maps),那么你可以做的是在一个区间内测试是否存在:
var checkExist = setInterval(function() {
if ($('#the-canvas').length) {
console.log("Exists!");
clearInterval(checkExist);
}
}, 100); // check every 100ms
但注意-很多时候第三方代码有一个选项来激活你的代码(通过回调或事件触发)当它完成加载。你可以把函数放在这里。区间解实际上是一个糟糕的解,只有在其他方法都不起作用的情况下才应该使用。
这是为那些在Chrome控制台上运行代码而不是硬编码到html的人准备的。
上面User993683提供的代码将在您的控制台代码中工作。他/她的代码如下:
while(!document.querySelector(".my-selector")) {
await new Promise(r => setTimeout(r, 500));
}
// now the element is loaded
他/她补充说,它“需要在一个异步函数中。”如果你在Chrome的控制台中使用代码,那么实际上你不需要把它包装在一个函数中。它会像写的那样工作。您只需要将它放在代码中试图访问元素之前的位置,以确保它存在。
唯一需要注意的是,它不适用于在其他情况下偶尔出现的元素。否则,如果元素从未下载,它将无限循环,您将不得不关闭浏览器来停止等待。只对您确定会出现的元素使用它。
我的公司的表单页面为每个案例号都有十几个或更多的字段需要填写。我每天在脚本数组中有数百个案例编号。当改变iFrame SRC和“onload”不工作在Chrome控制台脚本时,元素不同时加载。所以这个方法对我来说是天赐之物,它每天为我节省了至少45分钟,而不是因为加载时间的波动而在这里等10秒或在那里等30秒。
我所做的唯一改变是“getElementById”而不是一般的“querySelector”,因为我需要的所有元素都有ID。
while(!document.getElementById("myFrame").contentWindow.document.getElementById('someDocID')) {
await new Promise(r => setTimeout(r, 500));
}
// After completing the wait above it is now safe to access the element
document.getElementById("myFrame").contentWindow.document.getElementById('someDocID'
).innerText = "Smith, John R";
// and now click the submit button then change the SRC to a fresh form, and use
//*emphasized text* the code again to wait for it to fully load
我向监控器道歉,但我添加了这个作为回答,因为在对控制台脚本进行了几个月的研究并等待元素加载之后,user993683关于函数的评论最终使我意识到控制台脚本不需要此代码的函数。我在这里的目标只是让其他consoler脚本用户不必像我一样经历同样的学习曲线。