Not able to change nested div in javascript dom - javascript

I am new to javascript and I am facing problems in dynamically changing the onclick attribute of the anchor tag in html. Below is my code:
function changeImage(){
var charAll = <?php echo json_encode($_SESSION['char_all']); ?>;
var charCount = 0;
for (var key in charAll) {
var charDiv = document.getElementById(key);
var anchorTag = charDiv.getElementsByTagName('a')[0];
anchorTag.onclick = function(){startChar('1', charAll[key].toString());};
}
}
<ul id="portfolio-list" data-animated="fadeIn">
<li id="character1">
<img src="character1.jpg" width="250px" height="280px" alt="" />
<div class="portfolio-item-content">
<span class="header">Play!</span>
<p class="body"></p>
</div>
<i class="more">></i>
<div class="post-info">
<div class="post-basic-info">
<h3 class="text-center">Character 1</h3>
</div>
</div>
</li>
<li id="character2">
<img src="character2.jpg" width="250px" height="280px" alt="" />
<div class="portfolio-item-content">
<span class="header">Play!</span>
<p class="body"></p>
</div>
<i class="more">></i>
<div class="post-info">
<div class="post-basic-info">
<h3 class="text-center">Character 2</h3>
</div>
</div>
</li>
</ul>
What I intend on doing is to change the onclick function of each of the <li> elements. The session variable $_SESSION['char_all'] is a dictionary in php, where the key is the character name (string) and the value is the character id corresponding to the character name in my database table. So, ideally the <a> tags under the <li> tags should get the onclick attribute of startChar('1', '1') (for character 1) and startChar('1', '2') (for character 2). But, what I end up with is startChar('1', '2') for both the characters.
Where am I going wrong? It might be something very silly that I am overlooking. But, I am not able to figure out. So, please help me out!

Your for in procedure referes to key which changes while iterating thorugh charAll.
As a solution (not tested), you might want to wrap the function in an outer anonymous-function and pass key to it:
(function(currentKey) {
anchorTag.onclick = function(){startChar('1', charAll[currentKey].toString());};
})(key);

Related

Add a Like + Sort Function to existing dynamic funcion

I wrote a function that dynamically creates a webpage for me based on a json database.
Now I want to add 2 functions:
If you click the like img (its got the id button) the like counter should increase on the webpage by 1. Pretty easy just a on(click) with jQuery variable++ and then .text(variable)
A sort function - based on the likes one item received, you should be able to sort it (most liked div first, 2nd, 3rd....
I can write it for each individually with individual variables when I give all the like buttons and outputs a separate id but I wanted to make it dynamic so if you add new data to json file it dynamically works with the like and sort function.
The likes are not saved anywhere for now.
Since sitting on it for 3h and google so much and so much stackoverflow I think I overloaded my brain with different stuff and now nothing seems to work ^^
function filmInsert(insert) {
$.each(film, function(i, data) { //.each statt loop
let box =
`<div class="boxwrapper">
<div class="imgbox">
<img src="${data.img}" alt="${data.titel}">
</div>
<div class="textbox">
<h3>${data.titel}</h3>
<p>${data.beschreibung}</p>
<p> <a id="button${data.id}">
<img src="img/budspencer_official.png"> Like
</a>
<span class="output${data.id}">${data.likes}</span>
</p>
</div>
</div>`;
insert.append(box);
});
}
I've added a container element for the boxwrapper items as I assume you have one and as it's better to have one instead of just adding the sorted items to the body of the HTML document.
$(document).on("click", ".textbox a", function() {
let likes = parseInt($(this).closest(".textbox").find("span").text());
$(this).closest(".textbox").find("span").text(likes + 1);
});
$("#sort").on("click", function() {
let divs = $(".boxwrapper")
let sorted = divs.sort(function(a, b) {
return $(a).find("span").text() < $(b).find("span").text() ? 1 : -1;
});
$(".container").html(sorted);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="boxwrapper">
<div class="imgbox">
<img src="example.gif" alt="Title">
</div>
<div class="textbox">
<h3>Titel</h3>
<p>Description</p>
<p> <a id="button1">
<img src="https://dummyimage.com/40x40/000/fff&text=1"> Like
</a>
<span class="output1">0</span>
</p>
</div>
</div>
<div class="boxwrapper">
<div class="imgbox">
<img src="example.gif" alt="Title">
</div>
<div class="textbox">
<h3>Titel 2</h3>
<p>Description 2</p>
<p> <a id="button2">
<img src="https://dummyimage.com/40x40/000/fff&text=2"> Like
</a>
<span class="output2">0</span>
</p>
</div>
</div>
</div>
<button id="sort">
Sort
</button>

How to write a document.querySelector for the following code

I'm having difficulty writing the document.querySelector for the following code. Currently I've written this code as querySelector but it does not encompass everything...
Please help me improve this, thank you.
Edit: as there seemed to be some confusion, let me elaborate. I would like all the elements, from div, a, img, everything to be encompassed in the querySelector.
var areaa = document.querySelector("#menu #envelope #links");
<div id="menu">Click here to browse the internet.
<div id="envelope">
<div id="links" >
<div>
<a id="g" class="redirect">
<img id="google" src="assets/google.png" />
</a>
</div>
<div style="width: 20%;"></div>
<div>
<a id="s" class="redirect">
<img id="sava" src="assets/Logo_Sava.png"/>
</a>
</div>
</div>
</div>
</div>
Edit 2 - as more code was required (the href elements are removed / added as needed)...
var menu = document.getElementById("menu");
var areaa = document.querySelectorAll(".areaa");
menu.addEventListener("mouseenter", addHref);
//areaa.addEventListener("mouseleave", remHref);
document.addEventListener("mousemove", function(){
if(this != areaa){
remHref();
}
});
menu.addEventListener("click", addHref);
document.addEventListener("click", function (){
if (this != areaa){
remHref();
}
});
var g = document.getElementById("g");
var s = document.getElementById("s");
function remHref (){
if (g.hasAttribute("href")){
g.removeAttribute("href");
}
if (s.hasAttribute("href")){
s.removeAttribute("href");
}
}
function addHref (){
setTimeout(activate, 250);
}
function activate (){
document.getElementById("g").setAttribute("href", "https://www.google.com");
document.getElementById("s").setAttribute("href", "https://www.example.com");
}
you might want to add a class to all elements you want to be captured, then use document.querySelectorAll
var areaa = document.querySelectorAll(".my-class");
html shoud look like this:
<div id="menu" class="my-class">Click here to browse the internet.
<div id="envelope" class="my-class">
<div id="links" class="my-class">
<div>
<a id="g" class="redirect">
<img class="my-class" id="google" src="assets/google.png" />
</a>
</div>
<div style="width: 20%;"></div>
<div>
<a id="s" class="redirect">
<img id="sava" src="assets/Logo_Sava.png"/>
</a>
</div>
</div>
</div>
If you want to select everything you can use the below:
var areaa = document.querySelectorAll("#menu #envelope #links *");
If you want to be more specific you can do the following (the code below will select all of the anchor tags and images inside #links):
var areaa = document.querySelectorAll("#menu #envelope #links a, #menu #envelope #links img");
You can use querySelectorAll
The Document method querySelectorAll() returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.
Learn more: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
You can use it like this:
var areaa = document.querySelectorAll('*');
This will return all items.
You can replace document with the container if you want to restrict this to a specific div.
2 things, either add a class to every div
<div id="menu" class="area">Click here to browse the internet.
<div id="envelope" class="area">
<div id="links" class="area" >
<div>
<a id="g" class="redirect">
<img id="google" src="assets/google.png" />
</a>
</div>
<div style="width: 20%;"></div>
<div>
<a id="s" class="redirect">
<img id="sava" src="assets/Logo_Sava.png"/>
</a>
</div>
</div>
</div>
</div>
and select all divs by
let areaa = getElementsByClassName("area");
or you can use document.querySelectorAll("yourclassname") to access all divs of that class name

java script replace for html attributes

I have a html tag like the following:
<div id="slide1" class="mySlides" type="slide" index="1" duration="1100" style="display: block;">
<div id="page_number1" class="numbertext">1/2</div>
<div id="slide_content1"><p>First Slide</p>
</div>
<div id="slide_h1" class="slide_h1"></div>
<div id="slide_h2" class="slide_h2"></div>
<div id="playOptions{slide_number}" class="playOptions">|
<span id="remaining_slide_time{slide_number}"></span> |
<span id="remaining_time{slide_number}"></span>
</div>
</div>
</div>
I need to replace {slide_number} with an integer. Whatever I tried the result doesn't replace the {slide_number}
var str = template.replace("{slide_number}", i);
You can use attribute selector contains that will select all elements where id contains {slide_number} and you can replace that part of the id with the number.
document.querySelectorAll("[id*='{slide_number}']").forEach(function(e) {
e.id = e.id.replace("{slide_number}", 1)
})
<div id="slide1" class="mySlides" type="slide" index="1" duration="1100" style="display: block;">
<div id="page_number1" class="numbertext">1/2</div>
<div id="slide_content1">
<p>First Slide</p>
</div>
<div id="slide_h1" class="slide_h1"></div>
<div id="slide_h2" class="slide_h2"></div>
<div id="playOptions{slide_number}" class="playOptions">|
<span id="remaining_slide_time{slide_number}"></span> |
<span id="remaining_time{slide_number}"></span>
</div>
</div>
in javascript you can find them from
document.querySelector('[id$="{slide_number}"]').id;
and
document.querySelector('[id*="{slide_number}"]').id;
Please read this
If you use jquery then it can be done like below:
$('#playOptions').attr('id','playOptions88');
But I recommend you to use HTML data attribute to distinguish different element. It is a very nice thing to work with multiple elements that can be needed to change dynamically.
If you change your ID attribute dynamically adding some integer number then it may be harder to catch them. Instead, use data like below code.
You can make any element unique setting the data-SOMETHING.
If you write the code below:
$('#playOptions').data('roll','100');
Then the element will be
<div id="playOptions" data-roll="100" class="playOptions">
If you write the code below:
$('#playOptions').data('name','ahmad');
Then the element will be
<div id="playOptions" data-name="ahmad" class="playOptions">
You can then catch the element by the code below:
var name = $('#playOptions').data('name');
console.log(name) //Output should be 'ahmad'
Similarly,
var roll = $('#playOptions').data('roll');
console.log(roll) //Output should be '100'
To learn more about the data attribute please see the link
https://api.jquery.com/data/
This solution worked:
var find = '{slide_number}';
var re = new RegExp(find, 'g');
str = template.replace(re, i);

Passing a DOM element to a javascript function

I want to run a generic javascript function with an element, sometimes multiple elements in the same HTML document. It seems to me the easiest way is to call the function from inside a DOM element. OK here's the problem. "this" refers the window element and I have seen how scope works for functions using "this" but I don't see how to get "this" to refer to an element.
I could do getElementById but I want a fairly generic javascript and not have to come up with unique IDs everytime I want to use it. getElementsByClasses may be a workaround but it just seems there should be an easier way to do this without relying on id's or classes.
The HTML
</HEAD>
<BODY>
<div id="content">
<div class="linksbox">
<a href="https://www.corponline.org" target="_blank">
<div class="linkicon">
<img src="asislink.jpg">
</div>
</a>
<div class="linkblurb">
<h2>National</h2>
<p>Description of link</p>
</div>
<script>valignimg();</script>
</div>
</div> <!-- End content -->
</BODY>
</HTML>
The javascript. It's dh and ih that I need to pass to the function.
function valignimg() {
dh = /* div element */
ih = /* image (child element) */
topmargin = (dh.offsetHeight - ih.offsetHeight)/2;
return topmargin;
}
If you're not calling it from one of the elements (i.e. via event handler), you're going to have to use a selector of some kind, either ID or class as you highlighted, or name or tag name if that can work, or some combination. Somewhere along the way it will need to be specified. In even though you weren't keen on using class, that's likely your best option so I've highlighted it in this first example.
//warning - this event isn't supported on some older browsers like IE8
document.addEventListener("DOMContentLoaded", function(event) {
valignAll();
});
function valignimg(dh) {
//Only added the IDs for this purpose, not using them to select elements so there's no functional requirement for them.
console.log(dh.id);
//This supposes that you know the image tag you want is always the first img element among dh's children.
ih = dh.getElementsByTagName('img')[0];
console.log(ih.alt);
var topmargin = (dh.offsetHeight - ih.offsetHeight) / 2;
console.log('dh.offsetHeight = ' + dh.offsetHeight);
console.log('ih.offsetHeight = ' + ih.offsetHeight);
console.log('topmargin = ' + topmargin);
ih.style.marginTop = topmargin + "px";
console.log('ih.style.marginTop = ' + ih.style.marginTop);
}
function valignAll(){
var linkIcons = document.getElementsByClassName('linkicon');
for(i = 0;i < linkIcons.length;i++){
valignimg(linkIcons[i]);
}
}
<BODY>
<div id="content">
<div class="linksbox">
<a href="https://www.corponline.org" target="_blank">
<div id="icon1" class="linkicon">
<img alt="img1" src="http://placehold.it/20x20">
</div>
</a>
<div class="linkblurb">
<h2>National</h2>
<p>Description of link</p>
</div>
<a href="https://www.corponline.org" target="_blank">
<div id="icon2" class="linkicon">
<img alt="img2" src="http://placehold.it/21x20">
</div>
</a>
<div class="linkblurb">
<h2>National</h2>
<p>Description of link</p>
</div>
<a href="https://www.corponline.org" target="_blank">
<div id="icon3" class="linkicon">
<img alt="img3" src="http://placehold.it/22x20">
</div>
</a>
<div class="linkblurb">
<h2>National</h2>
<p>Description of link</p>
</div>
</div>
</div>
<!-- End content -->
</BODY>
You can see, although my usage is pretty rudimentary, I've used getElementsByTagName as well, calling from a parent element other than document. The IDs I've added aren't used for locating anything, I'm just using them so that when I log to console you can see which element it really is, the same as with my horrendous misuse of the alt attribute on the images.
If you know that your only image elements on the page are the ones you're acting on, then maybe starting with document.getElementsByTagName('img') is the approach for you, and then get the div with the .parentNode property. This would remove the reliance on classes, but if you add other img tags to the page then you'd need some way to identify from each one whether it's once you want to run your align function against or not. The img tags you want to access have a common ancestor or parent that no other img tags do. I've added another snippet below that shows this. And you could combine these two approaches with a nest loop to get all img tags within multiple divs that all share a class, for example.
//warning - this event isn't supported on some older browsers like IE8
document.addEventListener("DOMContentLoaded", function(event) {
valignAll();
});
function valignimg(ih) {
//Only added the IDs for this purpose, not using them to select elements so there's no functional requirement for them.
console.log(ih.alt);
//This supposes that you know the image tag you want is always the first img element among dh's children.
dh = ih.parentNode;
console.log(dh.id);
var topmargin = (dh.offsetHeight - ih.offsetHeight) / 2;
console.log('dh.offsetHeight = ' + dh.offsetHeight);
console.log('ih.offsetHeight = ' + ih.offsetHeight);
console.log('topmargin = ' + topmargin);
ih.style.marginTop = topmargin + "px";
console.log('ih.style.marginTop = ' + ih.style.marginTop);
}
function valignAll(){
//if they're the only img tags on the page,
//document.getElementsByTagName('img'); will work fine.
//lets assume they aren't.
var images = document.getElementsByClassName('linksbox')[0].getElementsByTagName('img');
//I can grab the comment parent/ancestor by whatever means available, and then grab just its decendants by tag name.
alert(images);
for(i = 0;i < images.length;i++){
valignimg(images[i]);
}
}
<BODY>
<div id="content">
<img src="http://placehold.it/240x20"><< Some sort of header logo
<div class="linksbox">
<a href="https://www.corponline.org" target="_blank">
<div id="icon1" class="linkicon">
<img alt="img1" src="http://placehold.it/20x20">
</div>
</a>
<div class="linkblurb">
<h2>National</h2>
<p>Description of link</p>
</div>
<a href="https://www.corponline.org" target="_blank">
<div id="icon2" class="linkicon">
<img alt="img2" src="http://placehold.it/21x20">
</div>
</a>
<div class="linkblurb">
<h2>National</h2>
<p>Description of link</p>
</div>
<a href="https://www.corponline.org" target="_blank">
<div id="icon3" class="linkicon">
<img alt="img3" src="http://placehold.it/22x20">
</div>
</a>
<div class="linkblurb">
<h2>National</h2>
<p>Description of link</p>
</div>
</div>
</div>
Sponsor Logos or Site Certs in the footer
<img src="http://placehold.it/20x20"><img src="http://placehold.it/20x20"><img src="http://placehold.it/20x20">
<!-- End content -->
</BODY>

jQuery or Javascript Click function change or add id

Is it possible to change the text "mars-on-newyork" from this links, this is how the links looks like:
<ul>
<li>
<a href="google.com/finder.php?offer=mars-on-newyork">
<img class="the-button-red"/>
</a>
</li>
<li>
<a href="google.com/finder.php?offer=mars-on-newyork">
<img class="the-button-green"/>
</a>
</li>
<li>
<a href="google.com/finder.php?offer=mars-on-newyork">
<img class="the-button-blue"/>
</a>
</li>
</ul>
This code changes my images only:
function changeIt(objName) {
var obj = document.getElementById(objName);
var objId = new Array();
objId[0] = "newyork";
objId[1] = "paris";
objId[2] = "tokyo";
var i;
var tempObj;
for (i = 0; i < objId.length; i++) {
if (objName == objId[i]) {
obj.style.display = "block";
} else {
tempObj = document.getElementById(objId[i]);
tempObj.style.display = "none";
}
}
return;
}
and here is the rest of the html from which the java script changes only the pictures:
<div id="newyork">
<a href="#">
<img src="newyork.jpg"/>
</a>
</div>
<div id="paris" style="display:none">
<img src="paris.jpg" border="0" alt="one"/>
</div>
<div id="tokyo" style="display:none">
<img src="tokyo.jpg" border="0" alt="two" />
</div>
<div style="display:none;">
<a id="one" href="#" onclick="changeIt('newyork');"><img src="newyork.jpg" border="0" alt="one"/></a>
</div>
<div>
<a id="one" href="#" onclick="changeIt('paris');"><img src="paris.jpg" border="0" alt="one"/></a>
</div>
<div>
<a id="two" href="#" onclick="changeIt('tokyo');"><img src="tokyo.jpg" border="0" alt="two"/></a>
</div>
If i click on
<a id="one" href="#" onclick="changeIt('paris');"><img src="paris.jpg" border="0" alt="one"/></a>
i want the text from the links on the ul to change from this:
href="google.com/finder.php?offer=mars-on-newyork
to this:
href="google.com/finder.php?offer=mars-on-paris
and if i click on
<a id="one" href="#" onclick="changeIt('tokyo');"><img src="paris.jpg" border="0" alt="one"/></a>
it changes it to
href="google.com/finder.php?offer=mars-on-tokyo
i want the java script to work like it does, how it changes the images but i also want to take advantage of the click to change the text.
thanks!
I see how it is now, i guess my post wasn't good enough to have piqued you're interest's, i guess i would have to pay a freelancer to help me, thanks anyways guys for your time and help!
Quick answer to "Is it possible to add or change and id from a link?":
$('#link').attr('id', 'yourNewId'); // Change id
Quick solution to "What I also want is not to just change the images but also the id or link"
$('#link').attr('href', 'yourNewUrl'); // Change link
I'm finding it a little hard to understand what you're trying to do, but...
what i also want is not to just change the images but also the id or link from the ul list e.g
OK, to change the link, i.e., the href property of all anchor elements in your ul list, assuming the URL has a fixed format and we can just replace whatever comes after the last "-":
// assume objName = "paris" or whatever
$("ul a").attr("href", function(i, oldVal) {
return oldVal.substr(0, oldVal.lastIndexOf("-") + 1) + objName;
});
If you pass the .attr() method a callback function it will call that function for each element and pass the function the current value - you then return the new value.
The elements in question don't seem to have an id at the moment, so I'm not sure what you mean by wanting to change it.

Categories

Resources