Javascript select div and change href inside - javascript

I am trying to modify the links in my page using JavaScript. I can select the div and the a element but cannot change the href.
Shopify is using a for loop to generate these objects and need each object to have a different link.
Here is the HTML:
<div id="tri-banner-1" class="banner-element banner-1 col-sm-4">
<a href="collections/all"><div class="home-banner">
<img src='//cdn.shopify.com/s/files/1/1093/4220/t/2/assets/group_top_banner01.png?17711418137279289271' alt="">
<div class="banner-caption">
<div class="display-table">
<div class="display-tablecell">
</div>
</div>
</div>
</div></a>
</div>
<div id="tri-banner-2" class="banner-element banner-2 col-sm-4">
<a href="collections/all"><div class="home-banner">
<img src='//cdn.shopify.com/s/files/1/1093/4220/t/2/assets/group_top_banner02.png?17711418137279289271' alt="">
<div class="banner-caption">
<div class="display-table">
<div class="display-tablecell">
</div>
</div>
</div>
</div></a>
</div>
<div id="tri-banner-3" class="banner-element banner-3 col-sm-4">
<a href="collections/all"><div class="home-banner">
<img src='//cdn.shopify.com/s/files/1/1093/4220/t/2/assets/group_top_banner03.png?17711418137279289271' alt="">
<div class="banner-caption">
<div class="display-table">
<div class="display-tablecell">
</div>
</div>
</div>
</div></a>
</div>
Here is my JavaScript.
<script type="text/javascript">
$(window).bind("load", function() {
window.alert("Test");
var banner1 = document.getElementById("tri-banner-1");
var banner1Links = banner1.getElementsByTagName("a");
banner1Links.href="facebook.com";
});
</script>

banner1.getElementsByTagName("a"); returns an HTMLCollection . You should either select the element using the index ; e.g.;
// set `href` of first `a` element in `bannerLinks`
banner1Links[0].href = "facebook.com";
or iterate the collection
for (var i = 0; i < bannerLinks.length; i++) {
bannerLinks[i] = /* set `href` here */;
}

banner1Links gets an array value so you need to loop in that array and for every array element you pass the value
// instead of banner1Links.href="facebook.com";
for(var i = 0; i < banner1Links.length; i += 1){
banner1Links[i] = 'http://example.com';
}

Related

How to get children of a div

User can, by pressing a button, select a particular topic of interest. When that happens, various divs will either become visible or invisible depending on whether that div has a link referring to that topic.
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
var topicAreas = area.getElementsByClassName("topicArea");
for (i = 0; i < topicAreas.length; i++) {
var children = topicAreas[i].children;
var topics = [];
for (j = 0; j < children.length; j++) {
topics.push(children[j].getAttribute("asp-route-name"));
document.getElementById("firstTest").innerHTML = children[j].toString();
}
var b = topics.includes(topic);
if (b == true) {
var parentId = document.getElementById(topicAreas[i]).parentNode.id;
document.getElementById(parent).style.display = 'block';
} else {
document.getElementById(parent).style.display = 'none';
}
}
}
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
The trouble, as far as I can tell, begin early in the JS part. I can see that when a do var children=topicAreas[i].children, I get nothing.
I hope this is what you're trying to do. Based on what button you click, respective div is displayed.
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
var topicAreas = area.getElementsByClassName("topicArea");
for (i = 0; i < topicAreas.length; i++) {
var children = topicAreas[i].children;
for (j = 0; j < children.length; j++) {
var parentId = topicAreas[i].parentNode.id;
if(children[j].getAttribute("asp-route-name") === topic){
document.getElementById(parentId).style.display = 'block';
}else{
document.getElementById(parentId).style.display = 'none';
}
}
}
}
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
Children isn't the issue. When you run your code you get the error "Uncaught TypeError: Cannot set property 'innerHTML' of null". Looking at your code where you are using .innerHTML, we see that you are trying to reference an element that you don't have in this code:
document.getElementById("firstTest")
Now, after adding that, you still have some items that you should change.
asp-action and asp-route-name are invalid HTML. Are you using a
framework that requires this syntax?
Don't use .getElementsByClassName().
Use .querySelectorAll() and Array.forEach() on the result for
easier looping.
Don't use .innerHTML when you aren't working with HTML strings as there are security and performance implications to doing so.
Avoid inline styles when you can. Using them causes duplication of code and code is harder to scale. Instead, use CSS classes and the .classList API.
It's not super clear exactly what is supposed to happen when clicking your buttons, but see the updated code below:
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
// Don't use .getElementsByClassName() as it provides a live node list
// and causes quite a performance hit, especially when used in loops.
// Use .querySelectorAll() and then use .forEach() on the collection that
// it returns to iterate over them.
area.querySelectorAll(".topicArea").forEach(function(area){
var topics = [];
// No need for children, here. Again, use .querySelectorAll()
area.querySelectorAll("*").forEach(function(child) {
topics.push(child.getAttribute("asp-route-name"));
document.getElementById("firstTest").textContent = child.getAttribute("asp-route-name");
});
if (topics.indexOf(topic) > -1) {
// Don't use inline styles if you can avoid it.
// Instead use pre-made classes.
area.classList.add("hidden");
}
else {
area.classList.remove("hidden");
}
});
}
/* Use CSS classes when possible instead of inline styles */
.hidden { display:none; }
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
<div id="firstTest"></div>

