Alternative for document.getElelementById() for several IDs/elements - javascript

I know that document.getElementById() won't work with several ids. So I tried this:
document.getElementsByClassName("circle");
But that also doesn't work at all. But if I use just the document.getElementById() it works with that one id. Here is my code:
let toggle = () => {
let circle = document.getElementsByClassName("circle");
let hidden = circle.getAttribute("hidden");
if (hidden) {
circle.removeAttribute("hidden");
} else {
circle.setAttribute("hidden", "hidden");
}
}

document.getElementsByClassName() returns a NodeList, and to convert it to an array of elements, use Array.from(). this will return an array containing all of the elements with the class name circle
Here is an example, which changes each element with the circle class:
const items = document.getElementsByClassName('circle')
const output = Array.from(items)
function change() {
output.forEach(i => {
var current = i.innerText.split(' ')
current[1] = 'hate'
current = current[0] + ' ' + current[1] + ' ' + current[2]
i.innerText = current
})
}
<p class="circle"> I love cats! </p>
<p class="circle"> I love dogs! </p>
<p class="square">I love green!</p>
<p class="circle"> I love waffles! </p>
<p class="circle"> I love javascript! </p>
<p class="square">I love tea!</p>
<button onclick="change()">Change</button>

You can try this.
const selectedIds = document.querySelectorAll('#id1, #id12, #id3');
console.log(selectedIds);
//Will log [element#id1, element#id2, element#id3]
Then you can do something like this:
for(const element of selectedIds){
//Do something with element
//Example:
element.style.color = "red"
}

Related

How to use multiple IDs in one function

