gpt4 book ai didi

javascript - 为什么我的 HTML 元素 javascript 变量与我在 DOM 中看到的不匹配?

转载 作者:行者123 更新时间:2023-12-04 09:35:26 24 4
gpt4 key购买 nike

我正在使用 javacript 在网页上监听用户输入。发生这种情况时,我想等到元素的某些属性发生更改,然后运行一些代码。我以为我有这个工作,但最近我的代码超时等待更改发生。我已将感兴趣的元素设置为变量,并且在控制台中的 Chrome 开发人员工具中,该变量仍显示旧的属性值,即使网站已明显更改。似乎我的元素实例已经过时并且不再是最新的。这是最后带有更具体问题的代码。请注意,我是 JavaScript 新手,因此超时代码可能不是正确的处理方式。


var tagFromError;
const ACTIVE_SHEET_TAB_CLASS = 'docs-sheet-active-tab';

function respondToAddSheet(){
console.log('adding worked');
}

function addSheetCalled(){
var hSheet = getHSheetByVSheet(activeTag);
if (hSheet) {
waitUntilNotActiveSheet(0, hSheet, respondToAddSheet);
}
}

/**
* Calls a function once the input tag is no longer active
* @param {number} i - A counter on how many times the function has been called
* @param {HTMLElement} tag - hsheet tag which is initially active
* @param {function} fcn - Function to call when 'tag' is no longer active
*/
function waitUntilNotActiveSheet(i,tag,fcn){

if (tag.classList.contains(ACTIVE_SHEET_TAB_CLASS)){
if (i < 20) {
setTimeout(function () {
waitUntilNotActiveSheet(i+1, tag, fcn)
},200)
}else{
console.log('Below is the tag which failed')
tagFromError = tag; //Promote to global for debugging
console.log(tag)
console.log('TIMEOUT FAILURE for ' + 'waitUntilNotActiveSheet');
}
}else{
//When no longer active, call the function
fcn(tag);
}
}

var addSheetButton = document.querySelector('.docs-sheet-add');
addSheetButton.addEventListener('mousedown',addSheetCalled);
基本上,我一直等到标签不再包含特定的类名。然而,这段代码失败了,因为最后类名仍然存在,即使对 DOM 的目视检查表明它不存在。
这是记录标签的开始(来自错误记录或存储的全局变量): <div class="goog-inline-block docs-sheet-tab docs-material docs-sheet-active-tab" role="button" aria-expanded="false" aria-haspopup="true" id=":1u">这表明它仍然具有事件选项卡名称,即使对 DOM 的目视检查表明情况并非如此。

最佳答案

我在 document.querySelector 调用中遇到了异步问题,所以我添加了 async/await 语法;
还为 ACTIVE_SHEET_TAB_CLASS 的值添加了一个句点:

const ACTIVE_SHEET_TAB_CLASS = '.docs-sheet-active-tab';
并且不得不将条件之一更改为:
sheetElements[i].textContent == sheetName.substr(1).trim()
因为 sheetName 有一个 0 和空格导致它永远不会匹配
这是带有异步/语法的代码,它应该在不添加任何内容的情况下运行:
var tagFromError;
const ACTIVE_SHEET_TAB_CLASS = '.docs-sheet-active-tab';

async function addSheetCalled(){
let activeTag = await document.querySelector(ACTIVE_SHEET_TAB_CLASS);
let hSheet = await getHSheetByVSheet(activeTag);
console.log("here!!!!",hSheet)
if (hSheet) {
waitUntilNotActiveSheet(0, hSheet, console.log);
}
}

function waitUntilNotActiveSheet(i,tag,fcn){
if (tag.classList.contains(ACTIVE_SHEET_TAB_CLASS)){
if (i < 20) {
setTimeout(function () {
waitUntilNotActiveSheet(i+1, tag, fcn)
},200)
}else{
console.log('Below is the tag which failed')
tagFromError = tag; //Promote to global for debugging
console.log(tag)
console.log('TIMEOUT FAILURE for ' + 'waitUntilNotActiveSheet');
}
}else{
//When no longer active, call the function
fcn("function works!!!",tag);
}
}

async function getHSheetByVSheet(vSheet){
//Right now this could be either for the right portion or the parent
console.log("inside ByVShet", vSheet)
var sheetName;
if (vSheet.classList.contains('vsheet-main')){
vSheet = await vSheet.querySelector('.vsheet-right');
sheetName = vSheet.textContent;
return getHSheetByName(sheetName,2);
} else {
sheetName = vSheet.textContent;
console.log("sheetName",sheetName)
return getHSheetByName(sheetName,2);
}
}

async function getHSheetByName(sheetName,type){
//Do we want:
//1) the span with the name
//2) the root tag ...
//docs-sheet-tab
console.log("inside HSheetByName", sheetName)
var sheetElements = await document.getElementsByClassName('docs-sheet-tab-name')
console.log("sheetElement",sheetElements);
for (var i = 0; i < sheetElements.length; i++) {
//sheetName has 0 added at the front and extra white space, must be removed ***important***
if (sheetElements[i].textContent == sheetName.substr(1).trim()){

if (type == 1) {
console.log("number 1")
return sheetElements[i];
}else{
console.log("number 2")
return closestClass(sheetElements[i],'docs-sheet-tab')
}
}
}
console.log("number 3")
return null;
}

function closestClass(el, cls) {
while (el && el !== document) {
if (el.classList.contains(cls)) return el;
el = el.parentNode;
}
return null;
}

var addSheetButton = document.querySelector('.docs-sheet-add');
addSheetButton.addEventListener('mousedown',addSheetCalled);

我还在最后进行了一个新的查询调用,以查看标签变量是否引用了旧实例(尽管这不是它应该的工作方式)。
就在那时,我注意到了一些事情;这是我执行脚本之前的节点:
enter image description here
这表明标签和新搜索在执行函数后都返回相同的节点,但是当新搜索在 setTimout 中延迟时,它返回 null:
enter image description here
此外,dom 现在不同,因为节点也有一个新的 id:
enter image description here
然后在控制台中搜索旧节点不返回任何内容(为什么延迟的新搜索返回 null):
enter image description here
所以看起来一个新节点可能已经替换了它,因为变量引用了一个节点实例而不是存储快照。
编辑:
为了返回新的,我引用了旧的索引,并且不得不使用 setTimout 来导致延迟:
 }else{
const allTabs = await document.querySelectorAll('.docs-sheet-tab');
let index;
for(let i = 0; i < allTabs.length ; i ++) {
console.log("logging id",allTabs[i].getAttribute('id'))
if(allTabs[i].getAttribute('id') == id) {
index = i;
break;
}
}
console.log("the index is:", index)
console.log("old tag", tag);
//When no longer active, call the function
setTimeout(()=> {
tag = document.querySelectorAll('.docs-sheet-tab')[index];
console.log("new tag", tag);
fcn("function works!!!",tag);
},500)

}
您可以看到现在引用了新节点:
enter image description here
编辑:
之前的节点:

let div = document.querySelector('div');

console.log('variable before class added:', div);

div.classList.add('test');

console.log('variable after class added:', div)

div.remove();

//once removed it still returns
console.log('variable after node deleted:', div);

//but not in a new search
console.log('new search after node deleted:', document.querySelector('div'))
<div>test</div>

关于javascript - 为什么我的 HTML 元素 javascript 变量与我在 DOM 中看到的不匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62617290/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com