Js:从指定节点开始向上(下)查找特定节点属性值

网盟程序员日常的工作之一就是给站长投放代码,经常要使用Js从页面中获取一些信息(资源名称、下载地址、预览图片地址等)并将其发送到指定的接口中,在内容页中实现大都比较容易,通常比较难的是在列表页中实现,再加上一些CMS没有提供相关标签来调用或是有相关的标签但无法使用时更是难上难,如下边的一个列表:



在模板中预览图标签不是单指图片地址,而是一整个img内容,但如果下载到手机的链接和预览图地址相隔很近的话,用几个previousSibling或nextSibling还是可以很容易获取图片地址的,但这个例子中两者相隔实在有点远,试了几次都没取到图片地址:(最终就想:能不能写个函数,它能从指定的节点开始向上或向下查找特定节点的属性值?想了一晚,总算是实现了:

//功能:从指定节点开始向上或向下查找特定节点属性值(就近原则)
//
//参数:
//    currentNode:    从该节点开始查找
//返回值:
//    指定属性值或null
function Find(currentNode)
{
    var parent = null;
    var node = null;
    var result = null;
    
    //公有方法:向上查找特定节点属性值
    //参数:
    //    nodeName:    要查找的节点名称
    //    attribute:    属性名称,最终返回该属性值
    //    subString:    属性值中必须包含此字符串
    this.Up = function(nodeName,attribute,subString)
    {
        parent = currentNode.parentNode;
        node = currentNode.previousSibling;
        
        while(!(node == null && parent == null))
        {
            if(node == null && parent != null)
            {
                node = parent.previousSibling;
                parent = parent.parentNode;
            }
            else
            {
                result = FindInChild(node,nodeName,attribute,subString)
                
                if(result != null)
                    return result;
                else
                    node = node.previousSibling;
            }
        }
        
        return null;
    }
    
    //公有方法:向下查找特定节点属性值
    //参数:
    //    nodeName:    要查找的节点名称
    //    attribute:    属性名称,最终返回该属性值
    //    subString:    属性值中必须包含此字符串
    this.Down = function(nodeName,attribute,subString)
    {
        parent = currentNode.parentNode;
        node = currentNode.nextSibling;
        
        result = FindInChild(currentNode,nodeName,attribute,subString)
        if(result != null)
        {
            return result;
        }
        else
        {
            while(!(node == null && parent == null))
            {
                if(node == null && parent != null)
                {
                    node = parent.nextSibling;
                    parent = parent.parentNode;
                }
                else
                {
                    result = FindInChild(node,nodeName,attribute,subString)
                    
                    if(result != null)
                        return result;
                    else
                        node = node.nextSibling;
                }
            }
            
            return null;
        }
    }
    
    //私有方法:在某个节点的子节点中查找特定节点属性值
    //参数:
    //    firstNode:    被查找的节点名称
    //    nodeName:    要查找的节点名称
    //    attribute:    属性名称,最终返回该属性值
    //    subString:    属性值中必须包含此字符串
    function FindInChild(firstNode,nodeName,attribute,subString)
    {
        //查找本节点
        if(firstNode.nodeName.toLowerCase() == nodeName.toLowerCase())
        {
            //Bug: 使用elementNode.getAttribute获取属性值
            //            如果<A>和<IMG>使用相对地址,FF和Opera获取的也为相对地址,只有IE获取的是绝对地址
            //                改为用elementNode[attribute]来获取
            if(typeof(subString) == "undefined" || subString == "")
            {
                return firstNode[attribute];
            }
            else
            {
                if(firstNode[attribute].toLowerCase().indexOf(subString.toLowerCase()) != -1)
                {
                    return firstNode[attribute];
                }
            }
        }
        
        //子节点中查找
        if(firstNode.childNodes.length > 0)
        {
            for(var i=0;i<firstNode.childNodes.length;i++)
            {
                result = FindInChild(firstNode.childNodes[i],nodeName,attribute,subString)
                if(result != null)return result;
            }
        }
        
        //未找到
        return null;
    }
}

使用示例

·(new Find(obj)).Up("img","src")表示从obj节点开始向上查找第一个img节点的src属性值
·(new Find(obj)).Up("img","src","images")表示从obj节点开始向上查找第一个src中包含images的img节点的src属性值
·(new Find(obj)).Down("img","src")表示从obj节点开始向下查找第一个img节点的src属性值
·(new Find(obj)).Down("img","src","images")表示从obj节点开始向下查找第一个src中包含images的img节点的src属性值

IE(6.0)、FF(3.0)、Opera(9.5)下测试通过。

评论: 0 | 引用: 0 | 查看次数: 6501
发表评论
登录后再发表评论!