Toggle classes onlick from multiple instances - javascript

So I ran into a problem regarding my toggle function. In my current case I would like to be able to turn parts of the web-based interface on and off (display:none and block). I got it to work from one of the windows but the snag I hit was when I added multiple calls to the same functions. I reverted from using getElementById and used getElementsByClass instead. This caused no problems as far as I know of. When I added the second menu however things started to malfunction.
I'll paste my code and a jsFiddle down below.
My goal is to make the onclick on the <li> toggle the other <li> and toggle the map/cesium at the same time.
HTML
<div id="map">
<nav id="primary_nav_wrap">
<ul>
<li>=
<ul>
<li><a class="buttonMap" href="#" onclick="toggleMap('none')">Toggle Map</a></li>
<li><a class="buttonMap2" href="#" onclick="toggleMap('block')">Toggle Map</a></li>
<li><a class="buttonCesium" href="#" onclick="toggleCesium('none')">Toggle Cesium</a></li>
<li><a class="buttonCesium2" href="#" onclick="toggleCesium('none')">Toggle Cesium</a></li>
</ul>
</li>
</ul>
</nav>
</div>
<div id="cesium">
<nav id="primary_nav_wrap">
<ul>
<li>=
<ul>
<li><a class="buttonMap" href="#" onclick="toggleMap('none')">Toggle Map</a></li>
<li><a class="buttonMap2" href="#" onclick="toggleMap('block')">Toggle Map</a></li>
<li><a class="buttonCesium" href="#" onclick="toggleCesium('none')">Toggle Cesium</a></li>
<li><a class="buttonCesium2" href="#" onclick="toggleCesium('block')">Toggle Cesium</a></li>
</ul>
</li>
</ul>
</nav>
CSS (minimal but so JsFiddle gets the point across)
#map{
height:100px;
width:100px;
background-color:red;
}
#cesium{
height:100px;
width:100px;
background-color:blue;
}
JS
function toggleMap(display) {
var elem = document.getElementById("map");
var buttonMap = document.getElementsByClassName("buttonMap");
elem.style.display = display;
buttonMap.style.display = display;
if (buttonMap.style.display === 'none'){
buttonMap2.style.display = 'block';
}
else if (buttonMap.style.display === 'block'){
buttonMap2.style.display = 'none';
}
};
function toggleCesium(display) {
var elem = document.getElementById("cesium");
var buttonCesium = document.getElementsByClassName("buttonCesium");
elem.style.display = display;
buttonCesium.style.display = display;
if (buttonCesium.style.display === 'none'){
buttonCesium2.style.display = 'block';
}
else if (buttonCesium.style.display === 'block'){
buttonCesium2.style.display = 'none';
}
};
In the JsFiddle, the colored blocks should disappear.
Any help is appreciated!
(PS! We can safely assume users will be using up-to-date browsers)

https://jsfiddle.net/rz4wu4qd/18/
Somewhat working solution as mentioned in comments.
getElementsByClassName returns an array, so you need to iterate through it, for example with a for loop.

Related

How do I change background color of each list item with JavaScript?

