选择html-element的前缀和后缀标签

时间:2014-08-31 19:25:30

标签: javascript jquery html dom tree-traversal

我想解决的问题是选择一个选定的html元素的某个前缀和后缀。一个小例子应该描述我想要做的事情。假设我们有以下html源:

<div class="box1">
  <div class="tutlogo">
    <a class="box" href="sql/default.asp" target="_top">
      <div class="image" style="background-color:#FF9900;"></div>
      <h1>SQL</h1>
    </a>
  </div>
</div>
<div class="tutbuttons">    
  <a class="btn" href="sql/default.asp" target="_top">SQL Tutorial</a>
  <a class="btn" href="sql/sql_quickref.asp" target="_top">SQL Reference</a>
</div>
<div class="box1">
  <div class="tutlogo">
    <a class="box" href="php/default.asp" target="_top">
      <div class="image" style="background-color:#41BC81;"></div>
      <h1>PHP</h1>
    </a>
  </div>
  <div class="tutbuttons">
    <a class="btn" href="php/default.asp" target="_top">PHP Tutorial</a>
    <a class="btn" href="php/php_ref_array.asp" target="_top">PHP Reference</a>
  </div>
</div>          

说我选择了<h1>PHP</h1>元素。我想要提取的内容是此元素的“前缀”是n标记之前的<h1> html标记。鉴于n为5,那么我想要提取的前缀是序列:</div><div><a><div><div>。我想分别以<h1>PHP</h1>元素作为后缀提取5个html标签。在此示例中,可能是:</a></div><div><a></a>

我尝试使用jquery的tree traversal方法来完成工作,但是这样我就无法获得关闭的html标记。我也搜索了一个解决方案,但找不到符合我需求的任何东西。也许有人已经这样做了,可以告诉我如何提取前缀,后缀标签或者可以指向正确的方向。也许它真的微不足道,我只是觉得太复杂了。

无论如何,谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

我不认为这是微不足道的,这会让你对以前的努力感到满意。

你可能需要进行一些树遍历,无论你最终如何做到这一点。我前几天正在构建一个自动工具提示创建插件,所以我想到了这种东西。

这是我一起攻击的内容 - http://jsfiddle.net/naazkc1v/

它不是一个最终的解决方案,但它可以按原样运行,并可能帮助您达到所需的目标。

  1. 定义要抓取var initialEl = $("h1")[0]
  2. 周围标记的元素
  3. 它导航文档树,如果遇到$(&#39; body&#39;),$(&#39; html&#39;)或$(文档)
  4. ,它会停止
  5. 它采用root元素并递归删除html标记上的所有属性并清空文本节点
  6. 它在新的精简HTML中找到原始元素的HTML,并在它之前和之后返回字符串。
  7. 实施例

    使用此HTML

    <div class="box1">
      <div class="tutlogo">
        <a class="box" href="php/default.asp" target="_top">
          <div class="image" style="background-color:#41BC81;"></div>
          <h1>PHP</h1>
        </a>
      </div>
      <div class="tutbuttons">
        <a class="btn" href="php/default.asp" target="_top">PHP Tutorial</a>
        <a class="btn" href="php/php_ref_array.asp" target="_top">PHP Reference</a>
      </div>
    </div>    
    

    最后的3个控制台日志将是

    <div><a><div></div>
    <h1>PHP</h1>
    </a></div><div><a></a><a></a></div>
    

    与您期望的解决方案相比的问题:

    目前还没有保证目标前后都有n个标签。编写解析器来剥离额外的标签应该很容易。但是,如果根父级不足以获取EXTRA标记,则需要抓住我们发现的根节点的兄弟节点,在该兄弟节点上运行此整个函数,然后从其返回的值中解析必要的标记。

    资源

    完整的Javascript

    $(function(){
    
        jQuery.fn.removeAttributes = function() {
          return this.each(function() {
            if (this.attributes){
                var attributes = $.map(this.attributes, function(item) {
                  return item.name;
                });
                var img = $(this);
                $.each(attributes, function(i, item) {
                  img.removeAttr(item);
                });
            }
          });
        }
    
        var initialEl = $("h1")[0],
            html = $("html")[0],
            body = $("body")[0],
            el = initialEl;
    
        function nodeInBody(node){
            return node.parentNode &&
                   node.parentNode != document &&
                   node.parentNode != html &&
                   node.parentNode != body;
        }
    
        while ( nodeInBody(el) ){
            el = el.parentNode;
        }
    
        var $el = $(el),
            //This assumes there's only ONE text node within the original element
            //If you have any other elements inside the element you're targetting,
            //this will fail
            $initialTextNode = $(initialEl).contents()[0];
    
        function removeAttributesFromChildren(el){
            $(el).contents().each(function(i,el){
                // Emptying Text Nodes if they're not our saved one
                if ( el.nodeType == 3 && el !== $initialTextNode) el.nodeValue = "";
                //Call the jQuery plugin we defined earlier
                $(el).removeAttributes();
                // Call this function on the element
                removeAttributesFromChildren(el);
            });
        }
    
        removeAttributesFromChildren(el);
    
        var html = $(el).html(),
            initialElHTML = initialEl.outerHTML;
    
        var start = html.indexOf(initialElHTML);
    
        // If our original item's HTML is contained in the html string
        if ( start > -1 ){
            // Grab the strings before and after it
            var end = start+initialElHTML.length,
                before = html.substring(0,start),
                word = html.substring(start,end),
                after = html.substring(end);
    
                console.log(before);
                console.log(word);
                console.log(after);
    
        }
    
    });