Replace class name on window resize

Here is my Markup. I want to update/replace class name col-sm-3
to col-md-6 on widow resize (ex: width < 800)
<div class="llotherlogos-userthumb">
<div class="col-sm-3">
<div class="logo-thumb">
<img class="img-fluid" src="images/logos/logo-seven.jpg" alt="">
<div class="logo-caption">
<div class="ll-category">Business</div>
<div class="ll-price"><span>1000BDT</span>5000 BDT</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="logo-thumb">
<img class="img-fluid" src="images/logos/logo-eight.jpg" alt="">
<div class="logo-caption">
<div class="ll-category">Business</div>
<div class="ll-price"><span>1000BDT</span>5000 BDT</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="logo-thumb">
<img class="img-fluid" src="images/logos/logo-nine.jpg" alt="">
<div class="logo-caption">
<div class="ll-category">Business</div>
<div class="ll-price"><span>1000BDT</span>5000 BDT</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="logo-thumb">
<img class="img-fluid" src="images/logos/logo-ten.jpg" alt="">
<div class="logo-caption">
<div class="ll-category">Business</div>
<div class="ll-price"><span>1000BDT</span>5000 BDT</div>
</div>
</div>
</div>
</div>
JavaScript
var otherlogos = function(){
var ww = document.body.clientWidth;
var myLogos = document.querySelectorAll(".llotherlogos-userthumb .col-sm-3");
if(ww < 800){
myLogos.className.replace(col-sm-3, col-md-6);
}
}
window.onresize = otherLogos;
You need this:
myLogos.className.replace(col-sm-3, col-md-6);
To be:
myLogos[0].classList.replace('col-sm-3', 'col-md-6');
(querySelectorAll returns an array of elements, even if only one element matches, hence the need for myLogos[0].)
To do this for multiple elements, you'd need something like this (explicit for loop, because I think foreach doesn't work here):
for (let i = 0; i < myLogos.length; ++i)
myLogos[i].classList.replace('col-sm-3', 'col-md-6');
with jQuery you could do something like this
<script>
$(window).resize(function () {
if($(window).width()<800){
$('.llotherlogos-userthumb').children().removeClass('col-sm-3').addClass('col-md-6');
}else{
$('.llotherlogos-userthumb').children().removeClass('col-md-6').addClass('col-sm-3');
}
});
</script>
You just require to use toggle for achieving the goal. The example is given below:
myLogos.classList.toggle('col-sm-3');
myLogos.classList.toggle('col-md-6');
or
var myLogos = document.querySelectorAll(".llotherlogos-userthumb .col-sm-3");
var classes = myLogos.classList;
var result = classes.replace("col-sm-3", "col-md-6");
console.log(result);
For more info on above access this link
try this jquery code:
enter$( window ).resize(function() {
var ww = document.body.clientWidth;
<==========now select id or element==============>
$("#a1").addClass( "my-hidden").removeClass("my-disply");
// code here
});

