首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何通过DOM的文本内容查找DOM元素?

如何通过DOM的文本内容查找DOM元素?
EN

Stack Overflow用户
提问于 2019-09-22 11:01:03
回答 2查看 2.1K关注 0票数 6

我尝试向一些节点添加新的SVG元素。为此目的,必须通过包含在文本内容中的字符串来查找要添加元素的节点,例如查找在"id0"标记中具有<text>的任何节点。

下面是我的HTML层次结构的示例:

代码语言:javascript
运行
AI代码解释
复制
<pre>
 <svg>
  <g>
   <g>
    <text> id3 </text>
    <text> 73% </text>
    <svg> ... </svg>
   </g>
   <g>
    <svg> ... </svg>
   </g>
   <g>
    <text> id0 </text>
    <text> 11% </text>
    <svg> ... </svg>
   </g>
   <g>
    <text> id1 </text>
    <text> 66% </text>
    <svg> ... </svg>
   </g>
   <g>
    <svg> ... </svg>
   </g>
  </g>
 </svg>
</pre>

我肯定不知道正确的解决方案,但我认为是这样的:

代码语言:javascript
运行
AI代码解释
复制
d3.select('svg').select('g').selectAll('g').each(function (d, i) {})
                .select('g').select('text').filter(function () {
                  return (d3.select(this).text() === 'id0')
                })
                .select(function () {
                  return this.parentElement;
                })
                .append('svg')
                .attr('width', 400)
                .attr('height', 400)

如果标记<text>包含"id0",则返回到父节点并向其添加一个SVG元素。但是在return this.parentElement;行上会发生一个错误:

属性“parentElement”在“窗口”类型上不存在。

使用parentElementparent时也会发生类似的错误。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-24 03:43:57

D3中没有通过文本内容选择元素的内置方式,这是因为D3内部使用Element.querySelector()Element.querySelectorAll()从DOM中选择元素。这些方法将CSS选择器字符串作为由3级选择器规范定义的单个参数。不幸的是,没有任何方法可以根据元素的内容来选择元素(这曾经是通过:contains()伪类来实现的,尽管这个类已经消失了)。

因此,要构建您的选择,您必须向.select()传递一个函数,该函数选择并返回您感兴趣的<text>元素。这样做有很多种方法,但我想提出一种不那么明显但却很优雅的方法。这利用了鲜为人知的NodeIterator接口,它可以用于从DOM创建一个符合过滤器标准的节点列表上的迭代器。

NodeIterator实例是通过调用来创建的,它包含三个参数:

  1. 执行搜索的DOM子树的根。
  2. 确定您感兴趣的节点类型的位掩码;就您的目的而言,这将是NodeFilter.SHOW_TEXT
  3. 实现NodeFilter接口的NodeFilter方法的对象。此方法按文档顺序显示指定类型的每个节点,必须返回任何匹配节点的NodeFilter.FILTER_ACCEPTNodeFilter.FILTER_REJECT任何其他节点。此时,您的实现将查找id值与实际文本元素的文本内容的匹配。

然后,您可以在创建的节点迭代器上调用.nextNode()来遍历匹配节点的列表。对于您的任务,这可以遵循以下思路:

代码语言:javascript
运行
AI代码解释
复制
document.createNodeIterator(
  this,                  // The root node of the searched DOM sub-tree.
  NodeFilter.SHOW_TEXT,  // Look for text nodes only.
  {
    acceptNode(node) {   // The filter method of interface NodeFilter
      return new RegExp(value).test(node.textContent)  // Check if text contains string
        ? NodeFilter.FILTER_ACCEPT                     // Found: accept node
        : NodeFilter.FILTER_REJECT;                    // Not found: reject and continue
  }
})
.nextNode()              // Get first node from iterator.
.parentElement;          // Found node is a "pure" text node, get parent <text> element.

一旦有了这个节点,就很容易应用对该元素所需的任何修改--即追加元素,设置属性…。如果您不是在寻找唯一的值,而是要查找与同一字符串匹配的多个元素,那么这也很容易适应于处理多个节点。您只需返回迭代器找到的节点数组,然后直接传递到D3的.selectAll(),以创建多个节点的选择。

对于正在运行的演示,请查看以下代码片段:

代码语言:javascript
运行
AI代码解释
复制
function nodeIterator(value) {
  return function() {
    return document.createNodeIterator(
      this,                  // The root node of the searched DOM sub-tree.
      NodeFilter.SHOW_TEXT,  // Look for text nodes only.
      {
        acceptNode(node) {   // The filter method of interface NodeFilter
          return new RegExp(value).test(node.textContent)  // Check if text contains string
            ? NodeFilter.FILTER_ACCEPT                     // Found: accept node
            : NodeFilter.FILTER_REJECT;                    // Not found: reject and continue
      }
    })
    .nextNode()              // Get first node from iterator.
    .parentElement;          // Found node is a "pure" text node, get parent <text> element.
  }
}

const filter = nodeIterator("id0");
const sel = d3.select("svg").select(filter);

// Manipulate the selection:...
// sel.append("g")
//   .attr("transform", "...");

