I have functioning code, but I am sure there is a way to write it cleaner.
My code is far from best practice I assume. Don't repeat yourself principle.
I have tried looking for this problem but can not find an answer.
Here are the expected result and my current code:
https://jsfiddle.net/9ednsp6x/
document.getElementById("BtnMoreTotalt").onclick = function() {MoreBtnTotalt()};
function MoreBtnTotalt() {
document.querySelector(".more-wrapper-totalt").classList.toggle("show");
}
I also wonder, if there is a way so I do not have to use specific id and classnames on every element? Could I only use class "more-wrapper" and skip the IDs?
Here you have your example with a re-usable button click handler.
To make it work, you have to:
Wrap all your groups of button/content in a wrapper div with a class
Change the CSS so it works over the wrappers class
Add the click event handler to every element of the class
Use the event to get the nearest wrapper
now you can change the class of it
// Query through all "a" elements that are inside a ".wrapper" element
document.querySelectorAll(".wrapper > a").forEach(b => {
// Add a click handler to each
b.onclick = (e) => {
// prevent the default action of an "a" element
e.preventDefault();
// get the closest wrapper from the event
let button = e.target;
let wrapper = button.closest(".wrapper");
// now change the class
wrapper.classList.toggle("show");
};
});
.wrapper > div {
visibility:hidden;
}
.wrapper.show > div {
visibility:visible
};
<div class="wrapper">
<div>test1</div>
Mer info
</div>
<div class="wrapper">
<div>test2</div>
Mer info
</div>
<div class="wrapper">
<div>test3</div>
Mer info
</div>
<div class="wrapper">
<div>test4</div>
Mer info
</div>
document.querySelectorAll(".more-button").forEach(element => {
element.onclick = (e) => {
const elm = document.getElementsByClassName(e.target.getAttribute("anchor"));
elm[0].classList.toggle("show");
};
});
.more-wrapper {
visibility:hidden;
}
.more-wrapper.show {visibility:visible};
<div class="more-wrapper more-wrapper-totalt">
<div>test1</div>
</div>
<a href="#" onClick="return false;">
<div anchor="more-wrapper-totalt" class="more-button">Mer info</div>
</a>
<div class="more-wrapper more-wrapper-kvant">
<div>test2</div>
</div>
<a href="#" onClick="return false;">
<div anchor="more-wrapper-kvant" class="more-button">Mer info</div>
</a>
<div class="more-wrapper more-wrapper-invb">
<div>test3</div>
</div>
<a href="#" onClick="return false;">
<div anchor="more-wrapper-invb" class="more-button">Mer info</div>
</a>
<div class="more-wrapper more-wrapper-barn">
<div>test4</div>
</div>
<a href="#" onClick="return false;">
<div anchor="more-wrapper-barn" class="more-button">Mer info</div>
</a>
You can add the className button with attribute after use this attr click event. It's like clone but i think you need this class another place.
Related
I want to be able to modify/output to the content of particular header tag with the id attribute value of whichever anchor/link is clicked.
Currently, i am able to only change the text "City" with the value of the first id ("New York", in the below example) - because the text is outside of the nested div tags, but still within the anchor tags. so the first link works, but the 2nd and 3rd links pass empty strings/give no output. i want to the text/content to remain within the div tags as in the 2nd and 3rd links.
<base target=splash>
<H3 id=myTitle onclick="myFunction()">City</H3>
<a class="clickable" href="myPage.htm?id=108" id="New+York">New York
<div class=cityWrap>
<DIV class=cityNo>108</DIV>
<DIV class=cityName>New York</DIV>
<DIV class=country>USA</DIV>
</div>
</a>
<a class="clickable" href="myPage.htm?id=110" id="Shanghai">
<div class=cityWrap>
<DIV class=cityNo>110</DIV>
<DIV class=cityName>Shanghai</DIV>
<DIV class=country>China</DIV>
</div>
</a>
<a class="clickable" href="myPage.htm?id=112" id="Damascus">
<div class=cityWrap>
<DIV class=cityNo>112</DIV>
<DIV class=cityName>Damascus</DIV>
<DIV class=country>Syria</DIV>
</div>
</a>
<IFRAME src="myPage.htm" name=splash></IFRAME>
<script>
window.addEventListener('load', () => {
let myFunction = event => {
let clickedElem = event.target;
document.getElementById('myTitle').innerHTML = clickedElem.id;
};
for (let elem of document.getElementsByClassName('clickable')) elem.addEventListener('click', myFunction);
});
</script>
Step 1: Add listeners to all required elements
You have a couple of options.
You could exhaustively list all clickable ids in your javascript:
let ids = [ 'New York', 'Shanghai', 'Damascus' /* ... */ ];
for (let id of ids) document.getElementById(id).addEventListener('click', myFunction);
You could target the clickable elements by the fact that they are all a elements:
for (let elem of document.getElementsByTagName('a')) elem.addEventListener('click', myFunction);
You could attach a common class for all desired a elements, and use document.getElementsByClassName:
html:
<a class="clickable" href="myPage.htm?id=New York" id="New York">New York</A>
<a class="clickable" href="myPage.htm?id=Shanghai" id="Shanghai">Shanghai</A>
<a class="clickable" href="myPage.htm?id=Damascus" id="Damascus">Damascus</A>
js:
for (let elem of document.getElementsByClassName('clickable')) elem.addEventListener('click', myFunction);
Step 2: Determine which element was clicked inside of myFunction:
Now the same function, myFunction, gets called no matter which element is clicked. We have to figure out which specific element was clicked, to determine which id to display.
Fortunately Event.target does this for us. We can rewrite myFunction to look like this:
let myFunction = event => {
// Get the <a> element that was clicked
let clickedElem = event.target;
// Apply that element's id as the innerHTML of the #myTitle element
document.getElementById('myTitle').innerHTML = clickedElem.id;
};
Final code
Could look something like this:
window.addEventListener('load', () => {
let myFunction = event => {
let clickedElem = event.target;
document.getElementById('myTitle').innerHTML = clickedElem.id;
event.preventDefault(); // Important to prevent page navigation
};
for (let elem of document.getElementsByTagName('a')) elem.addEventListener('click', myFunction);
});
[href$="=108"], [href$="=108"] * { background-color: #ffa0a0; }
[href$="=110"], [href$="=110"] * { background-color: #a0ffa0; }
[href$="=112"], [href$="=112"] * { background-color: #a0a0ff; }
a > div { pointer-events: none; }
<h3 id=myTitle>City</H3>
<a href="myPage.htm?id=108" id="New+York">New York
<div class=cityWrap>
<DIV class=cityNo>108</DIV>
<DIV class=cityName>New York</DIV>
<DIV class=country>USA</DIV>
</div>
</a>
<a href="myPage.htm?id=110" id="Shanghai">
<div class=cityWrap>
<DIV class=cityNo>110</DIV>
<DIV class=cityName>Shanghai</DIV>
<DIV class=country>China</DIV>
</div>
</a>
<a href="myPage.htm?id=112" id="Damascus">
<div class=cityWrap>
<DIV class=cityNo>112</DIV>
<DIV class=cityName>Damascus</DIV>
<DIV class=country>Syria</DIV>
</div>
</a>
you can try something like this for each of the links
<a onclick="getElementById('myTitle').innerHTML = your title here">your value here</a>
else try searching for w3schools onclick event
hope this helps :>
I have this multiple elements with the same class.
<div class="test-container">
<a class="dup-class">
Get Value
</a>
<div class="product-list-col">
1
</div>
</div>
<div class="test-container">
<a class="dup-class">
Get Value
</a>
<div class="product-list-col">
2
</div>
</div>
<div class="test-container">
<a class="dup-class">
Get Value
</a>
<div class="product-list-col">
3
</div>
</div>
If I click the the <a> tag on the first div, it should alert the value of .product-list-col value which is 1
if I click the second div of anchor tag, it should alert 2
here's the code for it
$(".dup-class").on('click', function() {
cont = $(this + " .product-list-col").text();
alert(cont);
});
Any solution for this stuff?
Here's the jsfiddle of it: http://jsfiddle.net/Vigiliance/PLeDs/3/
You could use siblings(), the reason why your code doesn't work is because it's selecting all .product-list-col
$(".dup-class").on('click', function () {
cont = $(this).siblings('.product-list-col').text();
alert(cont);
});
or use .next()
$(".dup-class").on('click', function () {
cont = $(this).next('.product-list-col').text();
alert(cont);
});
do this:
$(".dup-class").on('click', function() {
cont = $(this).next().text(); // this is the line where change done
alert(cont);
});
http://jsfiddle.net/PLeDs/2/
I have serval link buttons in order to show a div below it.
<a class="btnComment" onclick="showComment()" isshow='0'>{{ post_comments.count }} comment</a>
<div class="comment">
....
</div>
<a class="btnComment" onclick="showComment()" isshow='0'>{{ post_comments.count }} comment</a>
<div class="comment">
....
</div>
<a class="btnComment" onclick="showComment()" isshow='0'>{{ post_comments.count }} comment</a>
<div class="comment">
....
</div>
I want to clink one linkbutton and only show the div element below it. but my js code:
function showComment(){
var isshow=$(this).attr('isshow');
if(isshow=="0"){
this.$(".comment").show();
$(this).attr('isshow',"1");
}
else{
this.$(".comment").hide();
$(this).attr("isshow","0");
}
}
this show all div. and when i use $(this).siblings() or $(this).next(), i got null, i don't know why that not work.
What can i do?
this is not pointing to the element if you run it in an inline event. Try the following:
onclick="showComment(this)"
And:
function showComment(el) {
var isshow=$(el).attr('isshow');
if(isshow=="0"){
$(el).next(".comment").show();
$(el).attr('isshow',"1");
}
else{
$(el).next(".comment").hide();
$(el).attr("isshow","0");
}
}
Or if you use jQuery's click, you can use this to point to the element:
$('.btnComment').click(function(event) {
var isshow=$(this).attr('isshow');
if(isshow=="0"){
$(this).next(".comment").show();
$(this).attr('isshow',"1");
}
else{
$(this).next(".comment").hide();
$(this).attr("isshow","0");
}
});
You should wrap your <a> and <div> inside another <div> to create a more maintainable code. Like this:
<div class="commentContainer">
<a class="btnComment" isshow='0'>{{ post_comments.count }} comment</a>
<div class="comment">
....
</div>
<div>
This parent div serves as the context for your tags. In the future, if you change the position, move <a> after <div>, your code still works fine. And it's even possible for you to to styling as a group just by assigning a class to the container.
Your jquery, here I use jquery event handler instead.
$(".btnComment").click(function () {
var isshow = $(this).attr('isshow');
var parent = $(this).closest(".commentContainer");
if (isshow == "0") {
parent.find(".comment").show();
$(this).attr('isshow', "1");
} else {
parent.find(".comment").hide();
$(this).attr("isshow", "0");
}
}
If you use .next(), it means your code is coupled to the current html.
css
.hide{visibility:hidden;}
.show{visibility:visible;}
jquery
$('.btnComment').click(function(){
$('.btnComment + div').removeClass('show').addClass('hide');
$(this).next().removeClass('hide').addClass('show'); });
html
<a class="btnComment" href="javascript:;"
sshow='0'>click1</a> < div
class="hide">sandy1</div> <a class="btnComment"
href="javascript:;" isshow='0'>click2</a> <div
class="hide">sandy2</div> <a class="btnComment"
href="javascript:;" isshow='0'>click3</a> <div
class="hide">sandy3</div>
On every click of anchor tag respective div will be shown and others will be hidden.
Hope this will help you.
I am using the javascript function for multiple hide show divs in custom tumblr theme.. my The problem is as the class name is same, if i click on a single div, by default all the div gets show or hide.
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(document).ready(function() {
$(".toggleme").click(function () {
$(".toparea3").slideToggle("slow");
return false;
});
});
</script>
<a class="toggleme" href="#"><img src="http://www.abc.com/images/share.png"></a>
<div class="toparea3" style="display:none;">
<div class="share-bar clearfix" style=" margin-top:3px;margin-left: -2px;width: 380px;height: 50px;">
<div class="share-bar-buttons">
<div class="share-bar-facebook">
<iframe src="http://www.facebook.com/plugins/like.php?href={URLEncodedPermalink}&layout=button_count&show_faces=false&width=110&action=like&font=lucida+grande&colorscheme=light&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:110px; height:21px;" allowTransparency="true"></iframe>
</div>
</div>
<div style="margin-left:80px;margin-top: 15px;" class="share-bar-twitter">
<a href="http://twitter.com/share" class="twitter-share-button"
data-url="{Permalink}"
{block:Twitter}data-via="{TwitterUsername}"{/block:Twitter}
data-related="stylehatch:Premium Tumblr Themes by #newezra"></a>
</div>
<div style="float: right;margin-top:-25px;" class="share-bar-shorturl">
<div class="linktumb">
http://www.tumblr.com/xdrs2sf
</div>
</div>
</div>
</div>
Assuming you have multiple "toggleme" buttons, if they're all in the format where you have a toggleme button and then a toparea3, you could do something like this:
$('.toggleme').click(function(){
$(this).next().slideToggle('slow');
return false;
});
The "next" function gets the next element in the DOM, which is the element you want to expand.
Edit: (nevermind the .children)
try using the .closest selector, or the .next selector someone else suggested. Just remember to provide the selector .toparea3 to make sure that only that class opens, not just any closest/next element.
$(document).ready(function() {
$(".toggleme").click(function () {
$(this).closest(".toparea3").slideToggle("slow");
return false;
});
});
I would recommend the following:
Place the 'a' and the corresponding 'div' in a parent 'div'. Something like this:
<div>
<a class='toggleMe' />
<div class='toparea3 />
</div>
Then you can update your inner selector to be:
$('.toggleMe').click(function(evt){
evt.preventDefault();
var parent = $(this).closest('div');
$(".toparea3", parent).slideToggle("slow");
}
My Recommendation is to give the div an id, and make the anchor element's href point to it:
<script>
$(document).ready(function() {
$(".toggleme").click(function () {
$(this.hash).slideToggle("slow");
return false;
});
});
</script>
<a class="toggleme" href="#toparea3_1"><img src="http://www.abc.com/images/share.png"></a>
<div id="toparea3_1" class="toparea3" style="display:none;"></div>
This since the hash is given in the form #toparea3_1 that is a valid jQuery selector that selects on ID, and can be used directly.
If I mouseover on a link it has to show div.
My problem is that I have to show divs in all of the links inside a page. For each link I have to show a different div.
How to do this using javascript?
Since, your question does not specify anything. I will give a simplest solution I can. That is, with plain CSS, no JS needed.
Here is a demo
Markup
<a href="#">
Some
<div class="toshow">
Hello
</div>
</a>
<a href="#">
None
<div class="toshow">
Hi
</div>
</a>
CSS
.toshow {
display:none;
position: absolute;
background: #f00;
width: 200px;
}
a:hover div.toshow {
display:block;
}
You should not try to rely on script as much as possible. This is a very simple example, with displays the use of :hover event of the link.
Steps can be:
Make multiple divs all with different id.
Give style="display:none;" to all div.
Make links to show respective div.
In onMouseOver of link call js function which changes display property to block of proper div. Ex.:- document.getElementById("divId").style.display = "block"; And for all other div set display:none; in that js function.
Sample code:-
Your links:
Div 1
Div 1
Your divs:
<div id="myDiv1">Div 1</div>
<div id="myDiv2">Div 2</div>
JS function:
function Changing(i) {
if(i==1){
document.getElementById("myDiv1").style.display = "block";
document.getElementById("myDiv2").style.display = "none";
} else {
document.getElementById("myDiv1").style.display = "none";
document.getElementById("myDiv2").style.display = "block";
}
}
If you have more divs then you can use for loop in js function instead of if...else.
look at jquery each
<div id=div-0" class="sidediv" style="display:none" > Div for first link </div>
<div id=div-1" class="sidediv" style="display:none"> Div for second link </div>
<div id=div-2" class="sidediv" style="display:none"> Div for third link </div>
<a class="linkclass" href=""> Link </a>
<a class="linkclass" href=""> Link </a>
<a class="linkclass" href=""> Link </a>
and essentially do something like this
$('.linkclass').each(function(i,u) {
$(this).hover(function()
{
$('#div-'+i).show();
}, function() {
$('#div-'+i).hide(); //on mouseout;
})
});
Edit: oops ...this will need jquery. dont know why I assumed jquery here.
You can give ids to all the links such as
<a id="link-1"></a>
<a id="link-2"></a>
<a id="link-3"></a>
and so on ..
and similarly to div elements
<div id="div-1"></div>
<div id="div-2"></div>
<div id="div-3"></div>
and so on ..
then
$("a").hover(function () { //callback function to show on mouseover
var id = $(this).attr('id').replace("link-", "");
$("#div-"+id).show();
},
function () { //if you want to hide on mouse out
var id = $(this).attr('id').replace("link-", "");
$("#div-"+id).hide();
}
);