method $.find() in pure javascript

Asked

Viewed 562 times

1

How to define the attribute of a child element within another element using javascript pure?
in jquery would be: $('.preview').find('img').attr('src','#url'); but how does it get in javascript pure?

<div class="preview"><img src="" title=""/></div>

var el = document.getElementsByClassName("preview");
var img = el.getElementsByTagName('img');
img.setAttribute("src" , 'url');

I tried with your answer but it did not work: on the console appears: 'undefined'

var reader = new FileReader();

reader.onload = function (e){                   
    document.getElementsByClassName("preview")[0].querySelectorAll("img")[0].setAttribute("src", e.target.result);                      
};

reader.readAsDataURL(files[0]);

this function is called in the event change of input file

what I am trying to do is take the image url that is loaded into the input and shows a thumbnail, the code works in jquery but I need to do in javascript

that way it works:

<img src="" alt="" id="preview">

document.getElementById("preview").setAttribute('src', 'url');
  • document.getElementById("preview") this wrong, document.getElementById is for Ids and not CLASS, and something else document.getElementById returns only one element or null, other than getElementsByClassName and getElementsByTagName returning multiple, eternal elements.

  • I know I was testing and I ended up bringing it wrong here, anyway it doesn’t work when I change to class

  • Be careful when using the id property, you should not reference two elements with the same id

  • I know, so I need to use with getElementsByClassName ;)

2 answers

2

I replied something similar in /a/141203/3635, to be clearer the getElementsByTagName, getElementsByClassName and querySelectorAll are different in behavior of getElementById and querySelector (without the "All"):

  • getElementsByTagName, getElementsByClassName and querySelectorAll return a list of elements, similar to an array, and can return this list with zero items

  • querySelector returns only an element based on a query that can be more complex, or returns null if nothing finds

  • getElementById returns only one element by its id, or returns null if nothing is found. It can only be used with type property elements Document or a responseXML for example, but won’t work if used in other elements as something like this:

    <div id="a">
       <div id="b">x</div>
    </div>
    <script>
       console.log(document.getElementById("a").getElementById("b"));
    </script>
    

Overall something that solves your problem is to use only querySelector:

<div class="preview"><img src="" title=""/></div>

<script>
var img = document.querySelector(".preview > img");

//Verifica se encontrou o img
if (img) {
    img.setAttribute("src" , 'url');
}
</script>

If there are multiple .preview:

<div class="preview"><img src="" title=""/></div>
<div class="preview"><img src="" title=""/></div>
<div class="preview"><img src="" title=""/></div>
<div class="preview"><img src="" title=""/></div>

Then use querySelectorAll with for:

var imgs = document.querySelectorAll(".preview > img");

for (var i = 0, j = imgs.length; i < j; i++) {
    imgs[i].setAttribute("src" , 'url');
}

Read the documentation about DOM and learn how each function works before using them:

  • 1

    all the forms exposed here to be able to access the child of the element worked, however at the time of assignment for some reason it does not assign the value of the image to the value of the attribute src. on the console it prints the image in format base64 but does not attribute to src of the image...

  • See help: http://stackoverflow.com/a/16449483/3956218

  • @Hebertdelima but you didn’t mention it in the question, this speaking of FileReader?

  • because the problem is not the FileReader, is just like reaching the child of the element and assigning value to it with setAtribute which has not yet worked. =)

  • only works if I use getElementById but with getElementsByClassName doesn’t work that I don’t understand =, and since I need this same function in two places I don’t want to have to write twice to do the same thing

  • @Hebertdelima the problem is that you’re making trouble, in your question there’s nothing about base64 I just asked from Filereader to find out where this Base64 came from. Your question this vacancy, ie do not have such information on this, there is no way to answer concretely if you do not show the part that failed.

  • About getElementById but with getElementsByClassName this explained in the answer, you misunderstood how it works both, getElementsByClassName does not work because it can return multiple items and maybe the number item [0] is not what you want to access. That’s why I suggested document.querySelector. Got it? @Hebertdelima

  • yes, by the way I changed the code, but at the time of setAtribute it returns undefined

  • @Hebertdelima returns Undefined precisely because of what I have already said and I repeat again: getElementsByClassName does not work because it can return multiple items and maybe the number item [0] is not what you want to access.... Summarizing by getElementsByClassName return multiple elements may be that on your page there are more HTML elements with the class "preview" and it ends up accessing the wrong element, now using querySelector(.preview > img) it will only look for the preview that has an img and ignore the others.

Show 4 more comments

1

With jquery

var elemento = $('.preview').find('img').attr('src');
console.log(elemento);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="preview"><img src="teste" title=""/></div>


Note that it would work the same way if it did:

var elemento = $('.preview img').attr('src');
console.log(elemento);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="preview"><img src="teste" title=""/></div>

With vanillaJs

var elemento = document.querySelectorAll('.preview img')[0].getAttribute('src');
console.log(elemento);
<div class="preview"><img src="teste" title="" /></div>


To change the attribute just use setAttribute

console.log(document.querySelectorAll('.preview img')[0].getAttribute('src'));
document.querySelectorAll('.preview img')[0].setAttribute('src', "Ola");
console.log(document.querySelectorAll('.preview img')[0].getAttribute('src'));
<div class="preview"><img src="teste" title="" /></div>

Source: You Might Not Need jQuery

  • 2

    If you’re gonna use querySelectorAll it would be better to use in everything, I see no reason to use getElementsByClassName when using querySelector and querySelectorAll

  • No =) ... I think you confused, > indicates "son", ie in pure js would have to use childNodes and "filter them," wouldn’t be quite the same thing.

  • in that part .setAttribute('src', e.target.result) he returns undefined, placed console.log(e.target.result) and it returns me the image in Base64 data:image/png;base64,iVBORw0KGgoA...

  • I would use: document.querySelectorAll(".preview img")[0].setAttribute("src", e.target.result);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.