console.log(sel.node());
代码语言:javascript
运行
AI代码解释
复制
<script src="https://d3js.org/d3.v5.js"></script>

<svg>
  <g>
    <g>
      <text> id3 </text>
      <text> 73% </text>
      <svg></svg>
    </g>
    <g>
      <svg></svg>
    </g>
    <g>
      <text> id0 </text>
      <text> 11% </text>
      <svg></svg>
    </g>
    <g>
      <text> id1 </text>
      <text> 66% </text>
      <svg></svg>
    </g>
    <g>
      <svg></svg>
    </g>
  </g>
</svg>

票数 2
EN

Stack Overflow用户

发布于 2020-01-16 00:08:42

另一种选择是xpath,它允许通过文本进行搜索:

代码语言:javascript
运行
AI代码解释
复制
// if you know there's only one...
const singleResult = document.evaluate(`//*[name()="text" and contains(text(), "id0")]`, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
console.log(singleResult.nodeName, singleResult.textContent)

// if there might be multiple results
const multipleResults = document.evaluate(`//*[name()="text" and contains(text(), "id_multiple")]`, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)

for (let i=0; i < multipleResults.snapshotLength; i++) {
  console.log(multipleResults.snapshotItem(i).nodeName, multipleResults.snapshotItem(i).textContent)
}
代码语言:javascript
运行
AI代码解释
复制
<svg>
    <g>
        <g>
            <text> id_multiple </text>
            <text> 73% </text>
            <svg></svg>
        </g>
        <g>
            <svg></svg>
        </g>
        <g>
            <text> id0 </text>
            <text> 11% </text>
            <svg></svg>
        </g>
        <g>
            <text> id_multiple </text>
            <text> 66% </text>
            <svg></svg>
        </g>
        <g>
            <svg></svg>
        </g>
    </g>
</svg>

返回的迭代器(/snaphots)对我来说是出乎意料的--肯定读过这个极好的答案:https://stackoverflow.com/a/32468320/2586761和docs:MDN: document.evaluate

注意,由于"普通HTML节点和svg节点属于不同的命名空间",您需要选择SVG节点,比如*[name()="svg"]

关于查找文本,我建议使用contains(text(),'needle')而不是更显式的text()='needle',因为needle周围的任何空格都会导致选择器返回null

有趣的xpath vs CSS评论:cssSelector和Xpath之间有什么区别,哪个在跨浏览器测试的性能方面更好呢?

请注意,document.evaluate不支持IE

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58052522

复制
相关文章
AngularJS进阶(五)Angular实现下拉菜单多选
http://ngmodules.org/modules/angularjs-dropdown-multiselect
全栈程序员站长
2022/09/15
2.3K0
AngularJS进阶(五)Angular实现下拉菜单多选
最好用的 5 个 React select 多选下拉菜单组件测评推荐
本文完整版:《最好用的 5 个 React select 多选下拉菜单组件测评推荐》
蒋川@卡拉云
2022/06/01
7.7K0
最好用的 5 个 React select 多选下拉菜单组件测评推荐
CSS 下拉菜单_下拉菜单html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/01
7K0
MVC3教程之新手入门
你还可以通过Web Platform Installer将这些软件一起安装到本地。
拓荒者IT
2019/09/26
1.5K0
MVC3教程之新手入门
MVC 3.0 的新特性 摘要
MVC经过其1.0和2.0版本的发展,现在已经到了3.0的领军时代,随着技术的不断改进,MVC也越来越成熟。使开发也变得简洁人性化艺术化。
Isaac Zhang
2019/09/10
2.7K0
MVC 3.0 的新特性

            摘要
javascript下拉菜单代码(用jquery做下拉菜单)
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/126047.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/01
11.6K0
javascript下拉菜单代码(用jquery做下拉菜单)
vs2010 mvc3
asp.net mvc确实是好东西,VS2010在升级sp1的前提下只能最多安装mvc3.
py3study
2020/01/14
1.2K0
bootstrap 下拉菜单
<!doctype html> <html> <head> <meta charset="utf-8"> <title>联想控股</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="css/bootstrap.css" rel="stylesheet" type="text/css"> <script src="http://code.jquery.com/jquery.js"></script> <script src="js/bootstrap.min.js"></script> </head> <body>  <div class="dropdown"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> 下拉菜单<span class="caret"></span> </button> <ul class="dropdown-menu"> <li><a href="#">菜单项1</a></li> <li><a href="#">菜单项2</a></li> <li><a href="#">菜单项3</a></li> </ul> </div> </body> </html>
用户5760343
2019/07/05
4.6K0
Asp.Net MVC3 简单入门第一季(二)详解Asp.Net MVC3项目
在上一篇文章Asp.Net MVC3 简单入门第一季(一)环境准备中我简单介绍了Asp.Net MVC3项目的安装和第一个Asp.Net MVC3项目的基本情况。没有详细介绍项目中各个文件夹的作用,以及创建的第一个页面是怎样运行起来的?还有好多的疑问,那在这篇文章中我们将详细介绍项目中各个文件夹的作用,并真的第一个项目我们简要介绍一下Asp.Net MVC的URL驱动的是怎么回事。
老马
2022/11/28
9930
Asp.Net MVC3 简单入门第一季(二)详解Asp.Net MVC3项目
Asp.Net MVC3 简单入门第一季(一)环境准备
大家好,从今天开始我将写一个关于AspNet MVC3方面学习的总结,并跟初学者一起分享一些基本的基础知识,作者本身也很愿意跟大家一起交流技术,一起交流一起进步,欢迎高手不吝赐教,欢迎大家不同的意见和建议,作者的学识和见识当然有自己的局限性,希望自己能成为不闷骚型的技术人员,而不是只自己享受技术,而不让更多的人来分享你的成果的人。
老马
2022/05/10
5170
Asp.Net MVC3 简单入门第一季(一)环境准备
奥卡姆剃刀和数据简化理念
数据资源DataRes导读:《数据资源概论》数据资源类型和数据产品类型概述,从数据和信息的专业领域常识,到常见的几十种数据资源相关概念和类型,全面总结数据产学研用多个方面相关概念的内涵及差异、标准和应用。
秦陇纪
2020/04/21
7240
奥卡姆剃刀 - 如无必要,勿增实体
奥卡姆剃刀法则,又被称为“简约之法则”,它是由14世纪圣方济各会修道士奥卡姆(英格兰的一个地方)的威廉(William of Occam)提出来的,他说过这样一段话:
石云升
2022/08/25
3580
jenkins 多选框
背景 jenkins自带的参数化不支持多选框,不过有插件支持:Extended Choice Parameter Plug-In 插件地址: https://plugins.jenkins.io/ex
千往
2018/01/24
3.8K0
jenkins 多选框
bootstrap select 多选,最多选择两项 常用
image.png <!doctype html> <html> <head> <meta charset="utf-8"> <title>联想控股</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="css/bootstrap.css" rel="stylesheet" type="text/css"> <link href="css/bootstrap-
用户5760343
2019/07/08
3.5K0
bootstrap select 多选,最多选择两项 常用
vue + iview/elementUi --城市多选
最近收到了一个需求,管理系统需要上线一个活动,但是活动是根据地区上线的,最小范围到市,于是有了下面这个组件 页面展示如图:
super.x
2019/04/12
1.8K0
vue + iview/elementUi --城市多选
bootstrap select 多选 常用
<!doctype html> <html> <head> <meta charset="utf-8"> <title>联想控股</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="css/bootstrap.css" rel="stylesheet" type="text/css"> <link href="css/bootstrap-select.css" rel="stylesheet" type="text/css"> <script src="http://code.jquery.com/jquery.js"></script> <script src="js/bootstrap.min.js"></script> <script src="js/bootstrap-select.js"></script> </head> <body> <div class="container"> <div class="row"> <label class="col-sm-3 control-label" style="line-height: 34px;margin-bottom: 20px;">选择用户:</label> <div class="col-sm-6"> <select class="selectpicker" multiple> <option value="苹果">苹果</option>   <option value="菠萝">菠萝</option>   <option value="香蕉">香蕉</option>   <option value="火龙果">火龙果</option>   <option value="梨子">梨子</option>   <option value="草莓">草莓</option>   <option value="哈密瓜">哈密瓜</option>   <option value="椰子">椰子</option>   <option value="猕猴桃">猕猴桃</option>   <option value="桃子">桃子</option> </select> </div> </div> </div>
用户5760343
2019/07/07
1.6K0
精通MVC3摘译(4)-使用Area
MVC Framework支持将一个web application放入一个area,每个area表示一个特殊功能的应用程序片段,比如管理,账单,客户支持等等。这对大型项目很有用,如果大型项目中所有的controller,View和model都只有相应的一个文件夹,那么很难管理,那么此时使用area会很有帮助。
py3study
2020/01/10
6690
html中下拉菜单(html做下拉菜单栏)
使用html5或者jQuery如何实现文本框下拉效果,如下图 CSS布局HTML小编今天和大家分享大神详解最好有可以使用HTML5 list 属性。list 属性需要应用到 input 框上,然后内容写一个自定义的 id 然后在任意位置放一对 datalist 标签,并给 datalist 框一个 id,和 list 属性指向的 id 一致即可。 在 datalist 标签下放列表项。
全栈程序员站长
2022/08/02
11.6K0
html中下拉菜单(html做下拉菜单栏)
ElementUI Checkbox 多选框
https://element.eleme.io/#/zh-CN/component/checkbox
py3study
2021/03/12
3K0
ElementUI Checkbox 多选框
input file多选 multiple[通俗易懂]
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/160959.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/09
2.5K0

相似问题

Ajax在Chrome中工作,但在Firefox和IE中不起作用

16

Javascript / Ajax在Mozilla firefox中工作,但在Google Chrome和IE中不起作用

20

JQuery代码在Firefox中工作,但在Chrome和IE中不工作

11

代码在Chrome和Firefox中工作,但在IE中不起作用

13

$.ajax在chrome和firefox中不起作用,但在IE中起作用

33
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档