简体   繁体   中英

Getting two items from document.querySelectorAll

I'd like to extract data from HTML tags to form the following string:

Adrien Petitpas, Julien M.Jaquet, Pascal Sciarini

Where Adrien , Julien M. and Pascal are first names, and the other - last names.

This is how I extract name:

Array.from(document.querySelectorAll('span.text.given-name')).map(s=>s.outerText)

It gives me: ['Adrien', 'Julien M.', 'Pascal']

Extracting surnames is also easy:

Array.from(document.querySelectorAll('span.text.surname')).map(s=>s.outerText)

How to combine my two selects, to get name and surname combined?

I tried with the script below, but I got wrong result: 'Adrien Petitpas' , which is only the first person in tags.

Note that I'm interested in vanilla JavaScript.

Here's the page I have html text from: https://www.sciencedirect.com/science/article/pii/S0261379420301244?via%3Dihub

 const names = Array.from(document.querySelectorAll('#author-group')) .map(e => e.querySelector('span.text.given-name').outerText + ' ' + e.querySelector('span.text.surname').outerText) .join(', '); console.log(names)
 <div id="author-group"> <span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> <svg focusable="false" viewBox="0 0 106 128" width="19.875" height="24" class="icon icon-person"> <path d="m11.07 1.2e2l0.84-9.29c1.97-18.79 23.34-22.93 41.09-22.93 17.74 0 39.11 4.13 41.08 22.84l0.84 9.38h10.04l-0.93-10.34c-2.15-20.43-20.14-31.66-51.03-31.66s-48.89 11.22-51.05 31.73l-0.91 10.27h10.03m41.93-102.29c-9.72 0-18.24 8.69-18.24 18.59 0 13.67 7.84 23.98 18.24 23.98s18.24-10.31 18.24-23.98c0-9.9-8.52-18.59-18.24-18.59zm0 52.29c-15.96 0-28-14.48-28-33.67 0-15.36 12.82-28.33 28-28.33s28 12.97 28 28.33c0 19.19-12.04 33.67-28 33.67"></path> </svg> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span><span class="text surname">Sciarini</span> </div>

You can use nextElementSibling to get the element containing the surname.

 console.log(Array.from( document.querySelectorAll('span.text.given-name'), e => e.textContent + ' ' + e.nextElementSibling.textContent ));
 <span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> <svg focusable="false" viewBox="0 0 106 128" width="19.875" height="24" class="icon icon-person"> <path d="m11.07 1.2e2l0.84-9.29c1.97-18.79 23.34-22.93 41.09-22.93 17.74 0 39.11 4.13 41.08 22.84l0.84 9.38h10.04l-0.93-10.34c-2.15-20.43-20.14-31.66-51.03-31.66s-48.89 11.22-51.05 31.73l-0.91 10.27h10.03m41.93-102.29c-9.72 0-18.24 8.69-18.24 18.59 0 13.67 7.84 23.98 18.24 23.98s18.24-10.31 18.24-23.98c0-9.9-8.52-18.59-18.24-18.59zm0 52.29c-15.96 0-28-14.48-28-33.67 0-15.36 12.82-28.33 28-28.33s28 12.97 28 28.33c0 19.19-12.04 33.67-28 33.67"></path> </svg> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a>

You can loop over the author anchors that contain the name spans. Then use querySelector to find the given name and surname inside of the author.

 const authors = document.querySelectorAll('.author'); const names = Array.from(authors).map(author => { const givenName = author.querySelector('.given-name'); const surName = author.querySelector('.surname'); return `${givenName.textContent} ${surName.textContent}`; }); console.log(names);
 <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span> <span class="text surname">Jaquet</span> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span> <span class="text surname">Sciarini</span> </span> </a>

I had to complete some of the HTML to get it working, but here's one way to do it.

The problem in your current approach is that your map function receives an array with a single element. Hence the current output is the way it is.

