【问题标题】:Change button's text in JS without div.class在没有 div.class 的情况下在 JS 中更改按钮的文本
【发布时间】:2020-09-08 13:35:22
【问题描述】:

问题

我很难在我的网站上更改按钮的文本。

<div> 上没有我想要定位的课程,这就是为什么我在为这个编辑而苦苦挣扎的原因。 说实话,我对 JS 有一些基本的了解,所以我可以理解,但是我自己还没有找到这个解决方案。

有页面的简化代码:

<div class="notion-topbar">
  <div>
    <div class="notranslate">...</div>
    <div>...</div>
    <div role="button"> // I want to change the text in this <div>!
      <svg>...</svg> my_text
    </div>

如果您愿意,可以在此处观看完整页面并搜索“topbar”:https://overwatch-guide.com 我想把右上角的“搜索”按钮翻译成法语。

可能的解决方案

我可能会找到解决方案的一部分,例如使用 document.querySelector('input[type=button]').innerHTML = "Rechercher";,但我知道缺少某些内容,因为我不想选择页面上的所有按钮。

我还在 CSS(我更熟悉的一种语言)中发现了一种“hack”,但我不是这种解决方案的忠实拥护者,因为 CSS 不是用来编辑文本的。就我而言,我想象过这样的:

.notion-topbar > div:nth-child(1n+3) > .button {
  visibility: hidden
}

.notion-topbar > div:nth-child(1n+3) > .button:after {
  visibility: visible;
  display: block;
  content: 'Rechercher';
  position: absolute;
}

帮助

我真的可以使用你的帮助,因为我在这方面很难挣扎。 感谢您的宝贵时间!

【问题讨论】:

  • 任何 CSS 选择器都可以在 JS 中使用。因此,您的“CSS hack”中的选择器可以在 document.querySelector 中使用,或者只需右键单击 devtools 中的元素,然后单击 -> 复制 -> 复制选择器
  • 我不太确定在我的脚本中使用 CSS 选择器。那么,你的意思是我可以尝试这样的脚本吗? document.querySelector('div.notion-topbar > div > div:nth-child(3)').innerHTML = "Rechercher";
  • 如果这是正确的 CSS 选择器,那么可以。小提示,使用textContent 而不是innerHTML,因为它有一些重大的安全问题
  • 感谢textContent 的建议!我试过这个脚本,但我不知道为什么它不起作用... document.querySelector(".notion-topbar > div:nth-child(1) > div:nth-child(3)").textContent = "Rechercher";
  • 它适用于我,只需将其复制粘贴到控制台中。

标签: javascript html class dom button


【解决方案1】:

如果你不想使用一个类,你可以不给 div 分配一个 id 那么你可以称之为如下 document.getElementById("YourIdName").innerHTML = "whatever";

【讨论】:

  • 肯定会更简单,但我无法深入编辑网页上的代码。我在 Cloudflare 上使用了一个完全脚本化且“即用型”的工作人员。我已经对脚本进行了一些小修改,但这对我来说有点难以解决。无论如何感谢您的回答! :)
【解决方案2】:

大概是这样的吧?

document.querySelector('div[role=button]')

【讨论】:

  • 这个脚本是否会尝试编辑每个具有按钮角色的 div?因为这就是我认为它会做的事情。
  • @Yani ,不,它只会用role=button 更改第一个div,因为document.querySelector 返回与传递给它的选择器匹配的第一个元素。
  • 哦,是的,我完全忘记了document.querySelector做了什么,我的错! ^^ 无论如何,即使@Reyno 找到了我的问题的解决方案,谢谢你的回答! :)
【解决方案3】:

因为您的按钮中有多个节点。您应该检查每个项目,如果它是文本节点,请替换内容。

PS:这个函数可以用于所有类型的元素,而不仅仅是按钮。

const replaceTextInElement = (element, find, replace, searchInChildren = false) => {
  // Stop doing anything if the element is empty
  if (!element.hasChildNodes()) return;
  
  // Create regex to replace our provided word
  const regex = new RegExp(find, "g");
  
  // Loop over each child nodes of the element
  for(const childNode of element.childNodes) {
    // Replace the text if it is a text node
    if(childNode.nodeType === Node.TEXT_NODE) {
      // Replace the text with new text
      childNode.textContent = childNode.textContent.replace(regex, replace);
    } else if(searchInChildren) {
      // Also replace text in children if we specified it to do so
      replaceTextInElement(childNode, find, replace, searchInChildren);
    }
  }
}

