I'm trying to add some extra divs to the build-in blogs "read more" links. I've managed to add all the necessary div but I'm struggling to move the text from where it is into another div. I've managed to move it using:
'''jQuery(".readmore").detach().appendTo('.js-add-btn-assets');'''
But instead of moving the one .readmore element to the .js-add-btn-assets. Its making copies of all of the Read More Links on the page and putting them all under the .js-add-btn-assets so I essentially have 4 .readmore elements for every Read More link.
enter image description here
How do I change this so the .readmore class is only moving to the .js-add-btn-assets within its respected parent class instead of all classes on the page?
Like this:
enter image description here
Here all the code I'm currently using
<span class="more-link">
<a href="#" class="readmore">Continue reading
<span class="screen-reader-text">Blog Template</span>
</a>
</span>
var AddButtonWrap = document.querySelectorAll(".more-link");
for (i = 0; i < AddButtonWrap.length; i++) {
AddButtonWrap[i].classList.add("dbtb-button-wrap add-dbtb-button-div");
}
var SelectButtonDiv = document.querySelectorAll(".add-dbtb-button-div"); {
for (i = 0; i < SelectButtonDiv.length; i++) {
var dbtbBtnDiv = document.createElement('div');
dbtbBtnDiv.className = 'dbtb-button js-add-btn-assets';
SelectButtonDiv[i].appendChild(dbtbBtnDiv);
}
}
jQuery(".readmore").detach().appendTo('.js-add-btn-assets');
Do the moves in a third loop.
Something like below should work (untested)
First detach, then Append.
for (i = 0; i < AddButtonWrap.length; i++)
{
var readMore = jQuery(AddButtonWrap[i]).find(".readmore").detach();
readMore.appendTo(jQuery(AddButtonWrap[i]).find(".js-add-btn-assets"));
}
Related
I'm building a IT website and I'm using an accordion to display my clients services. One clicks on the accordion and it expands or contracts giving a description of that service. I want to add a read more / read less text that changes depending on whether or not the accordion is open or closed (which is done using the is-active class. I can't change the innerHTML of the Read More text because it is the child element of the "accordion is-active" article.
I've looked at many solutions and they don't seem to address the problem I'm facing because I need to access the child class of an element only IF that element has both the "accordion" and "is-active" classes. I've tried assigning the Read More tag with class = "readSwitch" id = "readSwitch" to a variable and changing that variables html e.g. z.innerHTML = "Read Less" but z is a copy of the y.getElementsByClass("readSwitch") not the actual element. How do I directly access the "readSwitch" class for elements that contain both "accordion is-active" classes?
JavaScript
function readToggle() {
var x = document.getElementById("accordions");
var y = x.getElementsByClassName("accordion is-active");
var i;
for (i = 0; i < y.length; i++) {
var z = y[i].getElementsByClassName("readSwitch");
z.innerHTML = "Read Less";
console.log(z.innerHTML);
}
}
HTML
<section class="accordions" id="accordions">
<article class="accordion is-active">
<div class="accordion-header toggle" onclick="readToggle()">
<p>
Custom Built Computers
</p>
<p style="font-size:10px" class="readSwitch"
id="readSwitch">
Read More
</p>
</div>
<div class="accordion-body">
<div class="accordion-content">
blah blah blah
</div>
</div>
</article>
</section>
The problem is z is a copy of y so changing it doesn't update the DOM. However when I try to directly access y's inner HTML using something like y[i].getElementsByClassName("readSwitch").innerHTML = "Read Less"; I get an error "TypeError: y.getElementsByClassName is not a function. (In 'y.getElementsByClassName("readSwitch")', 'y.getElementsByClassName' is undefined)" . Are there any ways to directly modify y's child classes innerHTML using something like y.readSwitch.innerHTML = "Read Less"?
EDIT SOLVED!!! :
Thanks to jonathan Heindl i was able to figure it out. I've been struggling with this stupid thing for 3 days and couldn't find any solutions on the internet so I'm posting my Javascript solution for the read more read less toggle here for others. This solution works with the HTML above.
document.onclick = function () {
//variables for accordions with is-active
var x = document.getElementById("accordions");
var y = x.getElementsByClassName("accordion is-active");
//variables for accordions with just accordion class, exclude those with "is-active"
var noless = document.querySelectorAll('article.accordion:not(.is-active)');
//Update all accordions with is-active to read less
var i;
for (i = 0; i < y.length; i++) {
y[i].getElementsByClassName("readSwitch")[0].innerHTML = "Read Less ↑";
}
//update accordions without is-active class to read more
var w;
for (w = 0; w < noless.length; w++) {
noless[w].getElementsByClassName("readSwitch")[0].innerHTML = "Read More ↓";
}
}
getElementsByClassName returns an array of elements
so when you want to reference the object itself you need to add the index afterwards:
y[i].getElementsByClassName("readSwitch")[0].innerHTML
PS: When editing the text of a node it is recommended to use .textContent = "Read LEss" otherwise you will overwrite all the childElements of said node
Bsp:
let x = document.getElementById("accordions");
let y = x.getElementsByClassName("accordion is-active");//maybe x.children depending on the structure
for (let i = 0; i < y.length; i++) {
let z = y[i].getElementsByClassName("readSwitch")[0];
z.textContent= "Read Less";
console.log(z.textContent);
}
I have several html pages and each one has a varying number of buttons that appear based on the page's content.
In just Javascript (since I don't use jquery), I am trying to have the same few lines of code apply to the respective button that was clicked, with the exception that the id tag has to be 'concatenated' into a variable based on the respective button that was clicked.
I saw other solutions on here that cycled through the elements of the class (in this case the "zoom_buttonClass"). However, when I attempt this, regardless of number of buttons on the page or which button was clicked, it is always the LAST button in the list that seems to be the one seen as clicked.
I need to always check if buttons are clicked, but how do I apply the actions based on the ACTUAL button that was clicked?
My HTML and JS code snippets are below:
Thanks in advance.
HTML code:
<div class="modalClass" id="myModalID">
<span class="closeModalClass" aria-label="Close Photo Enlargement Modal Box">×</span>
<img class="modal_contentClass" id="modalEnlargementID">
</div>
<div id="captionID"></div>
JS code:
for (var i = 0;i < document.getElementsByClassName("zoom_buttonClass").length;i++){
document.getElementsByClassName("zoom_buttonClass")[i].addEventListener('click', myFunction
(var attribute = this.getAttribute("id");
var photoIDstring = "photo"+counterX+"ID";
document.getElementById('myModalID').style.display = "block";
document.getElementById('captionID').style.display = "block";
document.getElementById("modalEnlargementID").src = document.getElementById(photoIDstring).src;
captionText.innerText = document.getElementById(photoIDstring).alt;
), false);
};
Well, I started again and I think I may have hit upon a solution. It seems to work.
var captionText = document.getElementById("captionID");
var howManyButtons = document.getElementsByClassName("zoom_buttonClass").length;
var buttonCollection = document.getElementsByClassName("zoom_buttonClass");
for (let i=0; i < howManyButtons; i++) {
buttonCollection[i].onclick = function() {
let photoIDstring = "photo"+(i+1)+"ID";
document.getElementById('myModalID').style.display = "block";
document.getElementById('captionID').style.display = "block";
document.getElementById("modalEnlargementID").src = document.getElementById(photoIDstring).src;
captionText.innerText = document.getElementById(photoIDstring).alt;
}
}
Using this script to open 1 of multiple menus based on the target ID. The class is .dropdownDiv. The script starts by removing the "show" class from any .dropdownDiv's, then allowing the user to toggle the targeted .dropdownDiv.
The issue is, the .remove and .toggle don't appear to work together. They work individually just fine. I can toggle one div show-unshow all day long, but clicking the other buttons will not control it. I can do the reverse and have one button remove the div from another, but then the targeting button will not remove it's own div.
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function(event) {
var divs = document.querySelectorAll('.navButton');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', showDropDown);
}
});
function showDropDown() {
//un-show all dropdowns
var containers = document.querySelectorAll('.dropdownDiv');
for (var i = 0; i < containers.length; i++) {
containers[i].classList.remove('show');
}
// show targeted dropdown only
var d = document.getElementById(event.target.dataset.target);
d.classList.toggle("show");
console.log(d);
}
</script>
a trivial way to toggle something, that is using a flag and flip it each time you hit an action, so you can do something like so:
if(a)
{//something to do}
else
{// another action to do}
a = ! a;
so, you can remove the clicked drop down instead of removing all drop down classes.
I am trying to randomize the hero content of a home page. I have this simple code, but it affects all the divs on the page, and I only want it to affect a few.
var elems = $("div");
if (elems.length) {
var keep = Math.floor(Math.random() * elems.length);
for (var i = 0; i < elems.length; ++i) {
if (i !== keep) {
$(elems[i]).hide();
}
}
}
Here is my html:
<div id="hero1">One</div>
<div id="hero2">Two</div>
<div id="hero3">Three</div>
<div id="constant">This content does not rotate.</div>
There is another caveat to this, I need it to work within a crappy CMS that strips out my class tags. So it has to be a solution that identifies the divs based on id.
How about
var elems = $('div').not('#constant')
?
The not function removes matching elements from the set it's called on.
I am adding a simple toggle button through Javascript. Then I want to add three span tags inside it.
So, I am creating variable of span and trying to append it inside our very own basic FOR loop. Iteration count is 3 times.
Here's my basic code below. Please let me know what has been missing or misplaced that my span tag refuses to append more than once. I checked this in the inspect mode.
Then, I brought up console tab and the value of i was 3. Append is meant to append and NOT replace the element. Right ?
var $navbar_header = $('<div class="navbar-header"></div>');
var $button = $("<button></button>");
var $span = $('<span class="icon-bar"></span>');
for (var i = 0; i < 3; i++) {
$button.append($span);
}
$button.addClass('navbar-toggle');
$navbar_header.append($button);
$("#menu").append($navbar_header);
Here's a link to fiddle.
The DOM is a tree, where any element points to its parent (see parentNode). An element can have only one location. So when you append an element, you're removing it from its precedent location.
The solution here is either to clone the element:
$button.append($span.clone());
or just to create it in the loop:
for (var i = 0; i < 3; i++) {
$button.append('<span class="icon-bar"></span>');
}