How do I use querySelectorAll to select <p> with parent <div class="entry-content"> only?
Eg.
<div>
<p>ParagraphA</p>
<p>ParagraphB</p>
</div>
<div class="entry-content">
<p>Paragraph1</p>
<p>Paragraph2</p>
<p>Paragraph3</p>
</div>
<p>Paragraph4</p>
<p>Paragraph5</p>
I only want Paragraph1 ~ Paragraph3 to be selected.
I'm currently using var x = document.querySelectorAll("p"); which is selecting everything.
var x = document.querySelectorAll("div > p"); is very closed to getting what I need, but I need to ensure only selecting all <p> elements within the <div class="entry-content"> with class specified.
How can this be modified to accomplish the task?
Specify the div's class:
document.querySelectorAll('div.entry-content > p');
var entryContent = document.querySelector('.entry-content');//matches first
var p = entryContent.querySelectorAll("p"); //matches all
console.log(p);
<div>
<p>ParagraphA</p>
<p>ParagraphB</p>
</div>
<div class="entry-content">
<p>Paragraph1</p>
<p>Paragraph2</p>
<p>Paragraph3</p>
</div>
<div>
<p>Paragraph4</p>
<p>Paragraph5</p>
</div>
Related
So I want to know how do I get count of parent child child childs for example:
const parent = document.querySelectorAll('.parent');
parent.forEach(el => {
const ul = el.querySelector('.child3-child');
const div = document.createElement('div');
div.textContent = ul.childNodes.length;
el.append(div);
});
<div class="parent">
<div class="child1">
text
</div>
<div class="child2">
text
</div>
<div class="child3">
<ul class="child3-child">
<li>
some text...
</li>
<ul>
</div>
</div>
And now I want count how many <ul class="child3-child"> has child elements in this case it has only 1 li.
Use children instead of childNodes. The former includes HTML Elements while the latter includes text nodes.
Close your </ul> tag properly or else the borwser will think it's opening a nested element.
const parent = document.querySelectorAll('.parent');
parent.forEach(el => {
const ul = el.querySelector('.child3-child');
const div = document.createElement('div');
div.textContent = ul.children.length;
el.append(div);
});
<div class="parent">
<div class="child1">
text
</div>
<div class="child2">
text
</div>
<div class="child3">
<ul class="child3-child">
<li>
some text...
</li>
</ul> <!--- This wasn't properly closed -->
</div>
</div>
The goal I'm after is trimming the first character from each of the link's text.
<div class="item">
<div>
1One
</div>
</div>
<div class="item">
<div>
2Two
</div>
</div>
I've tried simply substring and slice:
$('.item div a').substring(1);
$('.item div a').slice(1);
But after some fiddling, I've yet to get it to work. Then I attempted to use .text(), but it instead collects all the outputs from each link and replaces them, not individually. Which makes it so the end result is all the link text are the same.
var input = $('.item div a').text();
var output = input.substring(1);
$('.item div a').text(output);
Is there an alternative to using .substring() and .slice() to get this to work? (Also, I'm unable to alter the original HTML for this scenario)
Is this what you need?
[...document.querySelectorAll('.item div a')].forEach(a=>
a.innerHTML=a.innerHTML.substring(1))
<div class="item">
<div>
1One
</div>
</div>
<div class="item">
<div>
2Two
</div>
</div>
And jquery version:
$('.item div a').each(function(){
$(this).text($(this).text().substring(1));
});
var links = document.getElementsByTagName('a');
for(let i = 0;i<links.length;i++){
var string = links[i].innerHTML;
string=string.substring(1);
console.log(string);
}
<div class="item">
<div>
1One
</div>
</div>
<div class="item">
<div>
2Two
</div>
</div>
Something like this?
$(function() {
$("a").each((idx,el) => el.innerHTML = el.innerHTML.substring(1));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">
<div>
1One
</div>
</div>
<div class="item">
<div>
2Two
</div>
</div>
Use text(function) to iterate each instance.
The problem you had is jQuery slice() is for filtering the $(selector) collection and there is no jQuery substring() method
$('.item a').text((i, curr) => curr.slice(1))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">
<div>
1One
</div>
</div>
<div class="item">
<div>
2Two
</div>
</div>
Is there any way to display all inner html content inside a div with plain javascript?
MyFiddle
<div id="parent">
<div id="child">
some-value
</div>
</div>
<div id="output">
</div>
I am trying to use outerhtml
var parent = document.getElementById("parent");
document.getElementById("output").innerHTML = parent.outerHtml;
You misspelled outerHTML (HTML in all capital). But to show HTML tags as well, use innerText instead
var parent = document.getElementById("parent");
document.getElementById("output").innerText = parent.outerHTML;
<div id="parent">
<div id="child">
some-value
</div>
</div>
<pre id="output"></pre>
Use innerText with outerHTML
var parent = document.getElementById("parent");
document.getElementById("output").innerText = parent.outerHTML;
#output {
white-space: pre;
}
<div id="parent">
<div id="child">
some-value
</div>
</div>
<div id="output"></div>
If you want to create everything from Javascript only. Look at this example.
var div = document.createElement("div");
var nodeDiv = document.createTextNode("Pay attention! This is new.");
div.appendChild(nodeDiv);
var element = document.getElementById("parent");
element.appendChild(div);
<div id="parent">
<div id="child">
some-value
</div>
</div>
Basically I have multiple elements A,B,C,... And they are all "connected" to A1,B1,C1,...
For simplicity and better understanding , lets say A,B,C are personal data about A1,B1,C1 persons (A1,B1,C1 are pictures of those persons).
html looks like :
<div class="personal_data">
<p class="A"> Ronnie </p>
<p class="B"> James </p>
<p class="C"> Dio </p>
</div>
<div class="persons">
<div>
<div>
<div class="A1"> img1 </div>
</div>
</div>
<div>
<div>
<div class="B1"> img2 </div>
</div>
</div>
<div>
<div>
<div class="C1"> img3 </div>
</div>
</div>
</div>
Yes , those divs that contain img are nested like that and the order must not be changed.
p elements are hiddenand are shown in personal_data window according to which person has been clicked.
How can I make it that when one picture is clicked its corresponding p element is shown and the rest of them are hidden , and when I click to another picture it shows another p element and hides previous , and so on?
I tried with jQuery two methods :
$(".A1").click(function () {
$(".A").show();
$(".B").hide();
$(".C").hide(); })
But I immediately abandoned it for obvious reasons. It's ugly and I have more than 3 persons so doing it for every person like this would not be a good practice.
$(".persons div").click(function () {
var index=$(".persons div").index(this);
$(".personal_data p").hide().eq(index).show(); })
Because I don't know all jQuery functions ( and all native javascript functions) I was amazed by the power of these but because of those nested images the index of A that corresponds to the A1 would be ok , but other indexes would not have their pair with persons because the number od divs are not equal , rather then "shifted" by +3. So I tweaked .personal_data with 2 empty p elements after A,B and C so the indexes would align. And it worked but I feel like I am violating something .
Is there a more elegant way for achieving this? I feel my problem is lack of knowledge of all functions that exist inside javascript (and jQuery).
Get the list of matching clickable elements, and the personal data, ahead of time (so we don't have to keep re-querying them):
var clickables = $('.persons > div > div > div[class]');
var data = $('.personal_data p');
Then, when clicked, get the index of the clicked thing in that list, rather than hunt through the DOM:
clickables.click(
function() {
data.hide(); // hide the others
var idx = clickables.index(this);
$(data[idx]).show();
}
);
var clickables = $('.persons > div > div > div[class]');
var data = $('.personal_data p');
clickables.click(
function() {
data.hide();
var idx = clickables.index(this);
$(data[idx]).show();
}
)
.personal_data p {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="personal_data">
<p class="A">Ronnie</p>
<p class="B">James</p>
<p class="C">Dio</p>
</div>
<div class="persons">
<div>
<div>
<div class="A1">img1</div>
</div>
</div>
<div>
<div>
<div class="B1">img2</div>
</div>
</div>
<div>
<div>
<div class="C1">img3</div>
</div>
</div>
</div>
Assuming that you will have this class structure in your page consistently, I did something by comparing the class names. If the class name of the clicked div contains the class name of the p element, then the p will be shown, otherwise they will be hidden :
$(".persons div").click(function () {
var myclassname = $(this).attr('class');
$(".personal_data p").hide().filter(function() {
return myclassname.indexOf($(this).attr('class')) >= 0); //if it contains
}).show();
});
Well, I don't like working with index's in lists. I prefer that you retrieve it when you mount it on the server-side with attributes and id's.
So try the following:
$(document).ready(function () {
$('.personal_data p').on('click', function (event) {
var theTarget = $(this).attr('data-detail');
$('.person-details').removeClass('show'); //remove this line in case you don't want only one at a time
$('#' + theTarget).addClass('show');
});
})
.person-details {
opacity: 0;
}
.person-details.show {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="personal_data">
<p class="A" data-detail="ronnie"> Ronnie </p>
<p class="B" data-detail="james"> James </p>
<p class="C" data-detail="dio"> Dio </p>
</div>
<div class="persons">
<div>
<div>
<div class="A1 person-details" id="ronnie"> img1 </div>
</div>
</div>
<div>
<div>
<div class="B1 person-details" id="james"> img2 </div>
</div>
</div>
<div>
<div>
<div class="C1 person-details" id="dio"> img3 </div>
</div>
</div>
</div>
All the styling or class you can customize. If you prefer showing or hiding , just change the removeClass to hide, and the addClass to show
If you want the oposite interaction :
$(document).ready(function () {
$('.person-details').on('click', function (event) {
var theTarget = $(this).attr('data-detail');
$('.personal_data p').removeClass('show'); //remove this line in case you don't want only one at a time
$('#' + theTarget).addClass('show');
});
})
.personal_data p {
opacity: 0;
}
.personal_data p.show {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="personal_data">
<p class="A" id="ronnie"> Ronnie </p>
<p class="B" id="james"> James </p>
<p class="C" id="dio"> Dio </p>
</div>
<div class="persons">
<div>
<div>
<div class="A1 person-details" data-detail="ronnie"> img1 </div>
</div>
</div>
<div>
<div>
<div class="B1 person-details" data-detail="james" > img2 </div>
</div>
</div>
<div>
<div>
<div class="C1 person-details" data-detail="dio"> img3 </div>
</div>
</div>
</div>
I need to access the DOM tree and get the elements just 1 level below the current element.
Read the following code:
<div id="node">
<div id="a">
<div id="aa">
<div id="ab">
<div id="aba"></div>
</div>
</div>
</div>
<div id="b">
<div id="ba">
<div id="bb">
<div id="bba"></div>
</div>
</div>
</div>
<div id="c">
<div id="ca">
<div id="cb">
<div id="cba"></div>
</div>
</div>
</div>
</div>
I want to get the 3 elements "a", "b", "c" under "node". What should I do?
var nodes = node.getElementsByTagName("div") <---- I get all the divs but not the 3 divs I need.
var nodes = node.childNodes; <---- works in IE, but FF contains Text Node
Does anyone know how to solve the problem?
You could use a function that rules out all non-element nodes:
function getChildNodes(node) {
var children = new Array();
for(var child in node.childNodes) {
if(node.childNodes[child].nodeType == 1) {
children.push(child);
}
}
return children;
}
I'd highly recommend you look at JQuery. The task you're looking to do is straightforward in pure Javascript, but if you're doing any additional DOM traversal, JQuery is going to save you countless hours of frustration. Not only that but it works across all browsers and has a very good "document ready" method.
Your problem solved with JQuery looks like:
$(document).ready(function() {
var children = $("#node").children();
});
It looks for any element with an id of "node" then returns its children. In this case, children is a JQuery collection that can be iterated over using a for loop. Additionally you could iterate over them using the each() command.
This is simplier than you think:
var nodes = node.querySelector("node > div");
Try this (late answer, but can be useful for others):
var list;
list=document.getElementById("node").querySelectorAll("#node>div");
Universal selectors can do the trick:
var subNodes = document.querySelectorAll("#node > *");
Query parts:
#node is unique container selector
> next slector should be applied only on childs
* universal selector that match every tag but not text
Can I use universal selector
In my opinion the easiest way to do this is to add a class name to the
first level child nodes:
<div id="node">
<div id="a" class="level_1">
<div id="aa">
<div id="ab">
<div id="aba"></div>
</div>
</div>
</div>
<div id="b" class="level_1">
<div id="ba">
<div id="bb">
<div id="bba"></div>
</div>
</div>
</div>
<div id="c" class="level_1">
<div id="ca">
<div id="cb">
<div id="cba"></div>
</div>
</div>
</div>
</div>
and then to use the method getElementsByClassName, so in this case:
document.getElementById('node').getElementsByClassName('level_1');
I think node.childNodes is the right place to start. You could (to make it work with FF too), test the nodeName (and possibly nodeType) of all child nodes you get, to skip text nodes.
Also you might have a look at some javascript library like prototype, which provide a lot of useful functions.
I've added some text so we can see that it is working, and JavaScript that will add "added!" to the bottom of each of the divs at the base:
var cDiv = document.querySelectorAll('body > div > div'), i;
for (i = 0; i < cDiv.length; i++)
{
cDiv[i].appendChild(document.createTextNode('added!'));
}
<div id="node">
<div id="a">a
<div id="aa">aa
<div id="ab">ab
<div id="aba">aba</div>
</div>
</div>
</div>
<div id="b">b
<div id="ba">ba
<div id="bb">bb
<div id="bba">bba</div>
</div>
</div>
</div>
<div id="c">c
<div id="ca">ca
<div id="cb">cb
<div id="cba">cba</div>
</div>
</div>
</div>
</div>