jirengu / frontend-interview

前端笔试面试题题库
1.29k stars 139 forks source link

一个淘宝页面,你如何取得这个页面用到哪几种标签? #22

Open giscafer opened 7 years ago

giscafer commented 7 years ago

考点Dom基础,来自贺老知乎live

henryzp commented 7 years ago

遍历整个DOM树,判断它的nodeType === 11吧?然后取它的nodeName还是tagName,就可以了吧?

henryzp commented 7 years ago

nodeType到底是不是11,我不是太确定。。应该是11,11是表示element节点

giscafer commented 7 years ago

@henryzp 同一个回答建议不要分为两层楼啊。可以编辑自己原来的回答。

document.all能取得当前页面所有的element,判断nodeType===1就是element了,取nodeName就是标签名称,遍历做个类别统计就可以 听说还有其他方式,我首先想到的是这个方式而已。

leegedan commented 7 years ago

document.getElementsByTagName('*') 咋没人说这个

giscafer commented 7 years ago

@leegedan 不错。等价于document.all。在一些禁用document.all的页面下可以使用document.getElementsByTagName('*')获取了。类似jquery的选择器$("*")

guol-talend commented 7 years ago

简单写一下,可能还需要修改:

        let tags = [],
            labelType = {};
        tags.push.apply(tags, document.getElementsByTagName("*"));
        tags.forEach(function(tag) {
            if (tag.nodeType == 1) {
                if (labelType[tag.nodeName] == undefined) {
                    labelType[tag.nodeName] = 1;
                } else {
                    labelType[tag.nodeName] += 1;
                }
            }
        })
        console.log(labelType);
giscafer commented 7 years ago

@guol-talend 嗯,可以的。看到一个语句顺便说一下☟ 不过tags.push.apply(tags, document.getElementsByTagName("*"));这种方式不建议使用啊。 用concat好些。看个大数组:

var a=[]; var b=new Array(125624);
a.push.apply(a,b)

VM245:2 Uncaught RangeError: Maximum call stack size exceeded

guol-talend commented 7 years ago

@giscafer 谢谢提醒, 发现的一个stackoverflow 贴 ^_^ http://stackoverflow.com/questions/6095530/maximum-call-stack-size-exceeded-error

Jiasm commented 7 years ago
Array.from(new Set(Array.from(document.querySelectorAll('*')).map(({tagName})=> tagName.toLowerCase())))
cwsjoker commented 7 years ago

[...new Set([...document.getElementsByTagName('*')].map((value) => {return value.nodeName;}))] 思路是先获取全部标签将类数组转化为数组在遍历每个元素取出标签名返回一个新数组,在利用es6的Set结构去重

Joker-Qu commented 7 years ago

function getAllTypes() { var elems = document.querySelectorAll('*') var types = [] for(var i =0;i<elems.length;i++){ var ele = elems[i] if (ele.nodeType === 1 && types.indexOf(ele.nodeName.toLowerCase())<0){ types.push(ele.nodeName.toLowerCase()) } } return types }

OwenShi commented 6 years ago

[...new Set([...document.all].map(function(ele){if(ele.nodeType === 1){return ele.nodeName}}))]; 哎呀写了才发现楼上已经有类似的了。。

40years commented 6 years ago

Array.from(document.getElementsByTagName('*')).map((each)=>each.tagName).filter((each,index,array)=>array.indexOf(each)==index)
roadwild commented 6 years ago

function getTagsOfNode(node, result = []) { if(result.indexOf(node.tagName) < 0) { result.push(node.tagName) } for(var i = 0, len = node.children.length; i < len; i++) { getTagsOfNode(node.children[i], result) } return result } 可以通过这个函数拿到节点及其后代节点的标签名

giscafer commented 6 years ago

后边来的同学,不用继续回复了,自己写写和看看楼上各位答案就够了。最佳答案在@Jiasm