I am new to JavaScript and actually quite desperate by now
I have an HTML file that:
gets data from an XML file and displays them in various divs (e.g. )
these divs are hidden (by default) by a class name (class='box')
when a link is clicked, I pass the 'href' to the function showContent, remove the #, and then look for an element with that ID in the document.
then I add a new class name ('show') - so that this element shows up!
If you run the code you will see that every time you click on a link a new div is displayed...
So current problems:
replace already shown divs with the new clicked ID so that only one div shows up every time.
How can I avoid inserting the onClick event in every single tag - and make this more automated?
My code is as follows:
function showContent(obj)
{
var linkTo = obj.getAttribute("href");
var newlinkTo=linkTo.replace('#','');
//alert (newlinkTo);
document.getElementById(newlinkTo).innerHTML=" This is where the xml variable content should go";
document.getElementById(newlinkTo).className += " Show";
return true;
}
<a href="#b0" onClick="return showContent(this);">
<div id="text_content"> link2 </div>
</a>
<a href="#b1" onClick="return showContent(this);">
<div id="text_content"> link 1 </div>
</a>
<div class='box' id='b0'> abstract content </div>
<div class='box' id='b1'> introduction content </div>
I'm not usually into using jQuery everywhere, but with it you could just do:
<a class='showContent' data='b0'/>
Your js:
var selected;
$('a.showContent').on('click',function(e){
var toShow = $(this).attr('data');
if(selected!==undefined) selected.removeClass('Show');
selected = $(div+'#'+toShow);
selected.addClass('Show');
});
Not sure if this is what you want, but thought I'd suggest it.
This sort of thing is not hard to do without jQuery.
I would recommend using a hash-bang (#!) for Javascript activated links to keep it separate from other possible links with hashes. (script is at the bottom)
<div id="nav-links">
<a href="#!b0">
<div id="text_content"> link2 </div>
</a>
<a href="#!b1">
<div id="text_content"> link 1 </div>
</a>
</div>
<div class='box' id='b0'> abstract content </div>
<div class='box' id='b1'> introduction content </div>
<script type="text/javascript">
var links = document.getElementById('nav-links').getElementsByTagName('a');
for(var i = 0, link; link = links[i]; i++) {
link.onclick = showContent;
// Hide content divs by default
getContentDiv(link).style.display = 'none';
}
// Show the first content div
if(links.length > 0) showContent.apply(links[0]);
var current;
function showContent() {
// hide old content
if(current) current.style.display = 'none';
current = getContentDiv(this);
if(!current) return true;
//current.innerHTML = "This is where the xml variable content should go";
current.style.display = 'block';
return true;
}
function getContentDiv(link) {
var linkTo = link.getAttribute('href');
// Make sure the link is meant to go to a div
if(linkTo.substring(0, 2) != '#!') return;
linkTo = linkTo.substring(2);
return document.getElementById(linkTo);
}
</script>
There is a WAY cleaner way to do this:
This is just my quick example, it can get EVEN cleaner than this, but this works for your case:
HTML:
link b0
link b1
<div class='box' id='b0'> abstract content </div>
<div class='box' id='b1'> introduction content </div>
CSS:
#b0 { display: none; }
#b1 { display: none; }
a, div.text_content { display: inline; padding: 0 10px; }
JQUERY:
$('.link').click(function(){
var id = $(this).attr("rel");
$('#'+id).slideToggle('slow');
});
Each link would have to have a REL attribute that is the same as the ID of the div element that you are trying to show.
Here is a JSFiddle to this example in action:
http://jsfiddle.net/CUJSM/5/
Related
Can some one tell me, Why tag a make my first click without opening the table, but take the address which should go (in first moment table is hidden)
and after second click, table is opening and i'm going to it. without tag <a href="#team-#team.Id"> it open by 1 click. #team-**#team.Id** - it's normal, i did 15 tables by cycle, and make for each table id)
my code in view
<div id=team-logo-wrapper>
<ul>
#foreach (Team team in Model.Item2)
{
<li>
<div class="team-section-box">
<p class="team-name">#team.Name</p>
<a href="#team-#team.Id">
<img src="#Url.Content(string.Format("~/Images/NBAlogoImg/{0}", team.Path))" class="logo-images" alt="Логотип #team.Name" title="Логотип #team.Name" onclick="ShowTable(#team.Id)" />
</a>
</div>
</li>
}
</ul>
in CSS my display and visibility
.table-hidden {
margin-top: 50px;
display: none;
visibility: hidden;
}
the simplest script
var flag = true;
function ShowTable(teamId) {
var id = "team-" + teamId;
var getElem = document.getElementById(id);
if (flag) {
flag = false;
getElem.style.display = 'none';
getElem.style.visibility = 'hidden';
}
else {
flag = true;
getElem.style.display = 'block';
getElem.style.visibility = 'visible';
}
}
When you click on the image, you also activate the link.
If you really need the link, then change it to something like:
<a href="javascript: void(0)">
<img src="#Url.Content(string.Format("~/Images/NBAlogoImg/{0}", team.Path))"
class="logo-images" alt="Логотип #team.Name"
title="Логотип #team.Name"
onclick="ShowTable(#team.Id)" />
</a>
Can you help me to make the first div show on page load?
function showStuff(element) {
var tabContents = document.getElementsByClassName('tabContent');
for (var i = 0; i < tabContents.length; i++) {
tabContents[i].style.display = 'none';
}
var tabContentIdToShow = element.id.replace(/(\d)/g, '-$1');
document.getElementById(tabContentIdToShow).style.display = 'block';
}
.tabContent {
display:none;
}
<div tabindex="1" class="tabs"><div id="tabs1" onclick="showStuff(this)">CARATTERISTICHE</div><div class="triangle-down-tab"></div></div>
<div id="tabs2" onclick="showStuff(this)">DESTINATARI</div><div class="triangle-down-tab"></div></div>
<div tabindex="3" class="tabs"><div id="tabs3" onclick="showStuff(this)"><i class="fa fa-calendar" style="color:#000000;"></i> CALENDARIO</div><div class="triangle-down-tab"></div></div>
<a name="contenuto"><hr></a>
<div id="tabs-1" class="tabContent">
<p>tab 1</p>
</div>
<div id="tabs-2" class="tabContent">
<p>tab 2 tab 2 </p>
</div>
<div id="tabs-3" class="tabContent">
<p>tab 3 tab 3 tab 3</p>
</div>
This is my actual code. jsFiddle
Thanks!
You could try running a function when the document is ready.
$(document).ready(function () {
showTab("tabs-1");
function showTab(divId) {
//Get the element
var divElement= document.getElementbyId(divId);
//Set the css property "display" from "none" to be "block";
divElement..style.display = "block";
}
}):
The function should run once the page has fully loaded.
Let me know how it goes.
I sure can. When you do this kind of stuff best use css. That way when the dom loads the css will kick in and your desired effect will show.
Further more its easier to understand and easier to code up.
.tabContent {
display:none;
}
.tabContent.active {
display:block;
}
Then in the HTML
<div id="tabs-1" class="tabContent active">
So when the page loads tab one is active
Then in your JS
function showStuff(element) {
var tabContents = document.getElementsByClassName('tabContent');
for (var i = 0; i < tabContents.length; i++) {
tabContents[i].className="tabContent";
}
var tabContentIdToShow = element.id.replace(/(\d)/g, '-$1');
document.getElementById(tabContentIdToShow).className="tabContent active";
}
Updated fiddle!
https://jsfiddle.net/rb5c5095/3/
We could improve things since we know all the tabs will be made invisible at boot up and tab 1 will show. So when a tab is clicked we could just search the tab who has .active class and remove it, then apply the .active class to the new tab. This would have the benefit that any extra css you add in your html markup would not be removed by the JS code, but i reckon you can work that out and if you can't get back to me i can show you :-)
Here I am invoking the function (upon page load) that tweaks the css of the desired block;
Same can be achieved by $(document).ready;
I took this approach to avoid jquery;
window.onload = showDivOne();
function showDivOne() {
document.getElementById("tabs-1").style.display = "block";
}
Earlier, I did an assignment where I was supposed to write code in Javascript in order to toggle visibility for the submenus each belonging to their own topmenu in a navigation bar for a webpage. The visibility should be set to hidden by default and should be shown when a topmenu is clicked on. I know how to toggle visibility for ONE submenu belonging to a topmenu, but fail to make my code work for multiple elements. With help from here, I got my code to work. However, my teacher was not pleased over the fact that I used onclick in my HTML-code. So my question is now: How do I move all functionality to javascript, and thereby not use onclick in my HTML?
Note: Of course I gave it a try myself but I cannot make the pairing between header and div work correctly... By the pairing I mean that visibility of the div with the class "left_submenu_1" should be toggled when you click the topmenu "left_top1". Thus should the visibilily of the div with the class "left_submenu_2" be toggled when you click the topmenu "left_top2".
I guess I should start something like this:
var left_headings = document.getElementsByClassName("left_top");
for(var k = 0; k < left_headings.length; k++) {
??????
}
Earlier related question: Toggle visibility for multiple divs with one function: navigation bar
HTML
<a class="left_top" onclick = "toggle('.left_submenu_1')">Opinion</a><br>
<div class="left_submenu_1" style="display: none;">
<a class="left_sub1">Leaders</a><br>
<a class="left_sub1">Debates</a><br>
</div>
<br>
<a class="left_top" onclick = "toggle('.left_submenu_2')">Economy</a><br>
<div class="left_submenu_2" style="display: none;">
<a class="left_sub2">News</a><br>
<a class="left_sub2">Your Economy</a><br>
</div>
Javascript
function toggle(qs) {
var e = document.querySelector(qs);
e.style.display = e.style.display === 'block' ? 'none' : 'block';
}
Please note: We are NOT allowed to use jQuery or to give the topmenus id:s, as the idea is to use one general function to toggle the visibility.
EDIT: Changing the html was out of the question, updated answer.
Instead of using onclick to handle the event, assign the eventhandler via javascript, like this (Note that I added IDs to the elements in order to be able to select them properly):
jsfiddle: https://jsfiddle.net/pkptn4gf/
<a class="left_top">Opinion</a><br>
<div class="left_submenu_1" style="display: none;">
<a class="left_sub1">Leaders</a><br>
<a class="left_sub1">Debates</a><br>
</div>
<br>
<a class="left_top">Economy</a><br>
<div class="left_submenu_2" style="display: none;">
<a class="left_sub2">News</a><br>
<a class="left_sub2">Your Economy</a><br>
</div>
function toggle(qs) {
var e = document.querySelector(qs);
e.style.display = e.style.display === 'block' ? 'none' : 'block';
}
var clickables = document.getElementsByClassName("left_top");
clickables[0].addEventListener("click", function(){
toggle('.left_submenu_1');
});
clickables[1].addEventListener("click", function(){
toggle('.left_submenu_2');
});
I have set up some anchors and a little menu up top. when I click a menu item, it will scroll to that anchor.
what I want to do is have a next arrow on the menu to determine the next anchor on my page and scroll to it onClick.
My anchors are #header, #box1 - #box5
I would like to do it with JavaScript if possible.
here is my page
My Page
There is an HTML collection called document.anchors. To go to the next anchor, get the current anchor name from the URL and look for it in document.anchors. If you find it, the next one will be the next index. If you're at the last index, set the anchor to the first. Otherwise, if there is no match, just set it to the first.
This allows you to use any scheme for naming anchors, they will be visited in the order they appear in the DOM.
e.g.
<head>
<!-- Hide script-dependent content -->
<style type="text/css">
.requiresScript-block, .requiresScript-inLine {
display: none;
}
div.spacer {
height: 500px;
border: 1px solid blue;
}
</style>
<script type="text/javascript">
function goToNextAnchor() {
var anchors = document.anchors;
var loc = window.location.href.replace(/#.*/,'');
var nextAnchorName;
// Get name of the current anchor from the hash
// if there is one
var anchorName = window.location.hash.replace(/#/,'');
// If there is an anchor name...
if (anchorName) {
// Find current element in anchor list, then
// get next anchor name, or if at last anchor, set to first
for (var i=0, iLen=anchors.length; i<iLen; i++) {
if (anchors[i].name == anchorName) {
nextAnchorName = anchors[++i % iLen].name;
break;
}
}
}
// If there was no anchorName or no match,
// set nextAnchorName to first anchor name
if (!nextAnchorName) {
nextAnchorName = anchors[0].name;
}
// Go to new URL
window.location.href = loc + '#' + nextAnchorName;
}
// Display script-dependent content if javascript available
document.write(
'\u003Cstyle type="text/css"\u003e' +
'.requiresScript-block {display: block;}' +
'.requiresScript-inLine {display: inline;}' +
'\u003C/style\u003e'
);
</script>
</head>
<body>
<ol>
<li>Go to header
<li>Go to box 1
<li>Go to box 2
<li>Go to box 3
<li>Go to box 4
<li>Go to box 5
</ol>
<!-- Only shown if javascript available -->
<button class="requiresScript-inLine" onclick="goToNextAnchor()">Next</button>
<a name="header"></a><h1>Header</h1>
<div class="spacer">content</div>
<p><a name="box1"></a><p>Box 1</p>
<div class="spacer">content</div>
<p><a name="box2"></a><p>Box 2</p>
<div class="spacer">content</div>
<p><a name="box3"></a><p>Box 3 </p>
<div class="spacer">content</div>
<p><a name="box4"></a><p>Box 4</p>
<div class="spacer">content</div>
<p><a name="box5"></a><p>Box 5</p>
</body>
Something using an onClick in your HTML:
===>
...and then the JavaScript:
var max = 5;
function goToNext() {
var hash = String(document.location.hash);
if (hash && hash.indexOf(/box/)) {
var newh = Number(hash.replace("#box",""));
(newh > max-1) ? newh = 0 : void(null);
document.location.hash = "#box" + String(newh+1);
} else {
document.location.hash = "box1";
}
}
Change max the highest number you want to go (for box1, box2, etc...). Not sure if this will keep the animation, but you can take a look at an example here. Just watch the address bar.
I'm creating a page with an image at the top, and a menu below. When the user clicks on on of the 3 menu buttons, the image slideUp and the page scrolls down so the menu is at the top of the page, then the right .content div fades in. The slideUp should only happen the first time the user clicks on of the buttons.
What the absolute best way to do this with jQuery? (no plugins)
I also need to know how I can't prevent it to fade in the page that is already visible if i click the same button twice?
I'm using rel instead of href, since the href made the page jump, even with return false.
This is what I have so far:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
imgVisible = true;
$('#mainmenu a').click(function(){
var $activeTab = $(this).attr('rel');
if(!imgVisible){
$('html:not(:animated),body:not(:animated)').animate({scrollTop:$('#mainmenu').offset().top-20},500);
$('.content').hide();
$($activeTab).fadeIn();
} else{
$('#imgholder').slideUp(500,function(){
imgVisible = false;
$('#mainmenu a[rel="'+$activeTab+'"]').click();
});
}
return false;
});
});
</script>
<div id="imgholder"><img src="image.jpg" /></div>
<div id="mainmenu">
<ul>
<li><a rel="#tab1"></a></li>
<li><a rel="#tab2"></a></li>
<li><a rel="#tab3"></a></li>
</ul>
</div>
<div id="container">
<div class="content" id="tab1">
content
</div>
<div class="content" id="tab2">
content
</div>
<div class="content" id="tab3">
content
</div>
</div>
The following code accomplishes what you need:
$('#mainmenu a').click(function(){
var myrel=$(this).attr('rel');
$('.content:not([id='+myrel+'])').hide();
$('#imgholder').slideUp(500,function(){
$('#'+myrel).fadeIn();
});
});
....
<li><a href='#' rel='tab0'></a></li>
I have removed the '#' sign from your rel='' piece ;-)
I am not sure why you would want to scroll the page. When a user clicks on the menu, he/she already has it focused (so it is visible inside the current viewport). But do you have a very large top image? If that is the case, let me know and I will modify the snippet. (Still, it depends on the amount of content below the menu visible when the page first loads.)
Also, for SEO reasons you might want to use the href instead of the rel attribute and create separate content holding pages. The following snippet would remove the navigation action.
$('#mainmenu a').each(function(){
var myhref = $(this).attr('href');
$(this).attr('href','#').attr('rel',myhref);
}).click(function(){
var myrel=$(this).attr('rel');
$('.content:not([id='+myrel+'])').hide();
//....etc
I think this is a great example of what your looking for: Organic Tabs
var imgVisible = true;
var $activeTab, $lastTab;
var $mainmenu = $('#mainmenu');
var offset = $mainmenu.offset().top - 20;
$mainmenu.find('a').click(function() {
$activeTab = $($(this).attr('rel'));
if (!imgVisible) {
// dont fire any events if already open
if ($lastTab.attr('id') == $activeTab.attr('id')) return false;
$lastTab.fadeOut('normal', function() {
$activeTab.fadeIn(500, function() {
$lastTab = $activeTab;
});
});
} else {
$('#imgholder').slideUp(500, function() {
imgVisible = false;
window.scrollTo(0, offset);
$activeTab.fadeIn(500, function() {
$lastTab = $activeTab;
});
});
}
return false;
});
I highly suggest adding <a href="#"> as this will not make the page jump when done properly and will ensure validation on your anchor links. Someone let me know if I missed something, it can be resolved quickly (or you can do it for me if you have an optimization or improvement).