I'm struggling trying to change the background color of each item of a list when I move the mouse over it.
I have a list more or less like this:
<ul id="ul_menu">
<li>
Text
</li>
<li>
Text
</li>
<li>
Text
</li>
</ul>
I'm trying to do it with Javascript as the following:
var list = document.getElementByID("ul_menu");
var listItems = ul.getElementsByTagName("li");
function mouseOver() {
for (li in listItems){
li.style.backgroundColor = "yellow";
}
}
function mouseOut() {
for (li in listItems){
li.style.backgroundColor = null;
}
}
I'm generating this HTML code dynamically with XSLT from a XML file, so I'm unable to choose an specific ID for each list item.
Could you help me?
Thanks all.
If I'm reading this correctly (please let me know if I'm not), you just want to change the background color of the text when the mouse pointer hovers over a list item, correct?
If so, you can do this really easily with a little CSS:
.yellow:hover {
background-color: yellow;
}
<ul>
<li>
Text
</li>
<li>
Text
</li>
<li>
Text
</li>
</ul>
If you really want to use JavaScript, it's still possible, but you'll need to specify the width of the highlighted area. Try something like this:
function yellowa1(x) {
a1.style.backgroundColor = "yellow";
a1.style.width = "5px";
}
function yellowb2(x) {
b2.style.backgroundColor = "yellow"
b2.style.width = "5px";
}
function yellowc3(x) {
c3.style.backgroundColor = "yellow"
c3.style.width = "5px";
}
function nulla1(x) {
a1.style.backgroundColor = "transparent";
}
function nullb2(x) {
b2.style.backgroundColor = "transparent";
}
function nullc3(x) {
c3.style.backgroundColor = "transparent";
}
<body>
<ul>
<li onmouseover="yellowa1(this)" onmouseout="nulla1(this)" id="a1">a</li>
<li onmouseover="yellowb2(this)" onmouseout="nullb2(this)" id="b2">b</li>
<li onmouseover="yellowc3(this)" onmouseout="nullc3(this)" id="c3">c</li>
</ul>
</body>
Also, for future reference, be aware that an id is used to identify one element, whereas a class can be used to identify several. As well, Only the I in the Id part of the DOM method .getElementById should be capitalized, not both letters. And make sure that your <ul> element is defined.
#ul_menu li:hover{
background-color: yellow;
}
//Try using just CSS to achieve the result if you don't mind
<ul id="ul_menu">
<li>
<a href="#ref" title="go to ref" id="menu_selector" >Text</a>
</li>
<li>
<a href="#ref" title="go to ref" id="menu_selector" >Text</a>
</li>
<li>
Text
</li>
</ul>

How to Animate Scroll to Top JavaScript

I have got 2 websites with the same function. It works on one of the websites, doesn't work on the other.
script.js:
function scrollToTop(){
var timerHandle = setInterval(function() {
if (document.body.scrollTop != 0 || document.documentElement.scrollTop != 0)
window.scrollBy(0,-50); else clearInterval(timerHandle); },10);
}
HTML
<ul class="footer-navigation">
<li><a class="back" id="backtoTop" onclick="scrollToTop();return false;"href="#">↑Back to Top</a></li>
<li><a class="home" href="#home">Home</a></li>
<li><a class="about" href="#about">About</a></li>
<li><a class="contact" href="#contact">Contact</a></li>
</ul>
It doesn't hit any error but it seems as though it is "counting". When I console.log it there's a number in the console next to the logged counting but function never executes.
Thanks
Try this:
function scrollToTop(){
window.scrollTo({top: 0, behavior: 'smooth'});
}
<div style="height: 150vh">
scroll down
</div>
<ul class="footer-navigation">
<li><a class="back" id="backtoTop" onclick="scrollToTop();return false;"href="#">↑Back to Top</a></li>
<li><a class="home" href="#home">Home</a></li>
<li><a class="about" href="#about">About</a></li>
<li><a class="contact" href="#contact">Contact</a></li>
</ul>
I would say that you shouldn't scroll via a setInterval but through requestAnimationFrame to avoid jankiness in the scroll. A simple solution to your problem would also to use CSS to make your scrolling smooth. However, this affects all scrolling.
function scrollToTop(){
window.scrollTo(0, 0);
}
html {
scroll-behavior: smooth;
}
<div style="height: 150vh">
scroll down
</div>
<ul class="footer-navigation">
<li><a class="back" id="backtoTop" onclick="scrollToTop()"href="#">↑Back to Top</a></li>
<li><a class="home" href="#home">Home</a></li>
<li><a class="about" href="#about">About</a></li>
<li><a class="contact" href="#contact">Contact</a></li>
</ul>
More about requestforanimationframe:
https://stackoverflow.com/a/46072227/5526624
To complete the previous answers, we can use the following code to the CSS so as not to forget accessibility ;
#media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}
Indeed, there are people who have disorders of the vestibular systems and who have configured their browser to reduce animations and movements
(function($){
'use strcit';
$.ScrollUpToTop = function(options){
// Default options
options = $.extend({}, options);
// Variables
var $btnScroll = $("<button id=\"ScrollUpToTop\">^</button>").hide();
var $body = $(document.body);
// insert scroll up to top button
$($body).append($btnScroll);
// attach click event on button
$($btnScroll).click(function(e){
e.preventDefault();
$($body).animate(
{scrollTop:0},
800
);
});
$(window).scroll(function(){
if( $(window).scrollTop() > 0) {
$($btnScroll).fadeIn();
} else {
$($btnScroll).fadeOut();
}
});
};
$.ScrollUpToTop();
})(jQuery);
Please follow this link.
https://www.jqueryscript.net/demo/Super-Simple-Scroll-Up-To-Top-Plugin-with-jQuery/
and you can also get reference from using source.
view-source:https://www.jqueryscript.net/demo/Super-Simple-Scroll-Up-To-Top-Plugin-with-jQuery/
use this bro in pure javascript no css needed : window.scrollTo({ top: 0, behavior: "smooth" })

