Javascript Hover Content Show - javascript

I am attempting to write a JS function (using prototype in rails) that will show hidden divs within a li when that li is mouseover'ed. Each li has a unique id that is a number, like so:
<li id="100">
<div style="display:none;" id="hover-display-content">Content</div>
<div style="display:none;" id="more-hover-display-content">Content</div>
<div style="display:none;" id="even-more-hover-display-content">Content</div>
</li>
I'm not sure how to go about doing this though, especially where the JS only shows the hidden elemenst for that specific li.
I'm thinking something like:
Event.observe(window, 'load', function() {
Event.observe($("li"), 'mouseover', function() {
var id = readAttribute("id")
id.getElementById("hover-display-content").style.display = "inline";
id.getElementById("more-hover-display-content").style.display = "inline";
id.getElementById("even-hover-display-content").style.display = "inline";
});
Event.observe($("li"), 'mouseout', function() {
var id = readAttribute("id")
id.getElementById("hover-display-content").style.display = "none";
id.getElementById("more-hover-display-content").style.display = "none";
id.getElementById("even-hover-display-content").style.display = "none";
});
});
But it doesn't seem to be working. Where am I going wrong?
Edit:
I am now using:
Event.observe(window, 'load', function() {
$$('li').invoke('observe', 'mouseover', function(event) {
this.children[0].toggle();
});
$$('li').invoke('observe', 'mouseout', function(event) {
document.children[0].toggle();
});
});
Which is partially working, however my code looks like the following:
<ul>
<li>
<div style="display:hidden;">Hidden Div</div>
<div>More content that isn't hidden</div>
</li>
</ul>
When I rollover the li it displays the hidden div, however if I rollover the second div it hides the comment again, even though this div is in the li. Why?

with a tag and hover? just providing an idea
<html>
<head>
<style>
a div{display:none; height:10px;}
a:hover div{display:inline;}
</style>
</head>
<body>
<ul>
<li><a>a<div id="hover-display-content">Content</div></a></li>
<li><a>s<div id="more-hover-display-content">Content1</div></a></li>
<li><a>d<div id="even-more-hover-display-content">Content2</div></a></li>
</ul>
</body>
</html>

Im not sure if this is your only issue but one key thing is that DOM id's cannot begin with a number, youll need to prefix that with something like model_name-100. Additionally, all id's need to be unique. So your inner content div's need to have those id's converted to classes like class="even-more-hover-display-content"... or alternatively you could jsut prefix the id with the id of the parent element like model_name-100-even-more-hover-display-content.

I would start with the .getElementByClass() --- deprecated in Proto 1.6
Link here.
As a fallback plan, here's a proof-of-concept in regular JS that works:
<li onmouseover="this.children[0].style.display = 'inline';
this.children[1].style.display = 'inline';">
<div id="testdiv" style="display:none;background:blue">test</div>
<div id="testdiv" style="display:none;background:blue">test</div>
</li>

using jquery
$('#id').each(function(){
$(this).css({diplay:'inline'});});
isn't that simple . .

Related

Jquery show/hide divs - fix overlapping animations

