如何降低JavaScript代码的执行速度?
我正在写一个脚本来删除我在YouTube上的所有评论。这段代码的每一行都可以删除一条注释,但当我将其放入循环中时,会得到一个如何降低JavaScript代码的执行速度?,javascript,youtube,Javascript,Youtube,我正在写一个脚本来删除我在YouTube上的所有评论。这段代码的每一行都可以删除一条注释,但当我将其放入循环中时,会得到一个未捕获的TypeError:cannotread属性“click”of undefined,当我单独运行每一行时,该属性不会出现。我在想,如果我能想出一种在代码行之间休眠的方法,我就可以消除错误 var myList = document.getElementsByClassName("dropdown-trigger style-scope ytd-menu-render
未捕获的TypeError:cannotread属性“click”of undefined
,当我单独运行每一行时,该属性不会出现。我在想,如果我能想出一种在代码行之间休眠的方法,我就可以消除错误
var myList = document.getElementsByClassName("dropdown-trigger style-scope ytd-menu-renderer");
for(i = 0; i < myList.length; i++) {
myList[i].click();
document.getElementsByClassName("style-scope ytd-menu-navigation-item-renderer")[4].click(); //error here
document.getElementById("confirm-button").click();
}
var myList=document.getElementsByClassName(“下拉触发器样式范围ytd菜单渲染器”);
对于(i=0;i
我尝试使用setTimeout,如下所示:
var myList = document.getElementsByClassName("dropdown-trigger style-scope ytd-menu-renderer");
for(i=0; i<myList.length; i++) {
myList[i].click();
setTimeout(function(){document.getElementsByClassName("style-scope ytd-menu-navigation-item-renderer")[4].click();}, 1000);
setTimeout(function(){document.getElementById("confirm-button").click();}, 5000);
}
var myList=document.getElementsByClassName(“下拉触发器样式范围ytd菜单渲染器”);
对于(i=0;i而言,罪魁祸首是自从您执行函数以来,页面一直没有时间更新DOM。单击()
函数。您需要给它时间,可能是在下面的解决方案中使用requestAnimationFrame
或不太精确的setTimeout
。(完全未经测试,现场制作),进程是在暂停后执行每个操作(打开下拉列表,单击删除,确认),以给DOM时间进行更新。请考虑:
function deleteAllComments ( ) {
'use strict';
var commentsToDelete, i;
function openNextCommentOptionsDropdown ( ) {
if ( ! (++i < commentsToDelete.length ) ) {
console.log('No more comments to remove.');
return;
}
commentsToDelete[i].click();
setTimeout(activateCommentDeleteButton, 50);
}
function activateCommentDeleteButton ( ) {
var el = document.getElementsByClassName("style-scope ytd-menu-navigation-item-renderer")[4];
if ( ! el ) {
console.warn('No "Delete" button found, at comment #', i, commentsToDelete[i]);
console.log('Stopping delete operation');
return;
}
el.click();
setTimeout(activateCommentDeleteConfirmationButton, 50);
}
function activateCommentDeleteConfirmationButton ( ) {
var el = document.getElementById("confirm-button");
if ( ! el ) {
console.warn('Unable to confirm comment delete action, at comment #', i, commentsToDelete[i]);
console.log('Stopping delete operation');
return;
}
el.click();
setTimeout(openNextCommentOptionsDropdown, 50); // continue larger "loop"
}
commentsToDelete = document.getElementsByClassName("dropdown-trigger style-scope ytd-menu-renderer");
openNextCommentOptionsDropdown(); // start the "loop"
}
函数deleteAllComments(){
"严格使用",;
var,删除,i;
函数OpenNextCommonOptions下拉列表(){
如果(!(++i
这里有两大细节:
为DOM提供更新时间以响应代码已启动的操作(setTimeout(…,50)
,其中50ms应该足够长;根据需要减少,或者只使用requestAnimationFrame
)
防御性编码:在对返回的项目盲目执行函数之前,首先检查项目是否确实存在(if(!el){…}
)
罪魁祸首是,自从您执行.click()
函数以来,页面一直没有时间更新DOM。您需要给它时间,可能是使用requestAnimationFrame
或下面解决方案中精度较低的setTimeout
。(完全未经测试,现场制作),进程是在暂停后执行每个操作(打开下拉列表,单击删除,确认),以给DOM时间进行更新。请考虑:
function deleteAllComments ( ) {
'use strict';
var commentsToDelete, i;
function openNextCommentOptionsDropdown ( ) {
if ( ! (++i < commentsToDelete.length ) ) {
console.log('No more comments to remove.');
return;
}
commentsToDelete[i].click();
setTimeout(activateCommentDeleteButton, 50);
}
function activateCommentDeleteButton ( ) {
var el = document.getElementsByClassName("style-scope ytd-menu-navigation-item-renderer")[4];
if ( ! el ) {
console.warn('No "Delete" button found, at comment #', i, commentsToDelete[i]);
console.log('Stopping delete operation');
return;
}
el.click();
setTimeout(activateCommentDeleteConfirmationButton, 50);
}
function activateCommentDeleteConfirmationButton ( ) {
var el = document.getElementById("confirm-button");
if ( ! el ) {
console.warn('Unable to confirm comment delete action, at comment #', i, commentsToDelete[i]);
console.log('Stopping delete operation');
return;
}
el.click();
setTimeout(openNextCommentOptionsDropdown, 50); // continue larger "loop"
}
commentsToDelete = document.getElementsByClassName("dropdown-trigger style-scope ytd-menu-renderer");
openNextCommentOptionsDropdown(); // start the "loop"
}
函数deleteAllComments(){
"严格使用",;
var,删除,i;
函数OpenNextCommonOptions下拉列表(){
如果(!(++i
这里有两大细节:
为DOM提供更新时间以响应代码已启动的操作(setTimeout(…,50)
,其中50ms应该足够长;根据需要减少,或者只使用requestAnimationFrame
)
防御性编码:在对返回的项目盲目执行函数之前,首先检查项目是否确实存在(if(!el){…}
)
下面的所有选项都有点“黑客”——但当点击事件被完全处理时,没有一致且简单的方式获得通知。
您可以将自己的click事件侦听器添加到目标元素,但是,可以通过StopRopagation将其“静音”。。。
即使这样,也没有(简单的)方法知道DOM何时完成了由于单击事件而导致的“重新绘制”——您可以使用
我
var DELAY = 0; // try 0, then try increasing values
var myList = document.getElementsByClassName("dropdown-trigger style-scope ytd-menu-renderer");
var p = Promise.resolve();
for(i = 0; i < myList.length; i++) {
myList[i].click();
p = p.then(() => new Promise(resolve) => {
setTimeout(() => {
document.getElementsByClassName("style-scope ytd-menu-navigation-item-renderer")[4].click();
setTimeout(() => {
document.getElementById("confirm-button").click();
setTimeout(resolve, DELAY);
}, DELAY);
}, DELAY);
});
}
const DELAY = 0; // try 0, then try increasing values
const clickThenDelay = element => new Promise(resolve => {
element.click();
setTimeout(resolve, DELAY);
});
var myList = document.getElementsByClassName("dropdown-trigger style-scope ytd-menu-renderer");
Array.from(myList).reduce((p, item) => {
return p
.then(() => clickThenDelay(item))
.then(() => clickThenDelay(document.getElementsByClassName("style-scope ytd-menu-navigation-item-renderer")[4]))
.then(() => clickThenDelay(document.getElementById("confirm-button")))
}, Promise.resolve());
const DELAY = 0; // try 0, then try increasing values
const clickThenDelay = element => new Promise(resolve => {
const handleClick = () => {
element.removeEventListener('click', handleClick);
setTimeout(resolve, DELAY); // wait for repaint? Perhaps a MutationObserver event could be useful here?
}
element.addEventListener('click', handleClick);
element.click();
});
var myList = document.getElementsByClassName("dropdown-trigger style-scope ytd-menu-renderer");
Array.from(myList).reduce((p, item) => {
return p
.then(clickThenDelay(item))
.then(() => clickThenDelay(document.getElementsByClassName("style-scope ytd-menu-navigation-item-renderer")[4]))
.then(() => clickThenDelay(document.getElementById("confirm-button")))
}, Promise.resolve());