I'm building a Help Center for a website and I'd like to do something like Facebook does on their Help Centre site:
https://www.facebook.com/help
As you can see, there's a menu on the left hand side. When clicking on a section that has an arrow to the right of the menu item, the subpages for that section slide in. You can keep on clicking subpages and get their nested children. It also gives you the ability to go back to the previous parents.
I have been looking around and can't find anything like it... maybe I'm not looking for the right thing as I'm looking for things like "jQuery/Javascript sliding menu" etc etc, but most results are related to mobile menus, which is not what I'm looking for.
Anyone has come across anything similar? Just need a starting point really.
Thanks a lot!
After looking and looking I decided to give it a try and write it from scratch... and I got it to work! :)
It's a bit hacky as I'm quite new to jQuery so if anyone wants to improve it feel free.
Let me know if you have any questions or ways to improve it.
Here's the jQuery:
jQuery(document).ready(function() {
var content_height = jQuery(".column-right").height(); // Get height of main content
jQuery(".subnav").height(content_height); // Apply height to menu div
jQuery('a.forward').next().hide(); // Hide all children from the menu
jQuery('a.forward').click(function(e) { // On click .forward
e.preventDefault();
// Clone next child, append to container, position absolute and animate left
jQuery(this).next().clone(true, true).appendTo(".subnav").css({position: "absolute", left:"191px", top:"0", display:"block"}).animate({
left:"0"
}, 300);
// Animate current menu out sight
jQuery(this).closest("ul").animate({
left:"-191px",
}, 300);
return false
});
jQuery('a.back').click(function(e) { // On click .back
e.preventDefault();
// Animate the previous hidden element so it comes back
jQuery(this).closest("ul").prev().animate({
left:"0",
}, 300);
// Animate current menu out of sight to the right
// and remove after animation is completed
jQuery(this).closest("ul").animate({
left:"191px",
}, 300, "linear",function(){jQuery(this).remove()});
return false;
});
});
And here's the fiddle with some CSS and HTML:
http://jsfiddle.net/Mh35b/
Cheers
Modified the above post to make it more dynamic.
// Code goes here
var PANEL_WIDTH = 235;
$(function() {
$(".help-section").css("width", (PANEL_WIDTH * 2) + "px")
$(".help-subsection, .help-question-panel, .help-left-panel").css("width", PANEL_WIDTH + "px");
$(".help-subsection>li:not(.help-section-back)>a").click(function(e) {
$(".help-question-panel").html($("ul", $(e.target).parent()).html());
$(".help-question-panel").append("<li><a href='#' onclick='clickBack(event)' data-target='back'>Back</a></li>");
$(".help-subsection").animate({
"margin-left": "-" + PANEL_WIDTH + "px"
}, 300);
});
$("a[data-target='question']").on("click", function(e) {
console.log("test");
});
});
function clickBack(e) {
$(".help-subsection").animate({
"margin-left": "0px"
}, 200, function() {
$(".help-question-panel").html("");
});
}
.help-subsection {
width: 300px;
min-height: 100px;
border: 1px solid #cdcdcd;
border-radius: 7px;
margin-top: 10px;
margin-bottom: 10px;
margin-right: 0px;
margin-left: 0px;
padding: 5px;
line-height: 1.2em;
float: left;
}
.help-question-panel {
width: 300px;
min-height: 100px;
border: 1px solid #cdcdcd;
border-radius: 7px;
float: left;
margin-top: 10px;
margin-bottom: 10px;
margin-right: 0px;
margin-left: 0px;
padding: 5px;
line-height: 1.2em;
}
.help-section {
width: 600px;
}
.help-left-panel {
width: 300px;
margin-left: 20px;
overflow: hidden;
}
.help-left-panel li {
list-style: none;
padding-top: 15px;
padding-bottom: 15px;
/*border-bottom: 1px solid #cdcdcd;*/
}
.help-left-panel li:not(:last-child) {
border-bottom: 1px solid #cdcdcd;
}
.help-question-coll {
display: none;
}
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<h3>Facebook Help Like Left Sliding Menu</h3>
<div class="help-left-panel">
<div class="help-section">
<ul class="help-subsection">
<li>
Menu Item 1
<ul class="help-question-coll">
<li>This can be a realy really long question?
</li>
<li>I cannot anticipate how long this question will be! but it can be really really long.
</li>
<li>Question 1.3
</li>
<li>Question 1.4
</li>
</ul>
</li>
<li>
Menu Item 2
<ul class="help-question-coll">
<li>Question 2.1
</li>
<li>Question 2.2
</li>
<li>Question 2.3
</li>
<li>Question 2.4
</li>
</ul>
</li>
<li>
Menu Item 3
<ul class="help-question-coll">
<li>Question 3.1
</li>
<li>Question 3.2
</li>
<li>Question 3.3
</li>
<li>Question 3.4
</li>
</ul>
</li>
<li class="help-section-back">
Back
</li>
</ul>
<ul class="help-question-panel">
</ul>
</div>
</div>
</body>
Related
On my user interface I have a breadcrumb of which shows on the top bar. Upon the device width being below a defined width, it'll drop below the top bar and be it's own bar, however what I do not know how to do is add a trailing ellipsis upon the breadcrumb length being larger than the device width.
Example Breadcrumb:
<nav>
<ul>
<li>Home</li>
<li>>></li>
<li>User</li>
<li>>></li>
<li>Inbox</li>
<li>>></li>
<li>Mail_ID</li>
</ul>
</nav>
Note: >> represents a FontAwesome icon in an i tag
Upon the breadcrumb being larger than the device width, the best I can describe what I would like to happen is demonstrated below:
Home >> User >> Inbox >> Mail_ID
... User >> Inbox >> Mail_ID
... Inbox >> Mail_ID
... Mail_ID
This is still a partial code but might help you.
Idea
On load, call a function that checks for with of ul and its parent container.
If ul has greater width, hide first 2 visible li. Also add an li for ellipsis and make it hidden initially and make it visible only if any of other divs are hidden.
Repeat this process recursively and you will get what you are looking for.
Sample
$(function() {
$(".content").resizable();
$(".content").on("resize", function() {
var ul = $(this).find('ul');
if (ul.width() > $(this).width()) {
var lis = ul.find('li:not(.hide):not(.ellipsis)');
for (var i = 0; i < 2; i++) {
$(lis[i]).addClass("hide");
}
if ($(".ellipsis").not(":visible"))
$(".ellipsis").removeClass("hide")
}
})
});
.content {
text-align: left;
border: 1px solid gray;
width: 300px;
height: 40px;
max-height: 40px;
}
.content ul {
padding: 0px;
position: fixed;
overflow: hidden;
white-space: nowrap;
}
.content ul li {
display: inline-block;
text-decoration: none;
}
.hide {
display: none!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="content">
<ul>
<li class="hide ellipsis">...</li>
<li>Home</li>
<li>>></li>
<li>User</li>
<li>>></li>
<li>Inbox</li>
<li>>></li>
<li>Mail_ID</li>
</ul>
</div>
You can try to use the CSS-only ellipsis, but I don't know if it also works with <ul><li>. For sure it works with simple strings:
Use this HTML:
<ul class="ellipsis">
And this CSS:
ul.ellipsis
{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
I am trying to do an overview page on my website so that when I hover over a div on the overview page different sections of that div show different images. Essentially a slideshow but the image changes depending on where the cursor is.
I have managed to find some code that does what I want but it uses an a href to pull in the images which means if you click it, it goes to the link of the image.
Currently I just have placeholder images in but when finished each one will have specific project images in. As each div will just be one project the whole div should go to one html link and not just a specific image link of the image the user is hovering over.
All I want is the user to click and it go to a html link and not an img link.
Here is the code I am using:
The coding savvy people out there will probably have a much better solution for what I would like to achieve, I am interested to see any better solutions.
HTML
<div class="multi">
<ul class="rotator-nav fifth clearfix">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="imgcontent">
<ul class="rotator-icons fifth">
<span class="img1 active"></span>
<span class="img2"></span>
<span class="img3"></span>
<span class="img4"></span>
<span class="img5"></span>
</ul>
<img src="/img/FoI.jpg" class="currentimg">
</div>
</div>
CSS
.multi {
display: block;
float:left;
position: relative;
width: 30.8%;
height: 20%;
padding: 0px;
margin:0% 1% 2% 1%;
overflow: hidden;
}
.multi .imgcontent {
display: block;
position: absolute;
top: 0px;
}
.imgcontent img {
display:block;
width: 100%;
height: auto;
margin-left: auto;
margin-right: auto;
}
.rotator-nav {
display: block;
position: relative;
width: 100%;
height: 100%;
z-index: 9;
}
.rotator-nav li {
display: block;
float: left;
height: 100%;
}
.rotator-nav.fourth li {
width: 25%;
}
.rotator-nav.fifth li {
width: 20%;
}
.rotator-nav li a {
display: block;
float: left;
width: 100%;
height: 100%;
border-bottom:0px solid #fff
}
.clearfix:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }
.clearfix { display: inline-block; }
html[xmlns] .clearfix { display: block; }
* html .clearfix { height: 1%; }
JS
$(function(){
var $rotators = $('.multi');
var $imglinks = $('.rotator-nav a');
$imglinks.on('mouseenter', function(e){
var imgclass = '.'+$(this).attr('class');
var imglink = $(this).attr('href');
// update main image src
$(this).parent().parent().parent().find('.currentimg').attr('src',imglink);
// update current rotator icon
var $rotators = $(this).parent().parent().parent().find('.rotator-icons');
if($rotators.children(imgclass).hasClass('active')) {
// already active icon -- do nothing
} else {
// remove active class then add to new icon
$rotators.children('span').removeClass('active');
$rotators.children(imgclass).addClass('active');
}
});
});
Any help would be greatly appreciated!
Thanks,
Mark
I think you could best use a data attribute for this instead (if I understand the intention correctly) :
var imglink = $(this).data('image');
<div class="multi">
<ul class="rotator-nav fifth clearfix">
<li>
<a data-image="/img/FoI.jpg" href="#" class="img1"></a>
</li>
<li>
<a data-image="/images/card.jpg" href="#" class="img2"></a>
</li>
<li>
<a data-image="/images/amareal.jpg" href="#" class="img3"></a>
</li>
<li>
<a data-image="/images/edeva.jpg" href="#" class="img4"></a>
</li>
<li>
<a data-image="/images/amacover2.gif" href="#" class="img5"></a>
</li>
</ul>
...
If you'd still like to see the image over the original div, a pseudo element could be used. Advantage there is that they are not actual DOM elements and will not register clicks :
Demo
Now it would be great if the data attribute could be directly used for the content of the pseudo element as well but that doesn't seem possible. And you can't target them with JavaScript so each image would have to be defined with nth-of-type() in the stylesheet additionally.
You don't need to use .parent().parent()
Just use the parent's class to find the item.
Your $(this).parent() * 3 is the $(".multi")
So your $rotators can't find .rotator-icons,
you need to use one more parent or use siblings
And I suggest do not use class if there are no need to do one thing to lots of items.
I recently saw a navigation effect I liked on a website, but can't find it to check the code and see how it was done. There was a standard menu bar that was 100% width and aprox 30px in height, with each link equally spaced within it. When you hovered on the gallery link the whole menu bar changed and the links were replaced with the submenu. No dropdown, the whole menu bar was changed to the submenu items. I can't quite sort out how this was done. Any suggestions would be appreciated. Here is the example html markup I am working with:
<nav>
<ul class ="menu">
<li class ="nav__item">about</li>
<li class ="nav__item">galleries
<ul class="submenu">
<li class ="nav__subitem">one</li>
<li class ="nav__subitem">two</li>
<li class ="nav__subitem">three</li>
<li class ="nav__subitem">four</li>
<li class ="nav__subitem">five</li>
<li class ="nav__subitem">six</li>
</ul> <!-- close sub -->
</li>
<li class ="nav__item">stories</li>
<li class ="nav__item">contact</li>
<li class ="nav__item">thank you</li>
</ul>
</nav>
Not sure if this is what you are looking for but check out this fiddle
Setting a fixed height to the navigation with relative positioning and targeting the parent of the nested ul on mouse over I was able to achieve this effect.
nav {
height: 50px;
overflow: hidden;
position: relative;
background: #999999;
}
.menu {
list-style-type:none;
position: relative;
}
ul {
padding: 0;
margin: 0;
}
li.nav__item {
float:left;
}
li.nav__item a {
padding: 0 15px;
line-height:50px;
}
.submenu {
position:absolute;
left:15px;
}
.nav__subitem {
line-height: 50px;
float: left;
list-style: outside none none;
}
And the little bit of jQuery magic to tie it all together.
$(".has-children").mouseover(function () {
$(".menu").css("top", "-50px");
});
$(".main-navigation").mouseleave(function () {
$(".menu").css("top", "0px");
});
I'm working on an interface and I require something that would stick two unrelated elements together. Well, the most important element will be the "boss" and the other element called "employee" will follow the "boss" around and will change it's position accordingly.
This is the markup:
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
This is the jQuery I wrote:
$('.boss').each(function( i, obj ){
var Pos = $(this).position();
var ModuleWidth = $(this).outerWidth();
$(this).next('.employee').position({
my: 'right top',
at: 'right top',
of: $(this)
});
});
So I'm iterating through all the .boss classes and aligning all .employees to the right top of boss. They are supposed to always stick. But if I edit the html from the boss within chrome Developer Tools the .boss element will become smaller and larger and the .employee will not re-position its self accordingly. I would like to make .employee always reposition its self.
Later Update:
This http://screencast.com/t/F0RO7ODF is the kind of behavior i'm looking for. The gray box is the BOSS and the orange box is the EMPLOYEE. These 2 element's have a wrapper and i'm actually moving the wrapper. But i'd like a solution without a wrapper. Note: The organge box's position is irelevant.
I know this has been answered already, but here is an alternative which does not use any hierarchy between the two elements (even though that might not be the best practice):
HTML:
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
JS:
$.fn.invisible = function() {
return this.css("visibility", "hidden");
};
$.fn.visible = function() {
return this.css("visibility", "visible");
};
$(".boss").draggable({
stop:function(e) {
var employee_horizontal_position= $(this).offset().left+$(this).width();
var employee_vertical_position= $(this).offset().top-$(this).height();
$(this).next().visible();
$(this).next().offset({top: employee_vertical_position, left: employee_horizontal_position});
}
});
$(".boss").on("drag", function(e){
$(this).next().invisible();
});
CSS:
.boss{
height: 100px;
width: 300px;
background-color: grey;
float:left;
margin-top:100px;
}
.boss:hover{
cursor:pointer;
}
.employee{
height: 300px;
width: 100px;
background-color: orange;
float:left;
}
JSFIDDLE EXAMPLE: http://jsfiddle.net/ktxo4f6s/2/
I tried to make the employee hidden while the boss is being dragged as shown in your screencast.
n general when wanting elements to be in relation with each other they should be grouped together within an element.
To represent hierarchies it is best to also develop your html to honor the hierarchy you wish to represent.
This will force the behavior as you displayed in the video when moving the boss element.
For this particular example it may also be expanded upon with departments or roles.
See JSFiddle for example: http://jsfiddle.net/9dw5dvqw/
Updated: http://jsfiddle.net/en85bm9h/
HTML
<ul class="bosses">
<li class="boss">
<span class="boss-name"></span>
<ul class="employees">
<li class="employee">
<span class="employee-name"></span>
</li>
<li class="employee">
<span class="employee-name"></span>
</li>
</ul>
</li>
<li class="boss">
<span class="boss-name"></span>
<ul class="employees">
<li class="employee">
<span class="employee-name"></span>
</li>
<li class="employee">
<span class="employee-name"></span>
</li>
</ul>
</li>
</ul>
CSS
*{ margin: 0; padding: 0; }
body,
html{ height: 100%; }
ul{ list-style: none; overflow: hidden; float: left; }
li{ overflow: hidden; }
.bosses{ width: 100%; height: 100%; }
.boss{ margin: 20px 5px 20px 0; float: left; }
.boss-name{ display: block; background-color: #eee; float: left; width: 120px; height: 80px; cursor: move; }
.employees{ float: left; width: 50px; height: 120px; background-color: red; }
I have an idea for my personal website layout. I'd like stacked menu items on the left side (with like 10% width) and content on the right side. By 'vertical abacus' (the original calculator with beads on a rod), I'd like menu items to appear as boxes of varying colors with a set height for each box. Because they're a set height, there will be a large portion of empty space (colored depending on what menu you select).
Utilizing the new HTML5/CSS3, I'd like to know how I'd go about creating the menu so that when you select an item, that particular item (and the items above it) slide up and stack to the top, while changing the color of the empty space below it according to the color of the respective menu item. When a menu item that is stacked at the top is selected, the items stacked below it will move back down to their original position.
First visit to the website:
After clicking 'Page2':
(I'm such an excellent MSPaint artist, I know.)
Did I lose anyone yet? :)
Would I have to tweak this process with Javascript?
I'm not asking someone to code it for me (though obviously welcome), I just have no idea where to start since W3Schools.com is frowned upon and I have an amateur knowledge of the new features in HTML5/CSS3. Would something as seemingly simple as this be difficult to begin with?
Any help is greatly appreciated! :)
Create a Fiddle for you:
http://jsfiddle.net/M8bQH/
Please adapt Width/Height and colors to your needs!
HTML:
<div id="container">
<div id="sideBar">
<ul id="myMenu">
<li class="topic1 activeItem">Home</li>
<li class="topic2">Page 2</li>
<li class="topic3">Page 3</li>
</ul>
</div>
<div class="mainContent activeContent">
Content1
</div>
<div class="mainContent">
Content2
</div>
<div class="mainContent">
Content3
</div>
</div>
JavaScript (jQuery needed!)
$('#myMenu li').click(function(){
// Set active menu item
$('#myMenu li').removeClass('activeItem');
$(this).addClass('activeItem');
// Set active content according to item
$('.mainContent').removeClass('activeContent');
$('.mainContent').eq($(this).index()).addClass('activeContent');
// Adapt background color of content according to item
$('.mainContent.activeContent').css('background-color', $(this).css('background-color'));
});
CSS:
#container {
width: 800px;
height: 600px;
}
#myMenu {
list-style-type:none;
padding: 0;
margin: 0;
}
#myMenu li {
width: 100px;
height:48px;
border-bottom: 5px solid black;
-webkit-transition: height linear 0.5s; /* For Safari 3.1 to 6.0 */
transition: height linear 0.5s;
}
#myMenu li:last-child {
border-bottom: 0px;
}
#sideBar {
width: 100px;
height: 600px;
float:left;
border-right: 5px solid black;
}
.mainContent {
width: 700px;
height: 100%;
background-color: gray;
display: none;
}
.topic1 {
background-color: gray;
}
.topic2 {
background-color: #33CCFF;
}
.topic3 {
background-color: #99FF00;
}
.activeItem {
height: 494px !important;
}
.activeContent {
display: block !important;
}