为何无法访问createDocumentFragment创建的DOM元素?
问题:使用DocumentFragment插入DOM后无法通过querySelectorAll获取元素
问题描述
通过<template>克隆元素,借助DocumentFragment批量插入DOM,视觉上元素已成功渲染,但调用querySelectorAll返回空集合,querySelector返回null。
渲染代码
var renderPicture = function(photo) { var pictureElement = pictureTemplate.cloneNode(true); pictureElement.querySelector('.picture__img').src = photo.url; pictureElement.querySelector('.picture__stat--comments').textContent = photo.comments.length; pictureElement.querySelector('.picture__stat--likes').textContent = photo.likes; return pictureElement; }; var fragment = document.createDocumentFragment(); for (var i = 0; i < photo.length; i++) { fragment.appendChild(renderPicture(photo[i])); } picturesList.appendChild(fragment);
获取元素代码
var pictureImg = document.querySelectorAll('.picture__img'); var pictureImg = document.querySelectorAll('.picture__link');
返回结果
NodeList [] length : 0 [[Prototype]] : NodeList
问题原因
你直接克隆了<template>标签本身,而非它内部的实际内容。<template>标签的特性是:它自身是DOM节点,但内部的内容默认处于未激活状态,不会加入渲染树。当你把带<template>外壳的节点插入DOM后,.picture__img等目标元素仍被包裹在<template>内部,浏览器不会将其视为可查询的DOM元素,因此querySelectorAll无法找到它们。
解决方案
修改renderPicture函数,克隆<template>的content属性(该属性是包含模板实际内容的DocumentFragment),而非<template>标签本身:
var renderPicture = function(photo) { // 克隆template内部的内容,而非template标签 var pictureElement = pictureTemplate.content.cloneNode(true); pictureElement.querySelector('.picture__img').src = photo.url; pictureElement.querySelector('.picture__stat--comments').textContent = photo.comments.length; pictureElement.querySelector('.picture__stat--likes').textContent = photo.likes; return pictureElement; };
调整后,插入DOM的是模板里的实际元素,它们会被加入渲染树,此时再调用querySelectorAll就能正常获取到目标元素了。
另外可额外确认picturesList是否正确指向了DOM中的目标容器,确保插入操作的目标位置无误。
内容的提问来源于stack exchange,提问作者Mikita
相关产品推荐
相关产品推荐