// Don't do anything until the DOM is loaded
window.addEventListener("DOMContentLoaded", () => {
  const searchBtn = document.querySelector(".search-button");
  // Use the line below. I used the one above because i was to lazy to recreate all the html.
  // const searchBtn = document.querySelector(".notion-topbar > div:nth-child(1) > div:nth-child(3)");
  replaceTextInElement(searchBtn, "Search", "Rechercher");

  // You can also go through each child if you need to by adding true as parameter
  const anotherBtn = document.querySelector(".another-button");
  replaceTextInElement(anotherBtn, "Search", "Zoeken", true);
});
<div class="search-button">
  <div>Search level 2 (your SVG)</div>
  Search level 1
</div>

<br/><br/>

<div class="another-button">
  <div>Search level 2 (your SVG)</div>
  Search level 1
</div>

没有 cmets:

const replaceTextInElement = (element, find, replace, searchInChildren = false) => {
  if (!element.hasChildNodes()) return;
  
  const regex = new RegExp(find, "g");
  
  for(const childNode of element.childNodes) {
    if(childNode.nodeType === Node.TEXT_NODE) {
      childNode.textContent = childNode.textContent.replace(regex, replace);
    } else if(searchInChildren) {
      replaceTextInElement(childNode, find, replace, searchInChildren);
    }
  }
}

window.addEventListener("DOMContentLoaded", () => {
  const searchBtn = document.querySelector(".search-button");
  replaceTextInElement(searchBtn, "Search", "Rechercher");

  const anotherBtn = document.querySelector(".another-button");
  replaceTextInElement(anotherBtn, "Search", "Zoeken", true);
});
<div class="search-button">
  <div>Search level 2 (your SVG)</div>
  Search level 1
</div>

<br/><br/>

<div class="another-button">
  <div>Search level 2 (your SVG)</div>
  Search level 1
</div>

因为即使在 DOMContentLoaded 事件之后 DOM 也不可用。您唯一的选择是计时器,尽管这更像是解决问题而不是修复的黑客方法。最后一个示例尝试每秒更新一次文本。它只会在成功或达到最大尝试次数(限制)时停止更新。您当然可以增加等待时间(1000 毫秒)或尝试次数(10)

const replaceTextInElement = (element, find, replace, searchInChildren = false) => {
  if (!element.hasChildNodes()) return;
  
  const regex = new RegExp(find, "g");
  
  for(const childNode of element.childNodes) {
    if(childNode.nodeType === Node.TEXT_NODE) {
      childNode.textContent = childNode.textContent.replace(regex, replace);
    } else if(searchInChildren) {
      replaceTextInElement(childNode, find, replace, searchInChildren);
    }
  }
}

const replaceSearchText = (attempts, limit) => {
  if(attempts > limit) return;
  
  const searchBtn = document.querySelector(".search-button");
  // Use the line below. I used the one above because i was to lazy to recreate all the html.
  // const searchBtn = document.querySelector(".notion-topbar > div:nth-child(1) > div:nth-child(3)");
  
  searchBtn
    ? replaceTextInElement(searchBtn, "Search", "Rechercher")
    : setTimeout(() => replaceSearchText(attempts + 1, limit), 1000);
};

replaceSearchText(0, 10);
<div class="search-button">
  <div>Search level 2 (your SVG)</div>
  Search level 1
</div>

【讨论】:

  • 说实话,这段代码太复杂了,我无法完全理解 atm。我想我还有很多关于 JS 的知识要学! ^^ 无论如何,我在我的网站上尝试过......但不幸的是,结果和以前一样。我正在慢慢尝试检查您的代码示例中的问题,我不会放弃!如果您想自己检查它,它仍然存在。目前,有一个错误Uncaught TypeError: Cannot read property 'hasChildNodes' of null
  • @Yani 我做了更多的研究,发现在页面加载后添加了 DOM,这意味着事件 'DOMContentLoaded' 已经触发。唯一的其他选择是类似计时器的解决方案。以最后一个 sn-p 为例
  • 是的,它有效!感谢您的帮助,您做得很棒!我真的很感谢你的努力。再见! :)
猜你喜欢
  • 1970-01-01
  • 2021-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-21
  • 1970-01-01
相关资源
最近更新 更多