Search code examples
javascriptecmascript-6javascript-objects

attributes.getNamedItem('style') is null


The logic bellow create a div element that display image as base64 format. when I try to get the value of attribute style which contains the URL base64 of the image I get this error attributes.getNamedItem('style') is null. But I noticed when I update the image I can get the value of the attribute style. Could you please tell me what is the issue ?

function clickEvent(event) {
  const target = event.target;
  if (target === null) return;
  this.childNodes.forEach(function(node) {
    if (node && node.nodeType === 1) {
      if (node !== target) return;
      node.children[1].click();
    }
  });
}

function changeEvent(event) {
  const target = event.target;
  if (target === null) return;
  this.childNodes.forEach(function(node) {
    if (node && node.nodeType === 1) {
      if (node.children[1] === target && event.target.files.length > 0) {
        thumbnail(node, event.target.files[0]);
      }
    }
  });
  console.log(target.parentNode.firstChild.attributes.getNamedItem("style").value);
}

function thumbnail(element, file) {
  if (element.children[0]) {
    element.children[0].nodeName === 'SPAN' ? createThumbnail(element, file) : updateThumbnail(element.children[0], file);

  }
}

function createThumbnail(element, file) {
  element.children[0].remove();
  const thumbnail = document.createElement("div");
  thumbnail.classList.add("drop-area__thumb");
  element.prepend(thumbnail);
  updateThumbnail(thumbnail, file);
  thumbnail.dataset.label = file.name;
  return element;
}

function updateThumbnail(element, file) {
  if (file.type.startsWith("image/")) {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function() {
      element.style.backgroundImage = `url('${reader.result}')`;
    };
  } else {
    element.style.backgroundImage = null;
  }
}

function eventHandler(element, eventType, callback) {
  return document.getElementById(element).addEventListener(eventType, callback, false);
}

eventHandler('app', 'click', clickEvent);
eventHandler('app', 'change', changeEvent);
#app {
  display: inline-flex;
  padding: 24px;
  gap: 24px;
}

.drop-area {
  }

.drop-area__prompt {
  pointer-events: none;
  -webkit-text-size-adjust: none;
  text-size-adjust: none;
  font-;
  size: 18px;
}

.drop-area__input {
  display: none;
}

.drop-area__thumb {
  position: absolute;
  width: 90%;
  height: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  border-radius: 10px;
  overflow: hidden;
  background-color: #cccccc;
  background-size: cover;
  pointer-events: none;
}
<div id="app">
  <div id="1" class="drop-area">
    <span class="drop-area__prompt" style="pointer-events: none;">Upload file</span>
    <input type="file" accept="image/*" class="drop-area__input" name="upload">
  </div>
  <div id="2" class="drop-area">
    <span class="drop-area__prompt" style="pointer-events: none;">Upload file</span>
    <input type="file" accept="image/*" class="drop-area__input" name="upload">
  </div>
</div>


Solution

  • In general, the browser needs some time to read files, and this duration depends on the size of the files and your computer's performance. To address this, it's recommended to perform your operations asynchronously.

    Here's an example function that demonstrates this approach:

    function changeEvent(event) {
        let target = event.target;
        if (target === null) return;
        
        this.childNodes.forEach(function(node) {
            if (node && node.nodeType === 1) {
                if (node.children[1] === target && event.target.files.length > 0) {
                    thumbnail(node, event.target.files[0]);  
                }
            }
        });
        
        setTimeout(function() {
            // console.log(target.parentNode.firstChild.attributes.getNamedItem("style").value);
            console.log(target.parentNode.firstChild.getAttribute('style'))
        }, 500);
    }
    

    Hope that it resolve your problem.