I am using JS to show/hide divs via clicking on the side nav with jquery functions fadeIn() and fadeOut(). The problem I run into is as one div fades out, the next is fading in simultaneously. Also, if I click the link for the div that is already shown, it fades out and fades in again. I'm not sure if an IF statement would be the best approach to do two fixes:
1. Let shown div fully fadeOut before next starts to fadeIn.
2. Currently shown div will not fadeOut/In if same link is clicked.
Here is what I have thus far (without my broken attempt at an IF statement):
http://jsfiddle.net/k55Cw/1/
HTML:
<div class="container">
<header>
<ul class="sidenav">
<li><h2><a data-region="nav-1" href="#">About</a></h2></li>
<li><h2><a data-region="nav-2" href="#">Services</a></h2></li>
<li><h2><a data-region="nav-3" href="#">Team</a></h2></li>
<li><h2><a data-region="nav-4" href="#">News</a></h2></li>
<li><h2><a data-region="nav-5" href="#">Contact</a></h2></li>
</ul>
</header>
<div id="nav-1" class="infozone"><p>Hello I'm box 1.</p></div>
<div id="nav-2" class="infozone"><p>Hello I'm box 2.</p></div>
<div id="nav-3" class="infozone"><p>Hello I'm box 3.</p></div>
<div id="nav-4" class="infozone"><p>Hello I'm box 4.</p></div>
<div id="nav-5" class="infozone"><p>Hello I'm box 5.</p></div>
</div>
CSS:
.infozone{
float:left;
height:400px;
width:800px;
background-color: #000;
display:none;
}
JS:
$(document).ready(function() {
$('.sidenav a').click(function(){
$('.infozone').fadeOut(850);
var region = $(this).attr('data-region');
$('#' + region).fadeIn(850);
});
});
to chain the animations put the fadeIn inside the callback for fadeOut, and to cancel the function if it's currently shown, check if the div is already visible.
I've also had to add a check to see if the current .infozone div is visible - or else the fadeOut applies to hidden elements too, and the callback fires multiple times:
$(document).ready(function() {
$('.sidenav a').click(function(){
var region = $(this).attr('data-region');
var $region = $('#' + region);
if ($region.is(':visible')) return;
var $infozone = $('.infozone:visible');
if ($infozone.length === 0) {
$region.fadeIn(850);
} else {
$infozone.fadeOut(850, function() {
$region.fadeIn(850);
});
}
});
});
You could something like that:
html
This make you page works when javascript is disabled:
<header>
<ul class="sidenav">
<li><h2>About</h2></li>
<li><h2>Services</h2></li>
<li><h2>Team</h2></li>
<li><h2>News</h2></li>
<li><h2>Contact</h2></li>
</ul>
</header>
note that the href point to the id you want to show. This will works also for screen reader if you want to make your page accessible.
javascript. I have not tested it, you might have to fix few things, but the idea is there
$(document).ready(function() {
$('.sidenav a').click(function(e){
var href = $(this).attr('href');
// prevent default
e.preventDefault();
// prevent clicked twice
if(!$(this).hasClass('active'){
$('.sidenav a').removeClass('active');
$(this).addClass('active'){
$('.infozone').fadeOut(850);
$(href.substring(1)).fadeIn(850);
}
});
You should also consider adding some ARIA attributes and roles attributes.

Changing a div's id on click

How do I add an onClick listener to a div.
I want to change the name of a div to divclass active if it was inactive previously & then remove the word 'active' if user click on the list again.
I'm at a loss how to do this.
This is what I've tried so far
<script>
$function tog(){
$(this).toggleClass('active');
return false;
}
$(function() {
var dd = new DropDown( $('#dd') );
$(document).click(function() {
// all dropdowns
$('.wrapper-dropdown-4').removeClass('active');
});
});
</script>
where the div whose class name I want to change is defined as below
<div id="dd" onclick="tog()" class="wrapper-dropdown-4">
<!--something-->
</div>
I've tried this..
<html>
<head>
<script>
$('#dd').on('click', function(){
$(this).toggleClass('active')
});
</script>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<div id="dd" class="wrapper-dropdown-4">
ddddd
</div>
</body>
</html>
What's wrong with this now?
I'm inspecting the element id via chrome developer's tool & I don't see any change using this code. So, can anyone please help?
Thanks. :)
The only script you need is
$(function(){
$('#dd').on('click', function(){
$(this).toggleClass('active')
});
});
Demo: Fiddle
you have to pass the object $(this) is not recognizable , use tog(this)
<script>
function tog(obj)
{
$(obj).toggleClass('active');
return false;
}
$(function() {
var dd = new DropDown( $('#dd') );
$(document).click(function() {
// all dropdowns
$('.wrapper-dropdown-4').removeClass('active');
});
});
</script>
<div id="dd" onclick="tog(this)" class="wrapper-dropdown-4">
<!--something-->
</div>
not the best way to do it, you can bind the event ,by registering the click in the event.

Conflict between some JavaScript and jQuery on same page

I am using a JavaScript function and some jQuery to perform two actions on a page. The first is a simple JS function to hide/show divs and change the active state of a tab:
This is the JS that show/hides divs and changes the active state on some tabs:
var ids=new Array('section1','section2','section3');
function switchid(id, el){
hideallids();
showdiv(id);
var li = el.parentNode.parentNode.childNodes[0];
while (li) {
if (!li.tagName || li.tagName.toLowerCase() != "li")
li = li.nextSibling; // skip the text node
if (li) {
li.className = "";
li = li.nextSibling;
}
}
el.parentNode.className = "active";
}
function hideallids(){
//loop through the array and hide each element by id
for (var i=0;i<ids.length;i++){
hidediv(ids[i]);
}
}
function hidediv(id) {
//safe function to hide an element with a specified id
document.getElementById(id).style.display = 'none';
}
function showdiv(id) {
//safe function to show an element with a specified id
document.getElementById(id).style.display = 'block';
}
The html:
<ul>
<li class="active"><a onclick="switchid('section1', this);return false;">ONE</a></li>
<li><a onclick="switchid('section2', this);return false;">TWO</a></li>
<li><a onclick="switchid('section3', this);return false;">THREE</a></li>
</ul>
<div id="section1" style="display:block;">TEST</div>
<div id="section2" style="display:none;">TEST 2</div>
<div id="section3" style="display:none;">TEST 3</div>
Now the problem....
I've added the jQuery image gallery called galleria to one of the tabs. The gallery works great when it resides in the div that is intially set to display:block. However, when it is in one of the divs that is set to display: none; part of the gallery doesn't work when the div is toggled to be visible. Specifically, the following css ceases to be written (this is created by galleria jQuery):
element.style {
display:block;
height:50px;
margin-left:-17px;
width:auto;
}
For the life of me, I can't figure out why the gallery fails when it's div is set to display: none. Since this declaration is overwritten when a tab is clicked (via the Javascript functions above), why would this cause a problem? As I mentioned, it works perfectly when it lives the in display: block; div.
Any ideas? I don't expect anybody to be familiar with the jQuery galleria image gallery... but perhaps an idea of how one might repair this problem?
Thanks!
If you are including jQuery then you can shorten your javascript to this:
$(function() {
var sections = $('#section1, #section2, #section3');
function switchid(id, el){
sections.hide();
$('#'+id).show();
$(this).addClass('active').closest('ul').find('li').removeClass('active');
}
});
I would also remove the inline styles that set display:none. Then you can in your javascript you can initialize galleria then hide your sections.
Something like:
$(function() {
$('#section2, #section3').hide();
$('#section2 .images').galleria();
var sections = $('#section1, #section2, #section3');
function switchid(id, el){
sections.hide();
$('#'+id).show();
$(this).addClass('active').closest('ul').find('li').removeClass('active');
}
});
I would even go further and change your html to be something like this:
<ul class="sectionlinks">
<li class="active">ONE</li>
<li>TWO</li>
<li>THREE</li>
</ul>
<div id="section1" class="section">TEST</div>
<div id="section2" class="section">TEST 2</div>
<div id="section3" class="section">TEST 3</div>
Then you javascript could just be:
$(function() {
$('#section2 .images').galleria();
$('#section2, #section3').hide();
var sections = $('.section');
$('.sectionlinks a').click(function(e){
e.preventDefault();
sections.hide();
$($(this).attr('href')).show();
$(this).closest('ul').find('li').removeClass('active');
$(this).closest('li').addClass('active');
});
});
Working example: http://jsfiddle.net/cdaRu/2/
Set them all to 'block' by default, initialize the galleria image gallery, and afterwards hide the divs you want hidden and see if that fixes it. Or try initializing the gallery again after every switchid.
My first recommendation would be to re-write your original Javascript function to use jQuery. It already has built-in visibility toggle functions ... using the same system will minimize conflicts and make for smoother code.
This is just "off the cuff" but perhaps the box model is incomplete: "The element will generate no box at all" with display: none;
Perhaps change that back to "block" and set visibility: hidden; would be better?

Hiding a dropdown menu without it flashing with prototype

I have a number of dropdowns and divs that are hidden when the page loads and can be toggled with a click or mouseover, but some of them flash b/c the JavaScript does not run in time. I have their display initially set to block and then I use JavaScript/prototype to find the element and hide it. I have tried loading these "hider" functions using dom:loaded but there is still flashing. This is an example of a dropdown prototype initialization function. From
http://www.makesites.cc/programming/by-makis/simple-drop-down-menu-with-prototype/:
var DropDownMenu = Class.create();
DropDownMenu.prototype = {
initialize: function(menuElement) {
menuElement.childElements().each(function(node){
// if there is a submenu
var submenu = $A(node.getElementsByTagName("ul")).first();
if(submenu != null){
// make sub-menu invisible
Element.extend(submenu).setStyle({display: 'none'});
// toggle the visibility of the submenu
node.onmouseover = node.onmouseout = function(){
Element.toggle(submenu);
}
}
});
}
};
Is there a better way to hide div's or dropdowns to avoid this flashing?
You always run the risk of flicker when you try to hide elements after page load.
I suggest you give the elements in question an inline style like display:none; or a css class with the same setting.
From the class creation syntax used, I take it that you are using something like Prototype version 1.5.x. Here's my take on how I'd do it with that version (it would be nicer to step up to the latest version, of course):
<script type="text/javascript">
var DropDownMenu = Class.create();
DropDownMenu.prototype = {
initialize: function(menuElement) {
// Instead of using 2 listeners for every menu, listen for
// mouse-ing on the menu-container itself.
// Then, find the actual menu to toggle when handling the event.
$(menuElement).observe('mouseout', DropDownMenu.menuToggle);
$(menuElement).observe('mouseover', DropDownMenu.menuToggle);
}
};
DropDownMenu.menuToggle = function (event) {
var menu = DropDownMenu._findMenuElement(event);
if (menu) {Element.toggle(menu);}
};
DropDownMenu._findMenuElement = function (event) {
var element = Event.element(event);
return Element.down(element, 'ul');
}
var toggler = new DropDownMenu('menus');
</script>
And here is some markup to test it with (it may not match yours perfectly, but I think it is similar enough):
<html>
<head>
<title>menu stuff</title>
<style type="text/css ">
/* minimal css */
#menus ul, .menu-type {float: left;width: 10em;}
</style>
</head>
<body>
<h1>Menus</h1>
<div id="menus">
<div class="menu-type">
Numeric
<ul style="display: none;">
<li>1</li><li>2</li><li>3</li><li>4</li>
</ul>
</div>
<div class="menu-type">
Alpha
<ul style="display: none;">
<li>a</li><li>b</li><li>c</li><li>d</li>
</ul>
</div>
<div class="menu-type">
Roman
<ul style="display: none;">
<li>I</li><li>II</li><li>III</li><li>IV</li>
</ul>
</div>
</div>
</body>
</html>
Yoda voice: "Include the prototype.js, I forgot."
Should you want to get rid of inline styling (like I do), give the uls a class like
.hidden {display:none;}
instead, and make the DropDownMenu.menuToggle function do this
if (menu) {Element.toggleClassName(menu, 'hidden');}
instead of toggling the display property directly.
Hope this helps.
Set the display initially to none, then show them as needed. That will get rid of the flashing.

Javascript creating <div> on the fly

I have a a link that looks similar to this
Blog
As you can the link has an ID of 'blog' what I want to do is to create an div on the fly with the ID from the link that was clicked so if the 'blog' is clicked, then the markup would be
<div id="blog">
<!--some content here-->
</div>
Like wise if for instance the news link is clicked then I would like,
<div id="news">
<!--some content here-->
</div>
to be created in the markup if this possible? and how Im pretty new to jQuery.
Try this:
$("a").click(function(){
$("#wrapper").append("<div id=" + this.id + "></div>");
});
Not tested, should work ;)
where: #wrapper is parent element, work on all a as you see.
You will need to give the div a different ID. Perhaps you could give it a class instead:
$("#blog").click(function() {
$(this).after("<div class='blog'>...</div>");
return false;
});
That's just one of many ways to create a div. You probably also want to avoid duplicates however in which case, use something like this:
$("#blog").click(function() {
var content = $("#blog_content");
if (content.length == 0) {
content = $("<div></div>").attr("id", "blog_content");
$(this).after(content);
}
content.html("...");
return false;
});
As for how to handle multiple such links I would do something like this:
Blog
News
Weather
<div id="content"></div>
with:
$("a.content").click(function() {
$("#content").load('/content/' + this.id, function() {
$(this).fadeIn();
});
return false;
});
The point is this one event handler handles all the links. It's done cleanly with classes for the selector and IDs to identify them and it avoids too much DOOM manipulation. If you want each of these things in a separate <div> I would statically create each of them rather than creating them dynamically. Hide them if you don't need to see them.
Try This :
<a id="blog">Blog</a>
<a id="news">news</a>
<a id="test1">test1</a>
<a id="test2">test2</a>
$('a').click(function()
{
$('<div/>',{
id : this.id,
text : "you have clicked on : " + this.id
}).appendTo("#" + this.id);
});
First of all you should not make 2 elements with same ID. At your example a and div will both have id="blog". Not XHTML compliant, plus might mess up you JS code if u refernce them.
Here comes non-jquery solution (add this within script tags):
function addDiv (linkElement) {
var div = document.createElement('div');
div.id = linkElement.id;
div.innerHTML = '<!--some content here-->';
document.body.appendChild(div); // adds element to body
}
Then add to HTML element an "event handler":
Blog
This question describes how to create a div. However, you shouldn't have two elements with same IDs. Is there any reason why you can't give it an id like content_blog, or content_news?
Unfortunately if you click on a link the page you go to has no idea what the idea of the link you clicked was. The only information it knows is what's contained in the URL. A better way to do this would be to use the querystring:
Blog
Then using the jQuery querystring plugin you could create the div like:
$("wrapper").add("div").attr("id", $.query.get("id"));
You shouldn't have elements in your page with the same ID. Use a prefix if you like, or perhaps a class.
However, the answer is as follows. I am imagining that your clickable links are within a div with the ID "menu", and your on-the-fly divs are to be created within a div with the ID "content".
$('div#menu a').click(function(){
$('div#content').append('<div id="content_'+this.id+'"><!-- some content here --></div>');
});
Any problems, ask in the comments!
Also the following statement is available to create a div dynamically.
$("<div>Hello</div>").appendTo('.appendTo');
Working fiddle: https://jsfiddle.net/andreitodorut/xbym0bsu/
you can try this code
$('body').on('click', '#btn', function() {
$($('<div>').text('NewDive').appendTo("#old")).fadeOut(0).fadeIn(1000);
})
#old > div{
width: 100px;
background: gray;
color: white;
height: 20px;
font: 12px;
padding-left: 4px;
line-height: 20px;
margin: 3px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div>
<!-- Button trigger modal -->
<button type="button" id="btn">Create Div</button>
<div id="old">
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</body>
</html>

Categories