Disable dropdown item with CSS or Javascript

I need to disable, deactivate or at least hide a dropdown item called Private request and I can only use CSS or Javascript to do so.
When I inspect the dropdown item it has the class a.js-dropdown-list. But every item in my dropdown has this class. So I can't just use {display: none;} because it will hide all options. Is there no more specific ID for every item in the drop down or can I deactivate items with Javascript?
Drop Down looks like this:
Here the code (1st block is for the picker field, 2nd for the drop-down menue):
<div id="js-organization-picker">
<sd-select class="js-share-with-organisation-picker is-private" data-type="link" data-id="customfield_10203" data-value="38" data-options="[{"label":"Private request","styleClass":"is-private","icon":"locked"},{"label":"Share with Testorganisation","value":38,"icon":"unlocked"}]" resolved="">
<a id="js-customfield_10203-dropdown-trigger" class="aui-dropdown2-trigger aui-button aui-button-link js-trigger customfield_10203-trigger select-dropdown-trigger aui-alignment-target aui-alignment-element-attached-top aui-alignment-element-attached-left aui-alignment-target-attached-bottom aui-alignment-target-attached-left active aui-dropdown2-active aui-alignment-enabled" aria-controls="customfield_10203-dropdown" aria-haspopup="true" role="button" tabindex="0" data-aui-trigger="" data-dropdown2-hide-location="js-customfield_10203-dropdown-container" resolved="" aria-expanded="true" href="#customfield_10203-dropdown">
<span class="aui-icon aui-icon-small aui-iconfont-locked">
: : before
</span> Private request
: : after
</a>
<input name="customfield_10203" type="hidden" class="js-input" value="">
<div id="js-customfield_10203-dropdown-container" class="hidden"></div>
</sd-select>
</div>
<div id="customfield_10203-dropdown" class="aui-dropdown2 filter-dropdown aui-style-default js-filter-dropdown select-dropdown aui-layer aui-alignment-element aui-alignment-side-bottom aui-alignment-snap-left aui-alignment-element-attached-top aui-alignment-element-attached-left aui-alignment-target-attached-bottom aui-alignment-target-attached-left aui-alignment-enabled" role="menu" aria-hidden="false" data-id="customfield_10203" resolved="" style="z-index: 3000; top: 0px; left: 0px; position: absolute; transform: translateX(602px) translateY(918px) translateZ(0px);" data-aui-alignment="bottom auto" data-aui-alignment-static="true">
<div role="application">
<ul class="aui-list">
<li>
<a class="js-dropdown-item " href="#">Private request</a>
</li>
<li></li>
<li>
<a class="js-dropdown-item " href="#" data-value="38">Share with Testorganisation</a>
</li>
<li></li>
</ul>
</div>
</div>
E.g. you could give the dropdown item ids to identify them. In HTML this would look like this: <p id="yourIdHere"></p>
You can access this item through Javascript using the document.getElementById() function like this: document.getElementById('yourIdHere').style.display = 'none';
If you can't edit the existing html code, youi have to get the element by it's name/value. This is a bit difficult. You have to iterate through all elements of that type and evaluate each name/value. If you have found the one, you was looking for, you can edit/hide it. You would do so (untested):
var elements = document.getElementsByTagName('div'); //div will be the name of the tag of your elements in the dropdown list
var length = elements.length;
for (var i=0, item; item = elements[i]; i++) {
if(item.value == "Private request") { //"Private request" is the name of the element we are looking for
item.style.display = 'none'; //Hide the element
}
}
You could loot trough all 'js-dropdown-items', check its innerText for 'Private request' and set its parentNodes display-property to 'none':
var list = document.getElementsByClassName('js-dropdown-item');
for(var i = 0; i < list.length; i++){
if(list[i].innerText === 'Private request') list[i].parentNode.style.display = 'none';
}
<ul class="aui-list">
<li>
<a class="js-dropdown-item " href="#">Private request</a>
</li>
<li></li>
<li>
<a class="js-dropdown-item " href="#" data-value="38">Share with Testorganisation</a>
</li>
<li></li>
</ul>
VannillaJS Solution document.querySelectorAll(".aui-list > li")[0].style.display = "none";
Welcome!
If I get you right there are plenty of elements with the same ID js-dropdown-list and you want to hide a specific one and there is no additional class for the element and you're not allowed to add specificity to it, let's say by adding of an additional class, you can do the following:
Grab all elements with this id by:
let elements = document.querySelectorAll('.js-dropdown-list'); // this is an array of these elements
let elementToHide = elements[n] // whene n is the number of that element
//hiding the element
elementToHide.style.display = 'none';
Hope that helps!
NOTE: I believe you will have to actually hide it OR use whatever you are using for this pseudo drop down (there was no reference in the question) to manage the disabled state if it provides that. Reference: https://www.w3.org/TR/2014/REC-html5-20141028/disabled-elements.html
Get the element by its text and then hide it. Might need the parent but this directly answers the question. Note this could all be wrapped in a function and then called from where you wish.
function HideByText(elId, findText) {
let group = document.getElementById(elId).getElementsByClassName('js-dropdown-item');
let found = Array.prototype.filter.call(group, function(el) {
return el.innerText === findText;
});
found.forEach(function(el) {
el.style.display = 'none';
});
return found;// in case you need the elements ref.
}
let foundFiltered = HideByText('customfield_10203-dropdown', 'Private request');
<div id="customfield_10203-dropdown" class="aui-dropdown2 filter-dropdown aui-style-default js-filter-dropdown select-dropdown aui-layer aui-alignment-element aui-alignment-side-bottom aui-alignment-snap-left aui-alignment-element-attached-top aui-alignment-element-attached-left aui-alignment-target-attached-bottom aui-alignment-target-attached-left aui-alignment-enabled"
role="menu" aria-hidden="false" data-id="customfield_10203" resolved="" data-aui-alignment="bottom auto" data-aui-alignment-static="true">
<div role="application">
<ul class="aui-list">
<li>
<a class="js-dropdown-item " href="#">Private request</a>
</li>
<li></li>
<li>
<a class="js-dropdown-item " href="#" data-value="38">Share with Testorganisation</a>
</li>
<li></li>
</ul>
</div>
</div>
Alternate for parent would be:
Change el.style.display = 'none'; to
if (node.parentElement) {
el.parentElement.style.display = 'none';
}
Have you tried using CSS? Not an ideal solution, but it might be better than using JS for this.
#js-organization-picker + .aui-dropdown2 .aui-list li:first-child {
display: none;
}
If you need to hide the first 2 elements, you could do something like:
#js-organization-picker + .aui-dropdown2 .aui-list li:first-child,
#js-organization-picker + .aui-dropdown2 .aui-list li:first-child + li {
display: none;
}

