2

In my tutorial project, I fill the page with elements created using DocumentFragment. Everything happens as it should: the elements are created, drawn on the page, and displayed in the DOM. The problem is that when I try to access these elements for further work through querySelectorAll, I get an empty array. Why is this happening?

Using the tag <template>, I create and place elements in the right place for me:

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);

I refer to the created elements for further interaction:

var pictureImg = document.querySelectorAll('.picture__img');
var pictureImg = document.querySelectorAll('.picture__link');

The browser ignores the elements (even though they are present in the DOM), and returns either an empty collection (with querySelectorAll) or null (if I use querySelector):

NodeList []
length
: 
0
[[Prototype]]
: 
NodeList

What is the problem?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Mikita
  • 29
  • 2
  • Where do you place the elements into the document? Have you inspected the elements which are supposedly in the DOM? Do they have the correct class names? – Sebastian Simon Oct 23 '22 at 22:40
  • 1
    Can you provide your full code? – Michael M. Oct 23 '22 at 22:46
  • I place the elements in a block intended for them. The class names are correct. if I fire a click event then I can catch the target on them. But I need to work with an array of all created elements. – Mikita Oct 23 '22 at 22:50

1 Answers1

1

You need to access the DocumentFragment of the <template> before using querySelector. The fragment of a template is in the content property.

If you change this line to use the content property it should fix your issue.

pictureTemplate.content.cloneNode(true);
morganney
  • 6,566
  • 1
  • 24
  • 35
  • I changed the line as you showed and now the browser is showing an error on that line. Uncaught TypeError: Cannot read properties of undefined (reading 'cloneNode'). I use .content when I access template via querySelector var pictureTemplate = document.querySelector('#picture').content.querySelector('.picture__link'); – Mikita Oct 28 '22 at 01:19