I just changed your selector from #author-group to .author

 console.log(Array.from(document.querySelectorAll('.author')) .map(e => e.querySelector('span.text.given-name').outerText + ' ' + e.querySelector('span.text.surname').outerText) .join(', '));
 <div id="author-group"> <a class="author size-m workspace-trigger" name="bau1" href="#!"> <span class="content"> <span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span><span class="text surname">Sciarini</span> </span> </a> </div>

Another way, if you would like to just combine what you've figured out till now, would be to just concatenate the two arrays:

const givenNames = Array.from(document.querySelectorAll('span.text.given-name')).map(s => s.outerText)

const surnames = Array.from(document.querySelectorAll('span.text.surname')).map(s => s.outerText)

console.log(givenNames.map((givenName, i) => givenName + ' ' + surnames[i]).join(', '));

I think nextSibling is useful in this context :

 let output = []; document.querySelectorAll(".given-name").forEach( el => output.push(el.outerText + " " + el.nextSibling.outerText)); console.log(output);
 <span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> <svg focusable="false" viewBox="0 0 106 128" width="19.875" height="24" class="icon icon-person"> <path d="m11.07 1.2e2l0.84-9.29c1.97-18.79 23.34-22.93 41.09-22.93 17.74 0 39.11 4.13 41.08 22.84l0.84 9.38h10.04l-0.93-10.34c-2.15-20.43-20.14-31.66-51.03-31.66s-48.89 11.22-51.05 31.73l-0.91 10.27h10.03m41.93-102.29c-9.72 0-18.24 8.69-18.24 18.59 0 13.67 7.84 23.98 18.24 23.98s18.24-10.31 18.24-23.98c0-9.9-8.52-18.59-18.24-18.59zm0 52.29c-15.96 0-28-14.48-28-33.67 0-15.36 12.82-28.33 28-28.33s28 12.97 28 28.33c0 19.19-12.04 33.67-28 33.67"></path> </svg> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span><span class="text surname">Sciarini</span>

I would use a good selector and a forEach

 const names = [] document.querySelectorAll('#author-group span.text') .forEach((span,i) => { if (span.classList.contains("given-name")) names.push(span.textContent); else names[names.length-1] += ` ${span.textContent}` }) console.log(names)
 <div id="author-group"> <span class="text given-name">Adrien</span><span class="text surname">Petitpas</span> <svg focusable="false" viewBox="0 0 106 128" width="19.875" height="24" class="icon icon-person"> <path d="m11.07 1.2e2l0.84-9.29c1.97-18.79 23.34-22.93 41.09-22.93 17.74 0 39.11 4.13 41.08 22.84l0.84 9.38h10.04l-0.93-10.34c-2.15-20.43-20.14-31.66-51.03-31.66s-48.89 11.22-51.05 31.73l-0.91 10.27h10.03m41.93-102.29c-9.72 0-18.24 8.69-18.24 18.59 0 13.67 7.84 23.98 18.24 23.98s18.24-10.31 18.24-23.98c0-9.9-8.52-18.59-18.24-18.59zm0 52.29c-15.96 0-28-14.48-28-33.67 0-15.36 12.82-28.33 28-28.33s28 12.97 28 28.33c0 19.19-12.04 33.67-28 33.67"></path> </svg> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau2" href="#!"> <span class="content"> <span class="text given-name">Julien M.</span><span class="text surname">Jaquet</span> <svg focusable="false" viewBox="0 0 102 128" width="19.125" height="24" class="icon icon-envelope"> <path d="m55.8 57.2c-1.78 1.31-5.14 1.31-6.9 0l-31.32-23.2h69.54l-31.32 23.19zm-55.8-24.78l42.94 32.62c2.64 1.95 6.02 2.93 9.4 2.93s6.78-0.98 9.42-2.93l40.24-30.7v-10.34h-102zm92 56.48l-18.06-22.74-8.04 5.95 17.38 21.89h-64.54l18.38-23.12-8.04-5.96-19.08 24.02v-37.58l-1e1 -8.46v61.1h102v-59.18l-1e1 8.46v35.62"></path> </svg> </span> </a> <a class="author size-m workspace-trigger" name="bau3" href="#!"> <span class="content"> <span class="text given-name">Pascal</span><span class="text surname">Sciarini</span></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM