I am working with a WordPress theme and this is the functionality that I am trying to achieve:
225-1077
It sure is easily done with HTML but I am really not good with WordPress and this theme I got has so much files in it that it's hard to find where I should edit however, the theme allows you to add custom JS so I was wondering if the functionality above can be done with JS.
Any help is very much appreciated!
Very simply, it is possible, but that doesn't mean it's a good idea. JS support across mobile phones is not consistent, and not even always enabled, which would mean that these people would never see your link.
To create the link with JS is simple :
var cta = document.createElement('a');
cta.href = 'tel:12341234';
cta.setAttribute('class', 'my cta classes');
cta.appendChild(document.createTextNode('1234-1234'));
and then you need to put it somewhere on the page. If we have <div>s all over the place with a specific class, we can use that:
This is our HTML
<div class="target-cta">This div should receive a link</div>
<div class=""> this one shouldn't </div>
<div class="target-cta"> should have one here </div>
<div class=""> ...though not here</div>
<div class="target-cta">and finally, one here:</div>
and our JS to insert the links should loop through these elements, creating the links and inserting them as it goes:
var targets = document.getElementsByClassName('target-cta'),
target,
i,
cta; // Call To Action
for (i = 0; i < targets.length; i++) {
target = targets[i];
cta = document.createElement('a');
cta.href = 'tel:12341234';
cta.setAttribute('class', 'my cta classes');
cta.appendChild(document.createTextNode('1234-1234'));
target.appendChild(cta);
};
var targets = document.getElementsByClassName('target-cta'),
target, i, cta;
for (i = 0; i < targets.length; i++) {
target = targets[i];
cta = document.createElement('a');
cta.href = 'tel:12341234';
cta.setAttribute('class', 'my cta classes');
cta.appendChild(document.createTextNode('1234-1234'));
target.appendChild(cta);
};
<div class="target-cta">This div should receive a link</div>
<div class=""> this one shouldn't </div>
<div class="target-cta"> should have one here </div>
<div class=""> ...though not here</div>
<div class="target-cta">and finally, one here:</div>
Related
I'm a beginner in JS, I made a carousel with a data attribute and I want to display it and it have to change when we go the next or previous slider.
For the moment I made a small script and I can display only the data attribute of the first slider
HTML :
<div class="carousel2partsUp slick-initialized slick-slider">
<div class="el-carousel2parts slick-slide slick-current slick-active" data-legend="legend1">
{# Content #}
</div>
<div class="el-carousel2parts slick-slide" data-legend="legend2">{# Content #}</div>
<div class="el-carousel2parts slick-slide" data-legend="legend3">{# Content #}</div>
<div class="el-carousel2parts slick-slide" data-legend="legend4">{# Content #}</div>
</div>
<span id="legend"></span>
JS :
<script>
var carousel = document.querySelector('.el-carousel2parts');
var spanLegend = document.querySelector('#legend');
var dataLegend = carousel.dataset.legend;
spanLegend.innerHTML = dataLegend;
</script>
How can I improve my code to display the data attribute according to the good slider ?
should I make a loop ? or something with a event click ?
Thanks for answer
If you have only one active slide you can do it without loop:
var carousel = document.querySelector('.el-carousel2parts');
var spanLegend = document.querySelector('#legend');
// Find which is active and get its attribute:
var currentSlide = document.querySelector('.slick-active');
var currentData = currentSlide.getAttribute('data-legend');
var dataLegend = currentData;
spanLegend.innerHTML = dataLegend;
I do not see you full code, so just a guess.You can make onClick function and call new two lines of code. Put onClick on button which updates the slides. Imagine we have several buttons that scroll through the slides.
<button class="turn">Left</button>
<button class="turn">Right</button>
In that case we can have something like this:
var spanLegend = document.querySelector('#legend');
var btnsTurn = document.querySelectorAll('.turn');
btnsTurn.forEach(item => {
item.addEventListener("click", () => {
var currentSlide = document.querySelector('.slick-active');
var currentData = currentSlide.getAttribute('data-legend');
spanLegend.innerHTML = currentData;
});
})
But I assume that you already have a function which add Class 'slick-active' and remove it from another slide. So you can just add some code inside it without new forEach for the same buttons.
PS You take an Attribute from your DOM which can be edited by any user. In general, be careful innerHTML is a dangerous function.
Hope this helps! Regards,
I'm using Elementor Pro for my photography website and i want to set custom links for each image in the gallery. By default, i can only set a global link which is the same for each image so that's not great.
In fact, i want to set a custom link which will redirect the user to the shop page of the specific image.
I found some code online (thanks to elementhow !) and it's really close to what i want, but i still need to change some things. The thing is a have to manually write all the links in an array and it's not convenient (close to 100 files and growing, if i change the order, i have to reorder the links, etc).
Here's the code i currently use :
<style>.e-gallery-item{cursor: pointer;} </style>
<script>
document.addEventListener('DOMContentLoaded', function () {
var filteredImages = document.querySelectorAll('.e-gallery-item');
//Edit the links HERE
var links = [
'https://www.mywebsiteurl.com/product/product-name1/',
'https://www.mywebsiteurl.com/product/product-name2/',
'https://www.mywebsiteurl.com/product/product-name3/',
'https://www.mywebsiteurl.com/product/product-name4/',
];
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function () {
location = links[i];
});
};
for (var i = 0; i < filteredImages.length; i++) {
_loope(i);
}
});
</script>
I would like to use an attribute value in the algorithm to generate the link automatically for each image. I have the process in my mind, but i don't know how to code this...
Here's the code of one image ,i can set what value i want in "alt".
<div class="e-gallery-image elementor-gallery-item__image e-gallery-image-loaded" data-thumbnail="......" data-width="1024" data-height="768" alt="product-name";"></div>
I would like to use the "alt" attribute to create a unique url for each file, with this format :
'https://www......com/product/product-name/'
"product-name' will take the value of the "alt" attribute of each image.
I tried to change this part of the code (replace "links[i]" by trying to get the attribute value using filteredImages[i].getAttributes) but without success...
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function () {
location = links[i];
});
};
Can someone give me some tips about how to do that ? I spend 2 years without coding so i'm a bit rusty...
I think this does what you'd like it to, as you have already done you can cycle through each image link using a class.
You can get the value of alt using the .attr() function and then replace the href value of the link.
DEMO
// Cycle through each image using common class
$(".e-gallery-image").each( function() {
// Get value of 'alt' for clicked item
alt = $(this).attr("alt");
// Update href value
$(this).attr("href", "https://www.mywebsiteurl.com/product/" + alt );
});
// Prove that its worked
$(".e-gallery-image").click( function() {
// Confirm all is correct
console.log($(this).attr("href"));
// Assign url to window
location.href = $(this).attr("href");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="e-gallery-image" href="test.com" alt="product1">Product 1</div>
<div class="e-gallery-image" href="test.com" alt="product2">Product 2</div>
<div class="e-gallery-image" href="test.com" alt="product3">Product 3</div>
<div class="e-gallery-image" href="test.com" alt="product4">Product 4</div>
<div class="e-gallery-image" href="test.com" alt="product5">Product 5</div>
In fact it was really simple. I tried to target a parent element and it worked ! If anyone is interested, here's the code i use :
document.addEventListener('DOMContentLoaded', function () {
var filteredImages = document.querySelectorAll('YOUR_SELECTOR');
var _loope = function _loope(i) {
filteredImages[i].addEventListener('click', function() {
location = "YOUR_WEBSITE_URL" + filteredImages[i].querySelector("YOUR_SELECTOR").getAttribute("alt");
});
};
for (var i = 0; i < filteredImages.length; i++) {
_loope(i);
}
});
So I have this HTML here generated by Wordpress. I want to select the DIVs seperately using JS. Is this possible? Can I maybe select them by the order on which JS finds them in my HTML?
I tried if something like this would be possible (By adding an index number) but I believe that is used only for the LI element. But you get the idea. The end result is to add a different classname to each div object using .className
var koffie = document.getElementsByClassName("g-gridstatistic-item-text2")[0];
var brain = document.getElementsByClassName("g-gridstatistic-item-text2")[1];
var tevred = document.getElementsByClassName("g-gridstatistic-item-text2")[2];
console.log(koffie);
console.log(brain);
console.log(tevred);
<div class="g-gridstatistic-wrapper g-gridstatistic-3cols">
<div class="g-gridstatistic-item">
<div class="g-gridstatistic-item-wrapper">
<div class="g-gridstatistic-item-text1 odometer" data-odometer-value="4"></div>
<div class="g-gridstatistic-item-text2">Kopjes koffie per dag</div>
</div>
</div>
<div class="g-gridstatistic-item">
<div class="g-gridstatistic-item-wrapper">
<div class="g-gridstatistic-item-text1 odometer" data-odometer-value="14"></div>
<div class="g-gridstatistic-item-text2">Brainstormsessies per week</div>
</div>
</div>
<div class="g-gridstatistic-item">
<div class="g-gridstatistic-item-wrapper">
<div class="g-gridstatistic-item-text1 odometer" data-odometer-value="12"></div>
<div class="g-gridstatistic-item-text2">Tevreden klanten</div>
</div>
Your JavaScript code is looking for DOM elements before it checks whether the DOM has even loaded. Try wrapping it in an event listener, like so:
JS
document.addEventListener('DOMContentLoaded', function () {
var koffie = document.getElementsByClassName("g-gridstatistic-item-text2")[0];
var brain = document.getElementsByClassName("g-gridstatistic-item-text2")[1];
var tevred = document.getElementsByClassName("g-gridstatistic-item-text2")[2];
//console.log(koffie);
//console.log(brain);
//console.log(tevred);
/* to evidence that targeting works: */
brain.classList.add('addedClass');
});
CSS
.addedClass {
font-size:22px;
color:red;
}
Full demo here:
https://jsbin.com/saxizeyabo/edit?html,css,js,console,output
simply like this
var yourVariableName = document.getElementsByClassName("g-gridstatistic-item-text2");
console.log(youVariableName[0]);
console.log(youVariableName[1]);
and so on like an array
document.querySelectorAll('.g-gridstatistic-item-text2').item(0);
https://developer.mozilla.org/de/docs/Web/API/Document/querySelectorAll
This way, you can just use CSS-Selectors
The below code should work.
var classes = document.getElementsByClassName('g-gridstatistic-item-text2');
for(var i=0; i<=classes.length; i++) {
var appendClass = 'your_class_name'+i;
classes[i].classList.add(appendClass);
}
I appreciate all the suggestions I've gotten so far-thank you!
I'll try to describe a bit better what I'm trying to do:
I want to switch a CSS class on the active (clicked on) tab item on a item (to make a highlight effect while its related content is showing).
The JS Fiddle http://jsfiddle.net/4YX5R/9/ from Vlad Nicula comes close to what I'm trying to achieve, however I can't get it to work in my code.
The tabs are linked to content which is shown on the page when the tab is clicked. This part is working fine. I just want to change the CSS style on the ContentLink items when its content is being shown.
I'd also like to keep the content for ContentLink1 visible when the page loads, as it is now in the code, and for ContentLink1 to have the CSS .infoTabActive class when the page loads. When the ContentLink tab is not clicked, it should have the .infoTab class.
This is what I have so far:
HTML:
<article class="grid-70 infoContainer">
<a class="infoTab" id="aTab" href="javascript:show('a')">ContentLink1</a>
<a class="infoTab" id="bTab" href="javascript:show('b')">ContentLink2</a>
<a class="infoTab" id="cTab" href="javascript:show('c')">ContentLink3</a>
<div id="a">
<p> Inhalt 1111111.</p></div>
<div id="b">
<p>Inhalt 222222222
</p></div>
<div id="c">
<p>Inhalt 33333333
<7p></div>
</article>
Javascript:
window.onload = function () {
document.getElementById("a").style.display = "block";
}
function show(i) {
document.getElementById('a').style.display ="none";
document.getElementById('b').style.display ="none";
document.getElementById('c').style.display ="none";
document.getElementById(i).style.display ="block";
}
basic CSS for tab styles I want to apply:
.infoTab {
text-decoration:none;
color:red;
}
.infoTabActive {
text-decoration:none;
color:yellow;
}
Any pointers would be appreciated!
You can switch the classes simply bu using class property on DOM element.
To replace the existing class use
document.getElementById("Element").className = "ClassName";
Similarly to add a new class to exisiting classes use
document.getElementById("Element").className += "ClassName";
Change show function to be like this:
function show(i) {
document.getElementById('a').style.display ="none";
document.getElementById('a').className ="";
document.getElementById('b').style.display ="none";
document.getElementById('b').className ="";
document.getElementById('c').style.display ="none";
document.getElementById('c').className ="";
document.getElementById(i).style.display ="block";
document.getElementById(i).className ="selected";
}
I changed a little bit your code to make it suits your needs.
First, change the onload part in the Fiddle, by no wrap.
Then, you need to hide each elements at start like this :
window.onload = function () {
var list = document.getElementsByClassName("hide");
for (var i = 0; i < list.length; i++) {
list[i].style.display = "none";
}
}
I added an hide class to achieve it. Your show function works well then.
I would do it like this:
add a class called .show which sets the element to display block.
then toggle the classname.
Here's a JSFiddle
And here's an example:
HTML
<article class="grid-70 infoContainer">
<a class="infoTab" id="aTab" href="javascript:show('a')">Werbetexte</a>
<a class="infoTab" id="bTab" href="javascript:show('b')">Lektorate</a>
<a class="infoTab" id="cTab" href="javascript:show('c')">Übersetzung</a>
<div class="box" id="a">
<div class="col1"> <p>Inhalt 1111111.</p></div>
</div>
<div class="box" id="b">
Inhalt 222222222
</div>
<div class="box" id="c">
Inhalt 33333333
</div>
</article>
JavaScript
window.onload = function () {
show('a');
}
function show(elm) {
// get a list of all the boxes with class name box
var shown = document.getElementsByClassName('box');
// loop through the boxes
for( var i=0; i<shown.length; i++ )
{
// set the classname to box (removing the 'show')
shown[i].className = 'box';
}
// change the classname to box show for the element that was clicked
document.getElementById( elm ).className = 'box show';
}
CSS
.box {
display:none;
}
.box.show {
display:block;
}
Simplest way I could think of is this : http://jsfiddle.net/4YX5R/9/
Basically you don't want to listen to each element. If you do that you will have issues with new tabs. If you listen to the parent element like in my example you can add new tabs without having to write any more javascript code.
<a class="infoTab" data-target='a' id="aTab">Werbetexte</a>
Each tab button has a data-target attribute that will describe the div to show as the tab content. Hiding and showing content will be done via css, not style - which is a recommended best practice -.
tabs.addEventListener("click", function ( ev ) {
var childTarget = ev.originalTarget || ev.toElement;
...
}
When a tab is clicked, we check to see which element was clicked from the event listener on the parent, and then get the data-target from it. We use this as a id selector to show the new tab. We also need a reference to the old tab that was active, so we can hide it.
The logic is not that complicated, and with this you can have any number of tabs. I would recommend jQuery for this, since the event delegation might not work in all browsers with the current code.
I hope this helps :)
I'm trying to implement multiple scrollbars with the plugin Tinyscrollabr.js
http://baijs.nl/tinyscrollbar/
To implement the scrollbars, i use a function scrollify like in this article :
http://www.eccesignum.org/blog/making-tinyscrollbarjs-easier-to-implement
HTML :
<ul id="myList">
<li id="scrollbar1" class="col">
<h2>Title 01</h2>
<div class="scrollBox"><!--Scrollable Content here--></div>
</li>
<li id="scrollbar2 class="col">
<h2>Title 02</h2>
<div class="scrollBox"><!--Scrollable Content here--></div>
</li>
<li id="scrollbar3 class="col">
<h2>Title 03</h2>
<div class="scrollBox"><!--Scrollable Content here--></div>
</li>
</ul>
Javascript :
function scrollify(element,options) { // '#element', {list:of,key:values}
var opt = options || {}
$(element).children().wrapAll('<div class="viewport"><div class="overview"></div></div>');
$(element).prepend('<div class="scrollbar"><div class="track"><div class="thumb"><div class="end"></div></div></div></div>');
$(element).tinyscrollbar(options);}
$scrollbar1 = $('#scrollbar1 .scrollBox') ;
$scrollbar2 = $('#scrollbar2 .scrollBox');
$scrollbar3 = $('#scrollbar3 .scrollBox');
$scrollbar4 = $('#scrollbar4 .scrollBox');
$(function() {
scrollify($scrollbar1);
scrollify($scrollbar2);
scrollify($scrollbar3);
scrollify($scrollbar4);
})
I would to make this more simple.
For example, i would to be able to make this :
$(function() {
scrollify('.scrollBox');
})
But tinyscrollbar need an id. With a class, it's load the first scrollbar and not the others. Firebug return this error message "f.obj[0] is undefined"
Sorry if my question is stupid, but how can I do for applying tinyscrollbar to a list of elements with a class ?
And then, after some actions how to update all this scrollbars with the function $allScrollbars.tinyscrollbar_update();
Thanks for help, I'm just beginning with javascript and i'm trying to learn.
I would count the number of elements with the class:
var scrollCount = $(".scrollbox").size();
Then use an iterating loop to call each of your IDs:
for (i=0; i<5; i++) {
scrollify($('#scrollbar' + i));
}
Also I would recommend using DIVs instead of the list setup you have, use the example from the link you shared as a starting point :)
Thanks KneeSkrap3r for your answer. It's a good solution to make this but i'm trying to do something in the case i' don't know the numbers of element to scroll.
I think I've found with something like this (it's a part from the first jquery plugin i'm trying to do ) where $el is all elemnts with the class"scrollbox".
$el.each(function(index)
{
var $scrolls = $(this);
function scrollify(element,options)
{ // '#element', {list:of,key:values}
var opt = options || {}
$(element).children().wrapAll('<div class="viewport"><div class="overview"></div></div>');
$(element).prepend('<div class="scrollbar"><div class="track"><div class="thumb"><div class="end"></div></div></div></div>');
$(element).tinyscrollbar(options);
}
scrollify($scrolls);
// Update heights
$(window).resize(function()
{ $scrolls.tinyscrollbar_update('relative');
});
})
Like this, it's seems to work but i don't know if i'm using good practice of javascript.
For the Html markup, I told the li elements for div, it's better for the semantic.
Thanks for tips ;-)