How to use it on multiple ids such that when #more1 is clicked , #details1 will appear. And when #more2 is clicked , #details2 will appear?
Note that I want it only using one function.
Thank U.
$(document).ready(function () {
$('#more1,#more2').click(function () {
$('#details1,#details2').slideToggle();
});
});
You can use a more general selector: $('[id^="more"]').
This will select all items that have an id that starts with "more", and will have a click event tied to them.
Then you can use the number in the id property and use it to build the id of the target.
$('[id^="more"]').click(function()
{
let id = $(this).attr('id');
let num = /\d+/.exec(id)[0];
$('#details' + num).slideToggle();
});
$(document).ready(function()
{
$('[id^="more"]').click(function()
{
let id = $(this).attr('id');
let num = /\d+/.exec(id)[0];
$('#details' + num).slideToggle();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<button id="more1">One</button>
<span id="details1">Each Section</span>
</div>
<div>
<button id="more2">Two</button>
<span id="details2">Is Independent</span>
</div>
<div>...</div>
<div>
<button id="more25">Twenty Five</button>
<span id="details25">Of all the others</span>
</div>
You can check the id of the current item and act accordingly:
if($(this).attr('id') == 'more1') $('#details1').slideToggle();
A more elegant solution would be:
$('#details' + $(this).attr('id')[$(this).attr('id').length - 1]).slideToggle();
The last one uses the fact that the numbering in the ids is similar, and if you have less than 10 such ids it will work properly.
You can use for loop
$(document).ready(function()
{
var length = 9; // any number you need
for (var i = 0; i < length; i++ ) {
$('#more' + i).click(function()
{
$('#details' + i).slideToggle();
});
}
});

How to select middle nodes with specific text using jQuery :contains selector?

I want to get html elements containing specific text, and I used :contains selector. However, I'm not getting the nodes that I target.
In this example I'm trying to get all elements that has the 'today?' text, even if it's splited with other inline elements like <a>, <span>, <sup>, etc.
So I expect the result: DIV.some-class, P.another-class
//let results = $(':contains(today?):not(:has(*))')
let results = $(":contains('today?')").not("script")
results.each(function() {
console.log(`${this.tagName}${this.className ? '.' + this.className : ''}`)
})
/**
prints HTML, BODY, DIV.content, DIV.some-class, P.another-class
*/
console.log()
let results2 = $(":contains('today?')").not("script").children().filter(function() {
return ($(this).text().indexOf("today?") > -1)
}).get()
results2.forEach(r => {
console.log(`${r.tagName}${r.className ? '.' + r.className : ''}`)
})
/**
prints BODY, DIV.content, DIV.some-class, P.another-class
*/
console.log()
let results3 = $(":contains('today?')").not("script").filter(function() {
return (
$(this).clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.filter(":contains('today?')").length > 0)
}).get();
results3.forEach(r => {
console.log(`${r.tagName}${r.className ? '.' + r.className : ''}`)
})
/**
prints P.another-class
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='content'>
<div class='some-class'>
Hello world! How are you<a> doing today</a>?
</div>
<div class='some-other-class'>
Bye world!
</div>
<p class='another-class'>
Any <b>plans</b> for today?
</p>
</div>
You can use children() and contains a selector. Here's a working solution:
var elements = $('.content').children().filter(":contains('today?')");
var result = $.map(elements, function (el) {
return `${el.tagName}${el.className ? '.' + el.className : ''}`;
});
console.log(result.join(', '));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='content'>
<div class='some-class'>
Hello world! How are you<a> doing today</a>?
</div>
<div class='some-other-class'>
Bye world!
</div>
<p class='another-class'>
Any <b>plans</b> for today?
</p>
</div>

Transform text inside parentheses to uppercase

What I'm am trying to do is get the html text inside parentheses and transform it to uppercase. I want the output to be:
Cat (IVA)
Dog (MANGO) etc.
What am I doing wrong?
// Transform text inside parentheses to upper case
let petName = $(".petName").text();
let regExp = /\(([^)]+)\)/;
for (var i = 0; i < petName.length; i++) {
let regExp = /\(([^)]+)\)/;
regExp.replace(petName[i].toUpperCase())
}
html
<div>
<h1 class="petName">Cat (Iva)</h1>
</div>
<div>
<h1 class="petName">Dog (Mango)</h1>
</div>
<div>
<h1 class="petName">Puppy (Mara)</h1>
</div>
Multiple things wrong here:
String objects are immutable in JS. regExp.replace(…) does not change the original, it only returns the altered result.`
You are not selecting any elements to begin with. The selector .petName h1 matches h1 elements that are descendants of an element with the class petName
you can not directly call a function while replacing, you need to do this via a callback function, that gets the match(es) passed to it.
let $petNames = $("h1.petName")
$petNames.each(function() {
$(this).text( $(this).text().replace(/\(([^)]+)\)/, function(match) {
return match.toUpperCase()
} ) )
})
This should do it. :)
$(".petName").each(function(i, el) {
const text = el.innerText;
const strToReplace = text.match(/(\(.*\))/)[0];
el.innerText = text.replace(strToReplace, strToReplace.toUpperCase());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<h1 class="petName">Cat (Iva)</h1>
</div>
<div>
<h1 class="petName">Dog (Mango)</h1>
</div>
<div>
<h1 class="petName">Puppy (Mara)</h1>
</div>

using jquery next to find "nested" sibling

Perhaps there is a simple solution to this, but I am not able to figure it out.
I have a bunch of images sitting like this:
<div class='image-bar'>
<span>
<img class='my-image' src='blah1' id='1'>
</span>
<span>
<img class='my-image' src='blah2' id='2'>
</span>
<span>
<img class='my-image' src='blah3' id='3'>
</span>
</div>
Given the id of an image, I need to find the next and previous image to it, using jQuery.
Using 2 as example I tried following to get next image:
$('.image-bar').find('.my-image[id="2"]').next();
I think until my 'attribute equals' selector I am correct, but since the image with id 3 is not exactly a sibling, the next() is not working. How can I handle this? Any pointers are greatly appreciated!
This wont' work because the elements are wrapped in spans, you need to go relative to the parents of the images instead.
var next = $('.image-bar').find('.my-image[id=2]').parent().next().find('img');
var prev = $('.image-bar').find('.my-image[id=2]').parent().prev().find('img');
EDIT
Assuming you may have more images to deal with and are interested in the same functionality, you can do the following:
var elementId = "2";
var next = $('.image-bar').find('.my-image[id=' + elementId + ']').parent().next().find('img');
var prev = $('.image-bar').find('.my-image[id=' + elementId + ']').parent().prev().find('img');
If you have the id names in sequence I have another solution
var imgArray = $(".my-image"); // this will have an array with all images
Find image with id = 2
var id = 2;
imageArray[id-1]; // returns image with id 2
Find next image
imageArray[id];
Find previous image
imageArray[id-2];
NB: you need to check if the array index exists.
Fiddle here
var imgArray = $(".my-image"); // this will have an array with all images
console.log( getImage(2/* image id */, "next"));
function getImage(id, pos) {
var returnImage;
if(pos === "next") {
returnImage = imgArray[id] ? imgArray[id] : "";
}
else if(pos === "prev") {
returnImage = imgArray[id - 2 ] ? imgArray[id - 2] : "";
}
else {
returnImage = imgArray[id-1] ? imgArray[id-1] : "";
}
return returnImage;
}
Try using .filter() , .index() , .slice()
var imgs = $(".image-bar img");
var curr = imgs.filter("#2");
var i = curr.index(imgs.selector);
var prev = imgs.slice(i - 1, i);
var next = imgs.slice(i + 1, i + 2);
console.log("curr:"+curr[0].id
, "curr index:" + i
, "prev:" + prev[0].id
, "next:" + next[0].id);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class='image-bar'>
<span>
<img class='my-image' src='blah1' id='1'>
</span>
<span>
<img class='my-image' src='blah2' id='2'>
</span>
<span>
<img class='my-image' src='blah3' id='3'>
</span>
</div>

How to get child element by ID in JavaScript?

I have following html:
<div id="note">
<textarea id="textid" class="textclass">Text</textarea>
</div>
How can I get textarea element? I can't use document.getElementById("textid") for it
I'm doing it like this now:
var note = document.getElementById("note");
var notetext = note.querySelector('#textid');
but it doesn't work in IE(8)
How else I can do it? jQuery is ok
Thanks
If jQuery is okay, you can use find(). It's basically equivalent to the way you are doing it right now.
$('#note').find('#textid');
You can also use jQuery selectors to basically achieve the same thing:
$('#note #textid');
Using these methods to get something that already has an ID is kind of strange, but I'm supplying these assuming it's not really how you plan on using it.
On a side note, you should know ID's should be unique in your webpage. If you plan on having multiple elements with the same "ID" consider using a specific class name.
Update 2020.03.10
It's a breeze to use native JS for this:
document.querySelector('#note #textid');
If you want to first find #note then #textid you have to check the first querySelector result. If it fails to match, chaining is no longer possible :(
var parent = document.querySelector('#note');
var child = parent ? parent.querySelector('#textid') : null;
Here is a pure JavaScript solution (without jQuery)
var _Utils = function ()
{
this.findChildById = function (element, childID, isSearchInnerDescendant) // isSearchInnerDescendant <= true for search in inner childern
{
var retElement = null;
var lstChildren = isSearchInnerDescendant ? Utils.getAllDescendant(element) : element.childNodes;
for (var i = 0; i < lstChildren.length; i++)
{
if (lstChildren[i].id == childID)
{
retElement = lstChildren[i];
break;
}
}
return retElement;
}
this.getAllDescendant = function (element, lstChildrenNodes)
{
lstChildrenNodes = lstChildrenNodes ? lstChildrenNodes : [];
var lstChildren = element.childNodes;
for (var i = 0; i < lstChildren.length; i++)
{
if (lstChildren[i].nodeType == 1) // 1 is 'ELEMENT_NODE'
{
lstChildrenNodes.push(lstChildren[i]);
lstChildrenNodes = Utils.getAllDescendant(lstChildren[i], lstChildrenNodes);
}
}
return lstChildrenNodes;
}
}
var Utils = new _Utils;
Example of use:
var myDiv = document.createElement("div");
myDiv.innerHTML = "<table id='tableToolbar'>" +
"<tr>" +
"<td>" +
"<div id='divIdToSearch'>" +
"</div>" +
"</td>" +
"</tr>" +
"</table>";
var divToSearch = Utils.findChildById(myDiv, "divIdToSearch", true);
(Dwell in atom)
<div id="note">
<textarea id="textid" class="textclass">Text</textarea>
</div>
<script type="text/javascript">
var note = document.getElementById('textid').value;
alert(note);
</script>
Using jQuery
$('#note textarea');
or just
$('#textid');
$(selectedDOM).find();
function looking for all dom objects inside the selected DOM.
i.e.
<div id="mainDiv">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<div id="innerDiv">
link
<p>Paragraph 3</p>
</div>
</div>
here if you write;
$("#mainDiv").find("p");
you will get tree p elements together. On the other side,
$("#mainDiv").children("p");
Function searching in the just children DOMs of the selected DOM object. So, by this code you will get just paragraph 1 and paragraph 2. It is so beneficial to prevent browser doing unnecessary progress.

Categories

Resources