Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何选择最里面的元素?_Javascript_Jquery_Html - Fatal编程技术网

Javascript 如何选择最里面的元素?

Javascript 如何选择最里面的元素?,javascript,jquery,html,Javascript,Jquery,Html,在jQuery中,如何尽可能深入HTML树 为了简单起见,我只有一条向下的路径 相关但有好处:如何找到具有多条下行路径的最深层元素 <html> <table id="table0"> <tr> <td id="cell0"> <div class"simple"> I want to change this information </div> &l

在jQuery中,如何尽可能深入HTML树

为了简单起见,我只有一条向下的路径

相关但有好处:如何找到具有多条下行路径的最深层元素

<html>  
  <table id="table0">  
    <tr>  
      <td id="cell0">  
        <div class"simple">  I want to change this information </div>  
      </td>
    </tr>  
  </table>  
</html>
我想更改名为cell0的单元格的最内层HTML,但我不一定知道其中所有类的名称。是否可以在不知道这些名称的情况下选择到目前为止的位置


多谢

好吧,从你不知道这个最深的节点在哪里开始,你可以这样做:

$.fn.deepest = function() {
  var depth = 0;
  this.find('*').each(function() {
    var d = $(this).parents().length;
    depth = Math.max(d, depth);
  });
  return this.find('*').filter(function() {
    return this.parents().length === depth;
  });
});
然后

除了我代码中的12个bug之外,最深元素集的jQuery对象可能是一个

编辑-我的十二个错误之一是,这没有考虑到起始节点的深度-这是一个需要解决的技巧。最好对其进行重构,以便找到最初选定列表中最深的部分:

$.fn.betterDeepest = function() {
  var depth = 0;
  this.each(function() {
    depth = Math.max(depth, $(this).parents().length);
  });
  return this.filter(function() { return $(this).parents().length === depth; });
});
要在页面上获得最深入的信息,您需要:

var deepest = $('*').betterDeepest();
使用单一路径:

var elem = $('#table0'),
    next;
while ((next = elem.children(':first')).length > 0)
  elem = next;
// elem now points to the deepest child of table0

如果我有时间,我会用多条路径的代码更新我的答案。

也许不是最有效的,但你可以这样做:

例如:

或者这个:

例如:

示例中的结果似乎处于不同的级别,但这是因为浏览器正在插入缺少的


它不是特定于jquery的,但是可以调整这个递归解决方案来做任何您想做的事情

function findDeepest (elem) {
 var result = {maxDepth: 0, deepestElem: null}
 descend(elem, 0, result);
 if (result.maxDepth > 0)
  alert (result.deepestElem.tagName + " " + result.maxDepth);
 }


function descend(elem, depth, result) {    
 switch (elem.nodeType) {
    case 1: // ELEMENT_NODE
        if (depth > result.maxDepth) {
         result.maxDepth = depth;
         result.deepestElem = elem;
         }
        for (var i=0; i<elem.childNodes.length; i++)
           descend(elem.childNodes[i], depth + 1, result);
        break;
    case 3: // TEXT_NODE
    case 4: // CDATA_SECTION_NODE
    case 5: // ENTITY_REFERENCE_NODE
    case 8: // COMMENT_NODE
        // handle these cases as needed
    break;
    }
}

我将通过一个递归函数来实现这一点:

// Returns object containing depth and element
// like this: {depth: 2, element: [object]}
function findDeepestChild(parent) {

    var result = {depth: 0, element: parent};

    parent.children().each(
        function(idx) {
            var child = $(this);
            var childResult = findDeepestChild(child);
            if (childResult.depth + 1 > result.depth) {
                result = {
                    depth: 1 + childResult.depth, 
                    element: childResult.element};
            }
        }
    );

    return result;
}

我要做的第一件事是运行一个,并跟踪DOM中每个节点的级别

为了避免每次更改某个内容时都必须执行完整的DFS(假设要多次执行),可以在执行搜索时在树中为每个DOM节点标记其级别。同样,您可以在生成表的过程中执行此级别标记?搜索完成并确定最深的节点后,保留对该节点的引用


从那时起,您应该能够在任何给定时间快速更新最深级别的节点。

对于单路径,只需找到没有子节点的元素:

$('body *:not(:has("*"))');
或者,在更具体的情况下$'cell0*:not:has*'

对于多个路径-如果有多个相同嵌套的节点,该怎么办?此解决方案将为您提供一个包含祖先数量最多的所有节点的数组

var all = $('body *:not(:has("*"))'), maxDepth=0, deepest = []; 
all.each( function(){ 
    var depth = $(this).parents().length||0; 
    if(depth>maxDepth){ 
        deepest = [this]; 
        maxDepth = depth; 
    }
    else if(depth==maxDepth){
        deepest.push(this); 
    }
});
同样,在您的情况下,您可能希望获得表格单元格最深的元素,因此您回到了一行:

$('#table0 td *:not(:has("*"))');

-这将返回一个jQuery对象,其中包含表中每个单元格的所有最内层子节点。

我认为,这是最短的示例:

$('#cell0 :last').text('new information')

很晚才开始更改最里面的元素,并保存标签结构,但这是我的通用解决方案

var elements$ = $(':contains("your text")');
var result = elements$.filter((index, element) => 
        index === elements$.length || 
        ! $.contains(element, elements$.get(index+1))
    );
它非常快速和简单,因为jQuery已经为我们完成了所有的工作


注意,elements$是容器的有序列表,其中许多包含下一个容器。因此,最里面的元素是最后一个元素加上不包含下一个元素的所有元素。

对于jQuery,这个问题有一个简单而好的答案。然而,我正在寻找一个没有它的优雅解决方案。因为:have在任何浏览器中都不受支持,所以我在这里提出了这个

Array.from( document.querySelectorAll( 'body *' ) )
  .filter( e => !e.children.length );

如果中有两个兄弟姐妹,您希望发生什么?我知道您的示例代码只是一个示例,但我觉得我应该指出,它是无效的HTML,因为它们之间有一个,而没有一个。@Spudley:谢谢Spudley,我修复了它。@cdhowie:非确定性行为!前一个标记范围内的第一个或最后一个都可以,我想返回您检查的最后一个可能更容易。请问您为什么需要最里面的元素?我想不出有什么问题需要这样的选择。我不知道下一个关键字。@sova-没有下一个关键字。这里它只是一个变量名。@sova:next在JavaScript中不是关键字。由于此网站上的语法高亮显示支持多种语言,因此它有时会突出显示其他语言的单词。请解释为什么您的switch语句只有一个case注意我关于被调整的评论,在这种情况下,您可能需要执行其他操作,例如处理文本节点,等等。诚然,它看起来确实有点奇怪……但我通常使用这种形式来遍历dom树。我会在里面放一条评论,让你明白。。。
$('#cell0 :last').text('new information')
var elements$ = $(':contains("your text")');
var result = elements$.filter((index, element) => 
        index === elements$.length || 
        ! $.contains(element, elements$.get(index+1))
    );
Array.from( document.querySelectorAll( 'body *' ) )
  .filter( e => !e.children.length );