Javascript 有没有';元素渲染';事件
我需要准确地测量web应用程序中文本的尺寸,我通过创建一个元素(使用相关的CSS类),设置其Javascript 有没有';元素渲染';事件,javascript,dom,Javascript,Dom,我需要准确地测量web应用程序中文本的尺寸,我通过创建一个元素(使用相关的CSS类),设置其innerHTML,然后使用appendChild将其添加到容器中来实现这一点 执行此操作后,在渲染元素之前需要等待一段时间,然后才能读取元素的偏移宽度,以了解文本的宽度 目前,我正在使用setTimeout(processText,100)等待渲染完成 是否有任何回调我可以听,或更可靠的方式告诉我什么时候我创建的元素已经被呈现?目前没有DOM事件表明元素已经被完全呈现(例如,附加的CSS应用和绘制)。这
innerHTML
,然后使用appendChild
将其添加到容器中来实现这一点
执行此操作后,在渲染元素之前需要等待一段时间,然后才能读取元素的偏移宽度
,以了解文本的宽度
目前,我正在使用setTimeout(processText,100)
等待渲染完成
是否有任何回调我可以听,或更可靠的方式告诉我什么时候我创建的元素已经被呈现?目前没有DOM事件表明元素已经被完全呈现(例如,附加的CSS应用和绘制)。这会使一些DOM操作代码返回错误或随机结果(例如获取元素的高度) 使用setTimeout为浏览器提供一些渲染开销是最简单的方法。使用
setTimeout(function(){}, 0)
可能是最实际准确的,因为它将您的代码毫不延迟地放在活动浏览器事件队列的末尾-换句话说,您的代码在渲染操作(以及当时发生的所有其他操作)之后立即排队。Swizec Teller建议使用requestAnimationFrame
,并检查元素的大小
function try() {
if (!$("#element").size()) {
window.requestAnimationFrame(try);
} else {
$("#element").do_some_stuff();
}
};
实际上,它只重试一次。因为无论发生什么情况,在下一个渲染帧之前,无论是60秒还是一分钟,元素都将被渲染
例如,当你制作
var clonedForm = $('#empty_form_to_clone').clone(true)[0];
var newForm = $(clonedForm).html().replace(/__prefix__/g, next_index_id_form);
// next_index_id_form is just a integer
我在这里干什么?
我克隆一个已经呈现的元素,并更改要呈现的html
接下来,我将该文本附加到一个容器中
$('#container_id').append(newForm);
当我想将事件处理程序添加到newForm中的按钮时,问题就出现了,WELL,只需使用ready事件即可
$(clonedForm).ready(function(event){
addEventHandlerToFormButton();
})
我希望这对你有帮助
PS:对不起,我的英语不好。被接受的答案是2014年的,现在已经过时了。setTimeout
可以工作,但它不是最干净的,也不一定保证元素已添加到DOM中
var myElement = $("<div>hello world</div>")[0];
var observer = new MutationObserver(function(mutations) {
if (document.contains(myElement)) {
console.log("It's in the DOM!");
observer.disconnect();
}
});
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
$("body").append(myElement); // console.log: It's in the DOM!
从2018年起,当元素添加到DOM中时,您应该使用a来检测。现在所有现代浏览器(Chrome 26+、Firefox 14+、IE11、Edge、Opera 15+等)都广泛支持MutationObserver
将元素添加到DOM后,您将能够检索其实际维度
下面是一个简单的示例,说明如何使用MutationObserver
来侦听向DOM添加元素的时间
var myElement = $("<div>hello world</div>")[0];
var observer = new MutationObserver(function(mutations) {
if (document.contains(myElement)) {
console.log("It's in the DOM!");
observer.disconnect();
}
});
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
$("body").append(myElement); // console.log: It's in the DOM!
为简洁起见,我使用jQuery语法构建节点并将其插入DOM
var myElement = $("<div>hello world</div>")[0];
var observer = new MutationObserver(function(mutations) {
if (document.contains(myElement)) {
console.log("It's in the DOM!");
observer.disconnect();
}
});
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
$("body").append(myElement); // console.log: It's in the DOM!
var myElement=$(“你好世界”)[0];
var观察者=新的突变观察者(功能(突变){
if(document.contains(myElement)){
log(“它在DOM中!”);
observer.disconnect();
}
});
observe(文档,{attributes:false,childList:true,characterData:false,subtree:true});
$(“正文”)。附加(myElement);//console.log:它在DOM中!
每当从文档中添加或删除任何节点时,观察者
事件处理程序将触发。在处理程序内部,我们然后执行contains
检查,以确定myElement
现在是否在文档中
您不需要迭代存储在translations
中的每个MutationRecord,因为您可以直接在myElement
上执行文档。contains
检查
为了提高性能,将document
替换为将在DOM中包含myElement
的特定元素。MutationObserver可能是最好的方法,但这里有一个简单的替代方法可以工作
我有一些javascript为一个大表构建HTML,并将div的innerHTML设置为生成的HTML。如果在设置innerHTML后立即获取Date()
,我发现时间戳是在表完全呈现之前的一段时间。我想知道渲染需要多长时间(这意味着在渲染完成后我需要检查Date()
)。我发现可以通过设置div的innerHTML,然后(在相同的脚本中)调用页面上某个按钮的click方法来实现这一点。单击处理程序将仅在HTML完全呈现之后执行,而不仅仅是在设置了div的innerHTML属性之后。我通过比较click处理程序生成的Date()值与设置div的innerHTML属性的脚本检索到的Date()值来验证这一点
希望有人觉得这个有用假设您的元素有classname class=“test”
如果发生更改,以下功能将继续测试
如果是,请运行该函数
function addResizeListener(elem, fun) {
let id;
let style = getComputedStyle(elem);
let wid = style.width;
let hei = style.height;
id = requestAnimationFrame(test)
function test() {
let newStyle = getComputedStyle(elem);
if (wid !== newStyle.width ||
hei !== newStyle.height) {
fun();
wid = newStyle.width;
hei = newStyle.height;
}
id = requestAnimationFrame(test);
}
}
let test = document.querySelector('.test');
addResizeListener(test,function () {
console.log("I changed!!")
});
根据@Elliot B.的回答,我制定了一个适合我的计划
const callback=()=>{
const el=document.querySelector('a');
如果(el){
observer.disconnect();
el.addEventListener('click',()=>{});
}
};
const observer=新的MutationObserver(回调);
observer.observe(document.body,{subtree:true,childList:true});
在我的例子中,像setTimeout
或MutationObserver
这样的解决方案不是完全可行的。
相反,我使用了ResizeObserver。根据:
如果实现遵循规范,则应调用
在绘制之前和布局之后调整事件大小
因此,基本上,观察者总是在布局之后激发,因此我们应该能够得到被观察元素的正确尺寸。
作为奖励,观察者已经返回元素的维度。因此,我们甚至不需要调用类似于offsetWidth
的东西(即使它也应该可以工作)
constmyelement=document.createElement(“div”);
myElement.textContent=“测试字符串”;
常数