How do I get text of nested div in a specific HTML list element as alert message onclick [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
This is my HTML file structure:
var li = document.getElementById("myList").getElementsByTagName("li");
for (var i = 0; i < li.length; i++) {
li.onclick = function () {
alert(document.getElementsByClassName("title")[i].innerHTML);
}
}
<div class="maincontent">
<ul id="myList">
<li>
<div class="image">
<img src="http://lorempixel.com/100/100/">
<div class="button option-vertical-grid"></div>
</div>
<div class="info">
<div class="url">lorempixel.com</div>
<div class="title" id="title">M1</div>
<div class="play"><section>0</section></div>
</div>
<div class="info2">
<div class="date">30.11.2016</div>
<div class="button option-vertical"></div>
</div>
</li>
<li>
<div class="image">
<img src="http://lorempixel.com/102/100/">
<div class="button option-vertical-grid"></div>
</div>
<div class="info">
<div class="url">lorempixel.com</div>
<div class="title">M2</div>
<div class="play"><section>0</section></div>
</div>
<div class="info2">
<div class="date">30.11.2016</div>
<div class="button option-vertical"></div>
</div>
</li>
<li>
<div class="image">
<img src="http://lorempixel.com/103/100/">
<div class="button option-vertical-grid"></div>
</div>
<div class="info">
<div class="url">lorempixel.com</div>
<div class="title">M3</div>
<div class="play"><section>0</section></div>
</div>
<div class="info2">
<div class="date">30.11.2016</div>
<div class="button option-vertical"></div>
</div>
</li>
</ul>
</div>
The first task is:
On click of the list it should show an alert message with the title of the clicked list, i.e. the text in the div class "title", i.e. (M1 or M2....)
The second task is:
On click of the div class "button option-vertical" it should give me another alert containing the class title as in task above and additionally the img src value from the div class "image", for example: (http://lorempixel.com/100/100)
When showing the alert from the second task, the alert from the first task should not be shown and vice versa. Please all without jQuery, only JavaScript.
With the JavaScript I tried above, a click on the list item doesn't give me any alert message.
The getElementsByClassName()|getElementsByTagName method returns a collection of all elements in the document with the specified class|tag name, as a NodeList object.
The NodeList object represents a collection of nodes. The nodes can be accessed by index numbers. The index starts at 0.
var li = document.getElementById("myList").getElementsByTagName("li"),
len = li.length,
i;
for (i = 0; i < len; i += 1) {
li[i].onclick = function() {
//Li only has one child with class "title"
alert(this.getElementsByClassName("title")[0].innerHTML);
}
}

Wrapping an anchor tag around dynamically generated divs

I have a div that generates multiple elements inside it:
<div class="lists">
<?php for($i=0;$i<6;$i++) { ?>
<div class="list history[[$i]]" id="history[[$i]]">
<div class="info">
<div class="picture monophoto">
<div class="text">BO</div>
<div class="img" style="background-image: url();"></div>
</div>
<div class="right">
<div class="lineone">John Smith</div>
<div class="linetwo">Daily Essentials</div>
</div>
</div>
<div class="boxes">
<div class="left">
<div class="box box1"></div>
</div>
<div class="right">
<div class="box box2"></div>
<div class="box box3"></div>
</div>
</div>
<a class="cbutton whiteonblack">VIEW LIST<!--SEE <span class="owner">JOHN'S</span>--></a>
</div>
<?php } ?>
</div>
I am trying to wrap the following div with an anchor tag so it links:
<div class="boxes"> </div>
Using jQuery I am trying to wrap this using jQuery that is part of a loop:
for(var i = 0; i < listLength; i++){
for(var y = 0; y < result.history[i].length; y++){
var history = document.getElementById('history' + i);
history.querySelector('.boxes').wrap('');
}
}
This is not resulting in an anchor tag showing up at all on the DOM. What am I doing wrong and how do I fix it?
Edit: I clarified which div
Edit 2: To clarify, each of the links are actually going to be dynamically generated. I am just using google.com as an example. So effecting all of a specific class wont work.
querySelector returns a NodeList object, wrap() is a jquery function, they won't work together, try this :
for(var i = 0; i < listLength; i++){
for(var y = 0; y < result.history[i].length; y++){
$('#history' + i).find('.boxes').first().wrap('');
}
}
You can do this in a single line by selecting the .list .boxes elements:
$('.lists .boxes').wrap('')
Example fiddle
Note that this will only work if you are using HTML5, otherwise it would be invalid to have a block level element (a div) inside an inline element (the a).

How to alter the value of a div on each click

I have got a task to create a puzzle.I have 12 div.Each div contains different value up to 12.I have button like start now.I want to change my div value on each click of the start now button.
DEMO
<div id="container">
<div class="finder">
<div class="block1"> <div id="one"><h1>1</h1></div>
</div>
<div class="block1"> <div id="two"><h1>2</h1></div>
</div>
<div class="block1"> <div id="three"><h1>3</h1></div>
</div>
<div class="block1"> <div id="four"><h1>4</h1></div>
</div>
<div class="block1"> <div id="five"><h1>5</h1></div>
</div>
<div class="block1"> <div id="six"><h1>6</h1></div>
</div>
<div class="block1"> <div id="seven"><h1>7</h1></div>
</div>
<div class="block1"> <div id="eight"><h1>8</h1></div>
</div>
<div class="block1"> <div id="nine"><h1>9</h1></div>
</div>
<div class="block1"> <div id="ten"><h1>10</h1></div>
</div>
<div class="block1"> <div id="eleven"><h1>11</h1></div>
</div>
<div class="block1"> <div id="twelve"><h1>12</h1></div>
</div>
</div>
<div class="button">
<div id="startButton">
<button>Start</button>
</div>
</div>
</div>
js is
$(".finder").css('display','none');
$("#startButton").click(function () {
$(".finder").css('display','block');
});
var myDiv;
$(".block1 div").on('click', function(){myDiv = $(this)});
$(".block1 div").click(function () {
if(myDiv.text() < 12)
{
myDiv.text(parseInt(myDiv.text())+1);
}
if(myDiv.text() > 12)
{
myDiv.text(1);
myDiv.text(parseInt(myDiv.text())+1);
}
});
How can i change the values?
I have provided a solution below. One of the key takeaways you should get from it, is that when an event handler is used this will be assigned the element the event was trigger on within the bound function.
To Fill the boxes with random numbers use this code
$(function() {
//Array of values
var values = [1,2,3,4,5,6,7,8,9,10,11,12];
$( "input[type=submit], button" )
.button()
.click(function( event ) {
event.preventDefault();
});
$(".finder").css('display','none');
$("#startButton").click(function () {
var tmpValues = values.slice(); //copy array
$(".block1 div h1").each(function(){
var r = Math.floor(Math.random()*tmpValues.length);
//assign html to random array value that gets removed from array
$(this).html(tmpValues.splice(r,1));
});
$(".finder").css('display','block');
});
$(".block1 div").click(function () {
//Instead of setting myDiv use $(this) which will refer to the div
//We can grab the value of the H1 within the div using a scoped selector
var value = parseInt($("h1",this).html());
//Set the html of the clicked div
//When setting the html we must include new value in h1 to maintain style
//Ternary expression tidies up the logic, not sure why it sets to to 2 though?
$(this).html("<h1>" + ((value > 12) ? 2: value+1) + "</h1>");
});
});
Working Example http://jsfiddle.net/W55xc/3/
I didnt quite get the question, but I guess you want to generate random numbers for the div's, right? Use Math.random()
$(".block1 div").each(function() {
$(this).children('h1').text(Math.floor((Math.random() * 12) + 1)); // Generate a random number <-> [1, 12]
}

Categories

Resources