I've got the following code that works great! When I click Link 1, the DIV content appears. When I click it again, it disappears. If I click Link 1 again, the DIV content appears again. If I click Link 2 this time, the content appears along with Link 1 content. I want Link 1 to disappear if another DIV link is clicked. I don't want to have to turn that content off before turning another one on. How do I make a DIV disappear after another one is clicked?
Javascript:
function show(ele) {
var srcElement = document.getElementById(ele);
if(srcElement != null) {
if(srcElement.style.display == "block") {
srcElement.style.display= 'none';
}
else {
srcElement.style.display='block';
}
}
return false;
}
DIV:
FIRST LINK
SECOND LINK
<div id="link1" style="display:none">
<p>Link 1 Content Displayed</p>
</div>
<div id="link2" style="display:none">
<p>Link 2 Content Displayed</p>
</div>
I don't want to change the way I'm doing this, I feel like there's a simple solution, I just can't figure it out! Any help is appreciated.
Another, better answer would be to use jQuery, because it lets you write better javascript without having to worry about whether IE is going to break.
include this tag in the head:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
Javascript:
function show( elem )
{
$('.dynamic_link').hide();
$('#'+elem).show();
}
HTML:
FIRST LINK
SECOND LINK
<div id="link1" class="dynamic_link" style="display:none">
<p>Link 1 Content Displayed</p>
</div>
<div id="link2" class="dynamic_link" style="display:none">
<p>Link 2 Content Displayed</p>
</div>
Javascript (modified):
function show(ele) {
var links = ['link1','link2'];
var srcElement = document.getElementById(ele);
var doShow = true;
if(srcElement != null && srcElement.style.display == "block")
doShow = false;
for( var i = 0; i < links.length; ++i ) {
var otherElement = document.getElementById(links[i]);
if( otherElement != null )
otherElement.style.display = 'none';
}
if( doShow )
srcElement.style.display='block';
return false;
}
working example: http://jsfiddle.net/vDKmA/
Related
I want to have a single link that will take you to a different HTML page, down to a specific anchor tag, and also show a div that would be hidden by default.
I know how to link to another page and to an anchor on that page.
Link
On anotherpage.html, I have code to show that div.
<a onclick="toggle_visibility('hiddendiv');">Show div</a>
The Javascript for that is this:
<script type="text/javascript">
<!--
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
//-->
</script>
But I don't know how I could get the first link to also do what the second link is doing. Is this possible? This is for a local site, so I think I'm limited to just HTML, Javascript, and CSS.
Edit: I'm going to use this with Tipue Search (http://www.tipue.com/slide/). I'm going to have the search results point to specific sections on specific pages which have divs that are hidden by default. But in those sections, there are buttons to show those divs. I also included the Javascript I'm using for that above.
The HTML page with the second link either has a <script> tag pointing to an external javascript file providing the toggle_visiblility function or that function is defined directly on the page.
If you add the function definition either by linking to the javascript file <script src="myscripts.js"></script> or copy the definition directly into a <script> tag.
Once the toggle_visibility function is available on your page, the first link can read simply Link , obviously replacing hiddendiv with the appropriate string.
can you please check this project at: https://github.com/nezirz/anchor_scroll
First page contains only link to second one:
<div>
go to index2 and show diw
</div>
And second page contain this code:
<div>
<div id="anchor1" style="background-color:blue; height:500px;">
</div>
</div>
<div>
<div id="anchor2" style="background-color:green; height:400px;display: none;">
</div>
</div>
<div>
<div id="anchor3" style="background-color:red; height:200px;">
</div>
</div>
<script>
window.onload = function() {
var anchor = window.location.hash.substr(1);
console.log(anchor);
setTimeout(function(){
myFunction(anchor);
Element.prototype.documentOffsetTop = function () {
return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop() : 0 );
};
var top = document.getElementById( anchor ).documentOffsetTop() - (window.innerHeight / 2 );
window.scrollTo( 0, top );
}, 2000);
function myFunction(element) {
console.log(element);
var x = document.getElementById(element);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
};
</script>
This is only proof of concept, please update it to your exact requirement. I think that it is not complicated to you.
I'm trying to make a menu (with buttons) that open links.
when you hover on the buttons, a slideDown reveals more information on that link.
I've gotten all those features to technically work, however i can't get the animation speed to go any slower than instantly.
I'm really new to javascript and Jquery, and it took me 2-3 days to get the javascript and CSS to do what i have so far... and yeah it's probably bloated... but i'm still proud i got this done so far :D
PS, I know most menus are made w/ul's but I really like the way the buttons look and detested trying to put the list together. last time i tried used a seperate ul for the information and it kept styling the second list like the first because it was inside it... so annoying. I also tried vertical-link list w/CSS but still think flat 'buttons' are so boring. i really like the 3D esk of the actual html
HTML:
<div class="mainmenu">
<div id="homemenu">
<button id="home" class="mmbutton active">Home</button>
<div id="homesub" class="sub active">-just a bit about this page</div>
</div>
<div id="photosmenu">
<button id="photos" class="mmbutton">Photos</button>
<div id="photossub" class="sub inactive">-just a bit about this page
</div>
</div>
</div>
javascript/jquery:
$(function(){
var mmbutton = $('.mmbutton');
var start = "http://";
var address = "[my web address"; //add "http:
var about = "[web address]/aboutme.html";
var id = 0;
var rel = 0;
var mmsub = 0;
//<click link buttons:
$(mmbutton).click(function(){
var id = $(this).attr('id');
if (id === "home") {
location.replace(start+address);
}else if (id === "about") {
window.alert("I'm sorry I don't have this page set up yet. Thank you for visiting my page!");
//add additional buttons here under 'else if' unless its a subdomain
}else {
location.replace(start+id+'.'+address);//goes to any subdomain by id
}});
//>detect hover
$(mmbutton).hover(function(){
id = $(this).attr('id');
rel = '#'+id+'sub';
mmsub = '#'+id+'menu';
console.log('mouseenter'+rel);
$(rel).removeClass('inactive');
$(rel).stop().slideDown(500000);
}, function(){
console.log('mouseleave'+rel);
$(rel).addClass('inactive');
if ( $(this).hasClass('active')) {
$(rel).removeClass('inactive');
console.log('this is active');
}if ($(rel).hasClass('inactive')){
$(rel).stop().slideUp(500000);
}});});
relevante CSS:
.inactive {
display: none;
}
.sub {
transition-duration: 1s;
}
You can do it setting all that info divs to display:none and use slideToggle() function for that. Considering you want to keep the subdiv's opened when you're over them, one option is create a span element that include the button and the subdiv, and apply the hover to that span. So...
HTML:
<div class="mainmenu">
<div id="homemenu">
<span class="subcontainer">
<button id="home" class="mmbutton active">Home</button>
<div id="homesub" class="sub">-just a bit about this page</div>
</span>
</div>
<div id="photosmenu">
<span class="subcontainer">
<button id="photos" class="mmbutton">Photos</button>
<div id="photossub" class="sub">-just a bit about this page</div>
</span>
</div>
</div>
CSS:
.sub {
display: none;
/*transition-duration: 1s; IMPORTANT: REMOVE THIS!!*/
}
JQUERY:
$('span.subcontainer').hover(function() {
$(this).find('div.sub').slideToggle('slow');
});
IMPORTANT: Check that to make it work you have to remove the transition style you've created for .sub divs (it interfeers with the jquery function).
NOTE: I don't use the div.homemenu or div.photosmenu as the containers for the hover because div's normally have some styles pre-applied by default and can interfeer with the desired behaviour (for example, they normally have width=100% so the hover applies even when you're outside of the button or subdiv in the same line). span is normally more innocuous to use it just as a wrapper.
I hope it helps
Oh! i got it. i was trying to do too much (show off.../ using what im learning).
I removed the line that added and removed the class 'inactive' and just toggled the SlideUp and slideDown when i wanted it too. now i can adjust the animation speed:
(HTML remains unchanged)
CSS: removed the "transition-duration: 1s;"
JavaScript:
$(function(){
var mmbutton = $('.mmbutton');//any/all buttons
var activebut= 0; //detect button classes
var mmdiv = $("div[id$='menu']");//detect button sub info
var start = "http://";
var address = "[address]/index.html"; //add "http://" + [blog or games] + address
var about = "http://[address]/aboutme.html";
var id = 0;
var sub = 0;
var slidespeed= 450; //slideUP/slideDown animation speed //added var for speed
//<click link buttons: (unchanged)
$(mmbutton).click(function(){
id = $(this).attr('id');
if (id === "home") {
location.replace(start+address);
}else if (id === "about") {
location.replace(start+'[address]/aboutme/index.html')
//add additional buttons here under 'else if' unless its a subdomain
}else {
location.replace(start+id+'.'+address);//goes to any subdomain by id
}
});
//<hover display:
//<detect mouse ON button
$(mmbutton).hover(function(){
id = $(this).attr('id');
sub = '#'+id+'sub';
activebut= $(this);
if ( $(activebut).hasClass('active')) {
}else {
$(sub).stop().slideDown(slidespeed);
}
});
//<detect mouse off button AND div
$(mmdiv).mouseleave(function(){
if ( $(activebut).hasClass('active')) {
}else {
$(sub).stop().slideUp(slidespeed);
}
});
});
I'm trying to update an array when clicking on the li tag. I've been testing, testing, and unable to come up with a solution.
I have two tabs: The "Create" tab opens a container that allows you to insert paragraphs, the "Home" tab opens another container containing a "Select paragraph" button.
Problem
It won't update the values of the array when I do it for the second time. I.e., if I switch between the tabs and go on select mode again to select/deselect, it will not update the new selection, instead I get the same selection from the first time.
I've created an example so you can look at it and if there is a better way to accomplish this (which I know there is) then be my guest. Link is below the next paragraph.
Instructions
In order to select a paragraph, first you need to add a paragraph which is created on the fly, then you switch to "Home" section, click on the "Select paragraph" button, this takes you to the "Create" section on select mode. To select/deselect, click on any paragraph. When you select a paragraph, it stores its position using jQuery - index() in the "storeClass" array. Once you're done selecting paragraphs then you exit the select mode by clicking "Ok" button and it switches to "Home" section, but let's say you want to create another paragraph then you click on "Create" tab, create the paragraph, switch to "Home" tab, go on select mode and select again and switch between tabs and you will see just the first selection you made on the first time.
Here is the same example: http://jsfiddle.net/7mbhnvas/8/
HTML
<ul class="tab">
<li><a class="paragraph-tab">Create</a></li>
<li><a class="select-tab">Home</a></li>
</ul>
<div class="wrap">
<div class="create-para-cont">
<h3>Create a paragraph</h3>
<ul class="para-results">
</ul>
<div class="para-tool">
<p><textarea class="textarea"></textarea></p>
<button type="button" class="create-para-button">Create paragraph</button>
<div>
<button type="button" class="select-ok-button">OK</button>
</div>
</div>
</div>
<div class="select-para-cont">
<h3>Select Mode</h3>
<p><button type="button" class="select-para-button">Select paragraph</button></p>
</div>
</div>
jQuery
$('ul.tab li a:first').addClass('tab-active');
$('.create-para-cont').addClass('cont-active');
$('.create-para-button').on('click', function(){
$('.create-para-cont').addClass('cont-active');
var parent = $('.para-results');
var child = $('<li></li>');
var p = $('<p></p>');
var textarea = $('.textarea').val();
if($('.create-para-cont').hasClass('cont-active')){
p.text(textarea);
child.append(p);
parent.append(child);
} else {
return false
}
});
var storeClass = [];
$('.select-para-button').on('click', function(){
$('.create-para-cont').addClass('cont-select');
if($('.para-results li').length >= 1){
$('.textarea, .create-para-button').hide();
$('.select-para-cont').hide();
$('.select-tab').removeClass('tab-active');
$('.create-para-cont').show();
$('.paragraph-tab').addClass('tab-active');
$('.select-ok-button').show();
for ( var i = 0; i < storeClass.length; i = i + 1 ) {
$('.para-results').each(function( index ) {
$( this ).find( "li:eq("+ storeClass[ i ] +")" ).addClass('p-selected');
});
}
}
});
$('ul.tab li').on('click','a', function(){
if($(this).hasClass('paragraph-tab')){
$('.para-results').children('li').removeClass('p-selected');
$('.select-para-cont').hide();
$('.select-tab').removeClass('tab-active');
$('.create-para-cont').show();
$('.paragraph-tab').addClass('tab-active');
} else {
$('.create-para-cont').removeClass('cont-active');
$('.create-para-cont').hide();
$('.paragraph-tab').removeClass('tab-active');
$('.select-para-cont').show();
$('.select-tab').addClass('tab-active');
}
});
$('ul.para-results').on('click','li', function(){
if($('.create-para-cont').hasClass('cont-select')){
$(this).toggleClass('p-selected');
var selected = $('.p-selected ');
var pSelected = selected.parent().children().index(this);
storeClass.push( pSelected );
} else {
return false;
}
});
$('.select-ok-button').on('click', function(){
if($('.create-para-cont').hasClass('cont-select')){
$('.create-para-cont').removeClass('cont-select');
$('.create-para-cont').removeClass('cont-active');
$('.create-para-cont').hide();
$('.paragraph-tab').removeClass('tab-active');
$('.select-para-cont').show();
$('.select-tab').addClass('tab-active');
}
});
I would reset storeClass to a blank array when the 'OK' button is clicked, and then re-push all the correct values into it in that same click handler:
$('.select-ok-button').on('click', function(){
if($('.create-para-cont').hasClass('cont-select')) {
storeClass = []; // make it blank
$('.p-selected').each(function() {
storeClass.push($(this).index()); // push each one into the array
});
....
}
});
Then your click handler of ul.para-results would look like this:
$('ul.para-results').on('click','li', function(){
if($('.create-para-cont').hasClass('cont-select')){
$(this).toggleClass('p-selected');
} else {
return false;
}
});
Here's an updated Fiddle
I am having some trouble tracking the scroll position. I am trying to set a variable according to what section is visible.
My html looks like this
<body>
<div id="wrapper">
<div class="main">
<section id="one"><h2>BLA BLA</h2></section>
<section id="two"><h2>MJALLO!</h2></section>
<section id="three"><h2>MJALLO!</h2></section>
<section id="four"><h2>MJALLO!</h2></section>
<section id="five"><h2>MJALLO!</h2></section>
</div>
</body>
As said, i am trying to track the $(document) position and match it with a section id. I have for this the following jQuery
$(document).ready(function () {
var window = $(window);
var view = "";
if (window.scrollTop == $("#one").offset().top)
{view = "1";}
else if (window.scrollTop == $("#two").offset().top)
{view = "2";}
else if (window.scrollTop == $("#three").offset().top)
{view = "3";}
else if (window.scrollTop == $("#four").offset().top)
{view = "4";}
else if (window.scrollTop == $("#five").offset().top)
{view = "5";}
});
The section are styled as full frame blocks but i can't get any reaction on this if statement.
I am new to jQuery and js so a bit explanation would be appreciated ;)
Thanks in advance.
You need to wrap the ifs in a "on scroll" function:
$( document ).scroll(function() {
if(....)
});
https://api.jquery.com/scroll/
I have a bunch of links in my footer and I want to link to different headings on a page and create a click event so a associated paragraph changes from display: none to display: block.
Put another way: You see headings and a footer with links (like the demo). You click the footer links and the screen should jump to (link to) an associated h2 and display a previously hidden and associated p.
Here is what I have: I can display the paragraphs when I click on the headings directly (adapted from a stackoverflow post). I can link to the headings when I click on the links in the footer. But I need to display the associated paragraph and link to a heading (both) when I click the footer links.
Here is my markup so far:
<div class="service">
<h2 class="page services"><img class="img-bullet-services" src="websiteDot.png" alt="alt">service1</h2>
<p class="p-on-white service-desc p-hide" id="service1">xxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
</div>
</br>
<div class="service">
<h2 class="page services"><img class="img-bullet-services" src="websiteDot.png" alt="alt">service2</h2>
<p class="p-on-white service-desc p-hide" id="service2">xxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
</div>
<div id="col4-footer" class="four-cols-footer four-cols">
<ul>
<li style="list-style: none;">
<h3><a class="a-bold" href="Services.php">Services</a></h3>
</li>
<li>service1
</li>
<li>seervice2
</li>
</ul>
</div>
css:
.p-hide {
display: none;
}
js:
var services = document.getElementsByClassName('service'),
servicedesc;
for (var i = 0; i < services.length; i++) {
services[i].addEventListener("click", function () {
servicedesc = this.getElementsByClassName('service-desc');
for (var j = 0; j < servicedesc.length; j++) {
servicedesc[j].classList.toggle('p-hide');
}
});
}
Demo:
http://jsfiddle.net/4GgRY/
I need the solution in vanilla JavaScript.
Hope this works
<html>
<head>
<title>internav</title>
<style type="text/css">
.hideclass{
display: none;
}
</style>
</head>
<body>
<div class="service" id="div1">
<h2 class="page services"><img class="img-bullet-services" src="websiteDot.png" alt="alt">service1</h2>
<p class="service-desc" id="service1">
xxxxxxxxxxxxxxxxxxxxxxxxxxxx<br>
xxxxxxxxxxxxxxxxxxxxxxxxxxxx<br>
xxxxxxxxxxxxxxxxxxxxxxxxxxxx<br>
</p>
</div>
</br>
<div class="service" id="div2">
<h2 class="page services"><img class="img-bullet-services" src="websiteDot.png" alt="alt">service2</h2>
<p class="service-desc" id="service2">
xxxxxxxxxxxxxxxxxxxxxxxxxxxx<br>
xxxxxxxxxxxxxxxxxxxxxxxxxxxx<br>
xxxxxxxxxxxxxxxxxxxxxxxxxxxx<br>
</p>
</div>
<div id="col4-footer" class="four-cols-footer four-cols">
<ul>
<li style="list-style: none;">
<h3><a class="a-bold" href="Services.php">Services</a></h3>
</li>
<li>service1
</li>
<li>seervice2
</li>
</ul>
</div>
<script type="text/javascript">
function toggle (link) {
target = link.getAttribute("data-toggle");
servides = document.getElementsByClassName('service-desc');//.className += " hideclass";
for (var i = servides.length - 1; i >= 0; i--) {
//servides[i].className -= " hideclass";
servides[i].className = "service-desc hideclass";
};
document.getElementById(target).className = "service-desc";
}
</script>
</body>
</html>
Hello mountainclimber,
I hope this helps you out.
If I understand your question correctly, you wish to be able to navigate to the anchors within the page and at the same time un-hide a previously hidden (or other) tag.
To that end I took your original example and developed a new version. It may not be the very best version in the world, but I think it accomplishes what you asked.
The pertinent changes are as follows.
JS:
var useQuerySelector = false;
//Shim from jscheuer1 -- http://www.dynamicdrive.com/forums/showthread.php?68847-Why-getelementsbyclassname-not-working-IE
if (!document.getElementsByClassName)
{
document.getElementsByClassName = function (cn)
{
var rx = new RegExp("(?:^|\\s)" + cn+ "(?:$|\\s)");
var allT = document.getElementsByTagName("*"), allCN = [],ac="", i = 0, a;
while (a = allT[i=i+1])
{
ac=a.className;
if ( ac && ac.indexOf(cn) !==-1)
{
if(ac===cn)
{
allCN[allCN.length] = a; continue;
}
rx.test(ac) ? (allCN[allCN.length] = a) : 0;
}
}
return allCN;
}
}
//My own feature "sniffing"
try
{
document.getElementByClassName('');
}
catch(ex)
{
useQuerySelector = true;
}
function navigateToAnchor(anchorObject)
{
var anchorName = anchorObject.href.substring(anchorObject.href.lastIndexOf("#")+1, anchorObject.href.length)
var tagObj = document.getElementById(anchorName);
var hiddenElements = (!useQuerySelector?tagObj.parentElement.getElementsByClassName("p-hide"):tagObj.parentElement.querySelectorAll(".p-hide"));
toggleElements(hiddenElements, false);
}
function toggleElements(hiddenElements, bHide)
{
var objCurrElement = null;
for (i = 0; i < hiddenElements.length; i++)
{
objCurrElement = hiddenElements[i];
if (objCurrElement != null && objCurrElement != 'undefined')
{
if (bHide)
{
//Add the p-hide class.
objCurrElement.className += "p-hide";
}
else
{
//Remove the p-hide class.
objCurrElement.className = objCurrElement.className.replace(/p\-hide/,'');
}
}
}
}
Alternatively, using a syntax I have never used before you could do it this way
JS:
function toggleElements(hiddenElements, bHide)
{
var objCurrElement = null;
for (i = 0; i < hiddenElements.length; i++)
{
objCurrElement = hiddenElements[i];
tmpObj = objCurrElement;
if (objCurrElement != null && objCurrElement != 'undefined')
{
if (bHide)
{
//Add the p-hide class.
objCurrElement.classList.add("p-hide");
}
else
{
//Remove the p-hide class.
objCurrElement.classList.remove("p-hide");
}
}
}
}
HTML:
<li>Service 1</li>
<li>Service 2</li>
That's what I have :) I have tested it clean in the latest version of FireFox and Chrome as well as IE 8 and 9.
Please let me know if it helps!
I asked the initial question and I got a good answer from g-newa, but here is an alternative (really a modification of what g-newa posted). To make it work you have to move the service1 and service2 ids up into the div:
js:
var target, sericeDiv, pToDisplay
function toggle(link) {
target = link.getAttribute("data-toggle");
sericeDiv = document.getElementById(target)
pToDisplay = sericeDiv.getElementsByTagName('p')[0]
pToDisplay.className = "p-on-white service-desc"
document.getElementById(target).className = "service-desc";
}
...seems to work. Just an alternative. Hope it helps. In words this is what it is doing: get data-toggle attribute value, use the data-toggle as an id to get the correct div, get the child p (paragraph) within the div, change the class so it is no longer includes p-hide class, move screen to the appropriate div.
If this not good in some way can you please let me know.
The complete solution INCLUDING links that work from the footer even when you AREN'T on the services page go here:
link to heading on different page and make paragraph visible from footer link while not on linked-to page