Displaying pictures in html

I am learning about the DOM and incorporating Javascript in html files, I have tried this code that display and hide pictures using the event listener click. however, pictures don't seem to appear even no error is detected in the Chrome console.
NOTE: I only posted the concerned code, I omitted some of the HTML tags
<style>
.hide{
display: none;
}
</style>
<main>
<ul>
<li><a data-img="face" id="facebook" href="#"> Facebook </a></li>
<li><a data-img="insta" id="instagram" href="#"> Instagarm </a></li>
<li><a data-img="snap" id="snapchat" href="#"> Snapchat </a></li>
</ul>
<img class="hide" id="face" scr="https://cdn3.iconfinder.com/data/icons/free-social-icons/67/facebook_square-128.png">
<img class="hide" id="insta" scr="http://bikecleanse.com/wp-content/uploads/2016/10/Insta-Logo.png" >
<img class="hide" id="snap" scr="https://icon-icons.com/icons2/686/PNG/512/snapchat_snap_chat_icon_logo_social_app_red_icon-icons.com_61225.png">
</main>
<script type="text/javascript">
var face = document.getElementById('facebook');
var insta = document.getElementById('instagram');
var snap = document.getElementById('snapchat');
face.addEventListener("click", show);
insta.addEventListener("click", show);
snap.addEventListener("click", show);
function show() {
var picId = this.attributes["data-img"].value;
var pic = document.getElementById(picId);
if(pic.className === "hide"){
pic.className="";
} else {
pic.className= "hide";
}
}
</script>
First off, you issues is that it is src and not scr, so change that attribute and the images will show.
Second, I would recommend using classList with add, remove and contains. You could also use toggle to make your code even smaller like so:
<style>
.hide {
display: none;
}
</style>
<main>
<ul>
<li> <a data-img="face" id="facebook" href="#"> Facebook </a> </li>
<li> <a data-img="insta" id="instagram" href="#"> Instagarm </a> </li>
<li> <a data-img="snap" id="snapchat" href="#"> Snapchat </a> </li>
</ul>
<img class="hide" id="face" src="https://cdn3.iconfinder.com/data/icons/free-social-icons/67/facebook_square-128.png">
<img class="hide" id="insta" src="http://bikecleanse.com/wp-content/uploads/2016/10/Insta-Logo.png">
<img class="hide" id="snap" src="https://icon-icons.com/icons2/686/PNG/512/snapchat_snap_chat_icon_logo_social_app_red_icon-icons.com_61225.png">
</main>
<script type="text/javascript">
var face = document.getElementById('facebook');
var insta = document.getElementById('instagram');
var snap = document.getElementById('snapchat');
face.addEventListener("click", show);
insta.addEventListener("click", show);
snap.addEventListener("click", show);
function show() {
var picId = this.attributes["data-img"].value;
var pic = document.getElementById(picId);
pic.classList.toggle('hide', !pic.classList.contains('hide'))
}
</script>
I added the event input to your show function. I modified your show function like below. Check if this works for you:
function show(e) {
let picId = e.target.dataset.img;
let pic = document.getElementById(picId);
if(pic.classList.contains('hide'){
pic.classList.remove('hide');
}
else{
pic.classList.add('hide');
}
}

Check link click happen within a div

I would like the Javascript returning true when users click on the links within specific div
For example:
When users click on links in div having class="span1", it will return true
<div class="span1">
<h3>Title 3</h3>
<ul class="stages" dir="ltr">
<li><a href="http://www.example.com" >Example 1</a></li>
<li><a href="http://www.example.com" >Example 2</a></li>
</ul>
</div>
<div class="span2">
<h3>Title 4</h3>
<ul class="stages" dir="ltr">
<li><a href="http://www.example.com" >Example 1</a></li>
<li><a href="http://www.example.com" >Example 2</a></li>
</ul>
</div>
Thanks a lot!!
Simply use an if statement for .hasClass:
$("div").click(function(){
if($(this).hasClass("span1")){
alert("SPAN 1 CLICKED");
return true;
}
});
FIDDLE
UPDATE: I read your question too quick, here is a new fiddle which targets your a's instead of the div
NEW FIDDLE
should be this instead:
if($(this).closest("div").hasClass("span1")){
Here in pure Javascript: http://jsfiddle.net/xxx96bta/5/
var links = document.getElementsByTagName('a'); //collect your elements
for (i = 0; i < links.length; i++) {
(function () {
links[i].addEventListener('click', whatSpan, false);
})();
}
function whatSpan() {
var parentspan = this.parentNode.parentNode.parentNode.className;
if (parentspan == "span1") {
alert("you clicked span 1");
} else {
alert("you clicked span 2");
}
}

Categories