I wanted to create an effect where the whole body gets blurred or dimmed and only a particular list item appears clear. However when I set the z-index to the list item, it doesn't work. And when I set the z-index of the whole un-ordered list, it works but the all the list items appear clear (which I don't want).
Let me show you my html code:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ashish Toppo</title>
<link href="https://fonts.googleapis.com/css?family=Oxanium&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
</head>
<body >
<!-- the html for the top bar starts here -->
<div class="top_bar" id="topBar">
<div class="logo_name" id="logoName">Ashish Toppo</div>
<ul class="menu">
<li class="menu_items currently_active_menuItem" id="home">home</li>
<li class="menu_items" id="about">about</li>
<li class="menu_items" id="education">education</li>
</ul>
</div>
<!-- the html for the top bar ends here -->
<!-- the html for the intro starts here -->
<div class="intro" id="intro">
<div class="profile_pic" id="profilePic">
<img id="profileImg" src="images/ashish-toppo-green.jpg" width="100%" height="100%" alt="a picture of mine">
</div>
<div class="intro_box" id="introBox">
<!-- some introduction text here -->
<center id="aboutPointer">To know more about me, go to the about section!</center>
</div>
</div>
<!-- the html for the intro ends here -->
<script src="js/uiversal.js"></script>
<script src="js/index.js"></script>
</body>
</html>
Now, the Universal javaScript file:
/* this is a reusable js file universal to all web pages */
/* Ashish Toppo */
"use strict";
function get(id_or_class){
var obj = {
element: ( document.getElementById(id_or_class) ) ? document.getElementById(id_or_class) :
( document.getElementsByClassName(id_or_class) ) ? document.getElementsByClassName(id_or_class) :
( document.querySelector(id_or_class) ) ? document.querySelector(id_or_class) :
console.error("The provided HTML element could not be found"),
html: () => { return obj.element; },
changeText: (text) => { obj.html().innerHTML = text; },
appendText: (text) => {
let appendOn = obj.html().innerHTML;
obj.html().innerHTML = appendOn + text;
},
previousDisplayMode: "block",
hide: () => {
obj.previousDisplayMode = obj.html().style.display;
obj.html().style.display = "none";
},
show: () => {
obj.html().style.display = obj.previousDisplayMode;
},
on: (event, callBack) => {
obj.html().addEventListener(event, callBack);
},
previousZIndex: 1,
focusOn: () => {
let blur = document.createElement("div");
blur.className = "theDivThatBlurs";
blur.style.width ="100vw";
blur.style.height ="100vh";
blur.style.display ="block";
blur.style.position ="fixed";
blur.style.top ="0";
blur.style.left ="0";
blur.style.zIndex ="9";
blur.style.backgroundColor ="rgba(0, 0, 0, 0.9)";
blur.innerHTML = "";
document.body.appendChild(blur);
obj.html().style.zIndex = "100";
}
}
return obj;
}
and the index.js file was as followed:
/* my css wasn't working as i wanted, so i had to fix it using js */
"use strict";
(function(d){
const active = d.getElementsByClassName("currently_active_menuItem");
active[0].style.textDecoration = "none";
})(document);
var about = get("about");
var aboutPointer = get("aboutPointer");
aboutPointer.on("click", function(){
console.log("the about pointer has been clicked");
focus(about);
});
function focus(theElement){
console.log("the focus is working");
theElement.focusOn();
}
You can use the box-shadow property to achieve the dimming effect. Quick and easy :)
Just toggle a class programmatically and it should work for any element you have.
Code
function focusAndDim() {
document.getElementById("maindiv").classList.toggle("visible");
// if you want to get more fancy ;)
document.getElementsByTagName("body")[0].classList.toggle("blur");
}
.visible {
box-shadow: 0 0 0 10000px #ccc;
/* this code below make everything else hidden */
/* box-shadow: 0 0 0 10000px #fff; */
position: relative;
}
.btn {
height: 20px;
line-height: 1.4;
border: 2px solid #999;
padding: 12px 24px;
margin-bottom: 10px;
border-radius: 2px;
cursor: pointer;
}
body {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
height: 100vh;
}
body.blur div {
filter: blur(2px);
}
body.blur div.visible {
filter: blur(0);
}
<div class="btn" onclick="focusAndDim()" id="maindiv">Click Me</div>
<div>Other elements</div>
Related
Been working on a home automation dashboard and I need some help. How do I get the image to change when the button is toggled ON and OFF. I have a sun svg for on and moon svg for off.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard</title>
<!-- Add font from Google fonts -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght#300&display=swap" rel="stylesheet">
<!-- Link CSS style sheet to html document -->
<link rel="stylesheet" href="style.css">
<!-- Link JavaScript file to html document -->
<script src="mqttws31.js"></script>
<script src="dashboard.js"></script>
</head>
<body>
<div class="header">
<h1>Home Automation Dashboard</h1>
</div>
<hr>
<div id="messages"></div>
<div id="status"></div>
<hr>
<ul class="dashboard">
<ol class="b">
<li class="dashboard_item kitchen">
<img src="./moon.svg" width="40px" height="40px" alt="">
<h4>Kitchen</h4>
<p id="kitchen-light">OFF</p>
<button id="kitchen-btn">Toggle</button>
</li>
<ol class="b">
<li class="dashboard_item frontdoor" >
<img src="./door-closed.svg" width="40px" height="40px" alt="">
<h4>Front Door</h4>
<p>CLOSED</p>
</li>
</ul>
</body>
</html>
<!-- variable in js -->
var KitchenState = true;
var el = document.getElementById("kitchen-btn");
el.addEventListener('click', function() {
document.getElementById("kitchen-light").innerHTML = KitchenState ? "ON" : "OFF";
KitchenState = !KitchenState;
});
Been trying examples online with no luck so far.
Give some id attribute to the image and then change it in the same way like you are changing the innerHTML. For image you just need to change the src accordingly.
<script>
var KitchenState = true;
var el = document.getElementById("kitchen-btn");
el.addEventListener('click', function() {
document.getElementById("kitchen-light").innerHTML = KitchenState ? "ON" : "OFF";
document.getElementById('toggle-img').src = KitchenState ? './sun.svg' : './moon.svg'
KitchenState = !KitchenState;
});
</script>
<img src="./moon.svg" width="40px" id="toggle-img" height="40px" alt="">
use .setAttribute or .src
add id kitchen-icon to tag <img> icon
and try code:
var KitchenState = true;
var el = document.getElementById("kitchen-btn");
el.addEventListener('click', function() {
document.getElementById("kitchen-light").innerHTML = KitchenState ? "ON" : "OFF";
document.getElementById('kitchen-icon').src = KitchenState ? './moon.svg' : './sun.svg'
KitchenState = !KitchenState;
})
From the point of view of your question, I think you need the following code
let btnAll = document.getElementByTagName('button')
let conAll = document.getElementByClassName('content')
let btnAllLen = btnAll.length
//Create a callback function for the click event of each button
for (let i = 0; i < btnAllLen; i++) {
!(function(n) { // Register click events
btnAll[n].addEventListener('click', function() {
for (let j = 0; j < btnAlllen; j++) {
btn[j].className = ""
conAll[j].style.display = "none"
}
this.className = "active"
conAll[n].style.display = "block"
})
})(i)
}
.main {
text-align: center;
}
button:focus {
outline: none;
}
nav {
margin-top: 30px;
box-sizing: border-box;
}
button {
background: white;
border: none;
height: 36px;
line-height: 36px;
width: 80px;
text-align: center;
border: 1px solid lightgray;
border-radius: 4px;
cursor: pointer;
}
nav>button:not(:first-child) {
margin-left: 15px;
}
.active {
background: black;
color: white;
}
.content {
margin-top: 40px;
}
.content>p {
display: none;
}
<div class="main">
<nav>
<button class="active">content 1</button>
<button>content 2</button>
<button>content 3</button>
<button>content 4</button>
</nav>
<div class="content">
<p style="display: block;">content1</p>
<p>content2</p>
<p>content3</p>
<p>content4</p>
</div>
</div>
Trying to make my first project with bunch of pictures, with a filter/search bar at the top that would filter the pictures depending on the input. For example if the input would be "Aatrox", it would show "Aatrox" and not "Jayce" and or "Senna" and so on. Script was working fine, I added a .toLowerCase() so its not case sensitive and then I added to the pictures so they are clickable and each lead to their own page. After adding these two the search bar stopped working.
Here is the snippet of the script
<script>
function search(){
var searchText = (document.getElementById("searchInput").value).toLowerCase();
var images = document.querySelectorAll(".image_container > img");
if(searchText.length > 0){
images.forEach((image) => {
image.classList.add("hide");
if((image.dataset.tags).toLowerCase().indexOf(searchText) > -1){
image.classList.remove("hide");
}
});
}else{
images.forEach((image) => {
image.classList.remove("hide");
});
}
}
</script>
Here is the HTML part
<head>
<title> Counterpicks </title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1> Counterpicks pro debily </h1>
<div class="container">
<div class="searchbox_container">
<div class="searchbox">
<input type="text" name=" " placeholder="Search" class="search" id="searchInput" onkeyup="search()">
</div>
</div>
<div class="image_container">
<img data-tags="aatrox" src="aatrox.webp" alt="Aatrox" class="actionimages">
<img data-tags="ahri" src="ahri.webp" alt="Ahri" class="actionimages">
</div>
I input only few of the lines because they are just repeating for 130 lines.
And here is the CSS
.container {
background: rgba(0,0,0,0);
text-align: center;
margin-left: 20%;
margin-right: 20%;
}
.searchbox {
text-align: center;
margin-left: 20%;
margin-right: 20%;
margin-bottom: 20px;
}
.image_container {
clear:both;
}
.hide {
display:none;
This is my first project with JavaScript so I will be happy for any constructive criticism.
Replace:
var images = document.querySelectorAll(".image_container > img");
with:
var images = document.querySelectorAll(".image_container > a > img");
So, I was given a task of creating a Custom Flipbook, where using images in div tags, I was successful in creating one. Users could turn pages using prev/next buttons or flipping through them by the corners like shown for other Flipbooks.
My concern is Displaying PageNumbers. Changing pages through the buttons, pages change dynamically but when flipping through turn.js the page number does not update.
I am providing the snippet of the code that I have used. Any kind of help and guidance is appreciated !!
<!DOCTYPE html>
<head>
<title>Flipbook Demo</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script type="text/javascript" src="turn.min.js"></script>
</head>
<style>
body{
background-color: #313131;
}
#flipbook {
margin-top: 1.5%;
margin-left: 6%;
width: 1130px;
height: 800px;
position: relative;
overflow: hidden;
}
#nav_controls{
margin: 1.5%;
margin-left: 44%;
}
</style>
<body>
<h1 style="color: white; margin-left: 43%">FITI5 WHITEPAPER</h1>
<div id="flipbook">
<!-- Include Pages into div that you want to include -->
</div>
<div id="nav_controls">
<button id="startdoc"><-</button>
<button id="prev_page"> PREV </button>
<span id="pgnos" style="margin-left: 2%; color: white;">1</span>
<button id="next_page" style="margin-left: 2%;"> NEXT </button>
<button id="enddoc">-></button>
<!--
<button id="zoom-in">+</button>
<buton id="zoom-out">-</button>-->
</div>
<script type="text/javascript">
const startButton = document.querySelector("#startdoc");
const endButton = document.querySelector("#enddoc");
const prevButton = document.querySelector("#prev_page");
const nextButton = document.querySelector("#next_page");
const showPG = document.querySelector("#pgnos");
//magnify = document.querySelector("#zoom-in");
//minify = document.querySelector("#zoom-out");
/*
magnify.addEventListener('click', function() {
$("#flipbook").turn("zoom", 1.1, 1);
});
minify.addEventListener('click', function() {
$("#flipbook").turn("zoom", 1, 1.1);
})
*/
$("#flipbook").turn({
gradients: true,
page: 1,
duration: 2000
});
const first_page = $("#flipbook").turn("page");
const last_page = $("#flipbook").turn("pages");
startButton.addEventListener('click', function() {
$("#flipbook").turn("page", first_page);
showPG.innerHTML = first_page;
});
endButton.addEventListener('click', function() {
$('#flipbook').turn("page", last_page);
showPG.innerHTML = last_page;
});
nextButton.addEventListener('click', function() {
$("#flipbook").turn("next");
showPG.innerHTML = $("#flipbook").turn("page");
});
prevButton.addEventListener('click', function() {
$("#flipbook").turn("previous");
showPG.innerHTML = $("#flipbook").turn("page");
});
if ( (($("#flipbook").turn("page") == first_page)) ) {
$(nextButton).click(function() {
$("#flipbook").animate({left: "275"});
});
$(endButton).click(function() {
$("#flipbook").animate({left: "565"});
});
$(prevButton).click(function() {
$("#flipbook").animate({left: "275"});
});
$(startButton).click(function() {
$("#flipbook").animate({left: "0"});
});
}
if ( (($("#flipbook").turn("page") == last_page)) ) {
$(prevButton).click(function() {
$("#flipbook").animate({left: "300"});
});
}
</script>
</body>
</html>
Hello I have a number animation on my web page and I dont want the animation to start until it is in the middle of the web page. I tried to google onscroll and other options but I could not get this to work properly.
I prefer for the animation not to start until the visitor has scrolled down to 472px. As of right now as soon as the web page loads the number animation starts automatically. Any help I would really appreciate it.
// 472 px - Starts Yellow Counter Section
const counters = document.querySelectorAll('.counter');
const speed = 200; // The lower the slower
counters.forEach(counter => {
const updateCount = () => {
const target = +counter.getAttribute('data-target');
const count = +counter.innerText;
// Lower inc to slow and higher to slow
const inc = target / speed;
// console.log(inc);
// console.log(count);
// Check if target is reached
if (count < target) {
// Add inc to count and output in counter
counter.innerText = count + inc;
// Call function every ms
setTimeout(updateCount, 1);
} else {
counter.innerText = target;
}
};
updateCount();
});
.bg-yellow-white {
background: #f7c51e;
color: white;
}
.container {
max-width: 1404px;
margin: auto;
padding: 0 2rem;
overflow: hidden;
}
.l-heading {
font-weight: bold;
font-size: 4rem;
margin-bottom: 0.75rem;
line-height: 1.1;
}
/* Padding */
.py-1 {
padding: 1.5rem 0;
}
.py-2 {
padding: 2rem 0;
}
.py-3 {
padding: 3rem 0;
}
/* All Around Padding */
.p-1 {
padding: 1.5rem;
}
.p-2 {
padding: 2rem;
}
.p-3 {
padding: 3rem;
}
/* ======================== Red Block ======================== */
.red-block {
height: 472px;
width: 100%;
background-color: red;
}
/* ======================== PROJECS COMPLETED ======================== */
#projects-completed .container .items {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
#projects-completed .container .items .item .circle {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
<div class="red-block">
<p>red block</p>
</div>
<section id="projects-completed" class="counters bg-yellow-white">
<div class="container">
<div class="items">
<div class="item text-center p-3">
<div class="circle">
<div class="counter l-heading" data-target="1750">500</div>
</div>
<h2 class="py-2">Projects Completed</h2>
</div>
<div class="item text-center p-3">
<div class="circle py-2">
<div class="l-heading counter" data-target="5">500</div>
</div>
<h2 class="py-2">Staff Members</h2>
</div>
<!-- <div class="item text-center p-3">
<div class="circle">
<h3 class="l-heading ">1750</h3>
</div>
<h2 class="py-2">Projects Completed</h2>
</div>
<div class="item text-center p-3">
<div class="circle py-2">
<h3 class="l-heading">5</h3>
</div>
<h2 class="py-2">Staff Members</h2>
</div> -->
</div>
</div>
</section>
wesbos has great video on this https://www.youtube.com/watch?v=uzRsENVD3W8&list=PLu8EoSxDXHP6CGK4YVJhL_VWetA865GOH&index=14&t=0s
Basically what you need to do is listen for scroll and check where user currently is compared to desired place in px
you can check code here and adjust it to your needs https://github.com/wesbos/JavaScript30/blob/master/13%20-%20Slide%20in%20on%20Scroll/index-FINISHED.html
Try getBoundingClientRect(). document.querySelector( 'some element' ).getBoundingClientRect() will give you the properties of the specific element
for Example if you want to start an animation when an element is visible to user on his screen ( in the visible viewport ), you can use this to call the function and start the animation
let calledStatus = 0; // some flag variable to remember if function is called
window.onscroll = function(){
element = document.querySelector( '.some element' );
clientRect = element.getBoundingClientRect();
if( clientRect.top < window.innerHeight && clientRect.top > ( clientRect.height * -1) && calledStatus == 0){
//call your function or do other stuff
console.log('called' )
calledStatus = 1;
}
}
By using jquery , first add this reference script above your js code or referenece script
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></scrip>
....
</head>
if you want the code to launch specifically after 472 px:
js
$(document).ready(function () {
Let initialScroll = true;
//you can decrease or increase 472 depending on where exactly
//you want your function to be called
$(document).scroll(function () {
if (($(document).scrollTop() > 472)&& initialScroll) {
//call your function here
console.log( "reached 472")
InitialScroll=false;
}
});
});
if you want your function to start after reaching the middle
of the document
you place a div where the middle of the html code is :
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
...
<div id="middle"></div>
...
</body>
</html>
js
$(document).ready(function () {
Let initialScroll=true
$(document).scroll(function () {
if (($(document).scrollTop() >=$('#middle').position().top)&&initialScroll) {
//call your function here
console.log( "reached middle")
InitialScroll=false;
}
});
});
There is a native javascript API for "listetning" where the user currently is on the page called Intersection Observer. Basically you set a callback which should execute once the desired content scrolls into view.
It's used for all those fancy page animations where cards appear once you start scrolling to the bottom of the page since it's far more efficient than listening on the scroll event.
Kevin Powell did a great video about this topic.
Hope it helps!
Here's a code copy pasted, but it should give you a clue on how it should work:
document.addEventListener("DOMContentLoaded", function() {
let lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
let active = false;
const lazyLoad = function() {
if (active === false) {
active = true;
setTimeout(function() {
lazyImages.forEach(function(lazyImage) {
if ((lazyImage.getBoundingClientRect().top <= window.innerHeight && lazyImage.getBoundingClientRect().bottom >= 0) && getComputedStyle(lazyImage).display !== "none") {
lazyImage.src = lazyImage.dataset.src;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.classList.remove("lazy");
lazyImages = lazyImages.filter(function(image) {
return image !== lazyImage;
});
if (lazyImages.length === 0) {
document.removeEventListener("scroll", lazyLoad);
window.removeEventListener("resize", lazyLoad);
window.removeEventListener("orientationchange", lazyLoad);
}
}
});
active = false;
}, 200);
}
};
document.addEventListener("scroll", lazyLoad);
window.addEventListener("resize", lazyLoad);
window.addEventListener("orientationchange", lazyLoad);
});
I really didn't know how to come up with a descriptive title for this. Pretty much what I'm trying to do is make this accordion list item jump to the other side of the page when clicked. Currently the accordion is opening from left to right - but the last cell doesn't jump right it instead stays in place. How can I make that last cell jump to the right instead of staying in place.
The point of this is to put a picture in the tabs and have them come together at the beginning and end of browsing links.
JSFiddle Example - click the last cell
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Accordion</title>
<link rel="stylesheet" type="text/css" href="redo.css" />
</head>
<body>
<div id="hc1" class="haccordion">
<ul>
<li>
<div class="hpanel">
<div class="preview" id="p1"></div>
<div class="contentContainer">
<div class="content">
</div>
</div>
</div>
</li>
<li>
<div class="hpanel">
<div class="preview" id="p2"></div>
<div class="contentContainer">
</div>
</div>
</li>
<li>
<div class="hpanel">
<div class="preview" id="p3"></div>
<div class="contentContainer">
</div>
</div>
</li>
<li>
<div class="hpanel">
<div class="preview" id="p4"></div>
<div class="contentContainer">
asdf
</div>
</div>
</li>
<li>
<div class="hpanel">
<div class="preview" id="p5"></div>
<div class="contentContainer">
</div>
</div>
</li>
</ul>
</div>
<!-- Scripts -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="accordion.js"></script>
<!-- End Scripts -->
</body>
CSS
*
{
margin:0px;
padding:0px
}
html, body
{
height:100%;
width: 100%;
}
#hc1, #hc1 ul, #hc1 li
{
height: 100%;
}
#hc1, #hc1 ul
{
width: 100%;
}
.preview
{
width: 50px;
float: left;
height: 100%;
background-color: #E48525
}
#p1{background-color: #231F20}
#p2{background-color: #4F4E4F}
#p3{background-color: #919191}
#p4{background-color: #C4C4C3}
#p5{background-color: #E8E8E8}
/*
#p1{background-color: red}
#p2{background-color: blue}
#p3{background-color: green}
#p4{background-color: black}
#p5{background-color: orange}
*/
.contentContainer
{
background-color: gray;
margin: 0 auto;
width: 100%;
height: 100%;
}
/* -- Start Accordion -- */
.haccordion{
padding: 0;
}
.haccordion ul{
margin: 0;
padding: 0;
list-style: none;
overflow: hidden; /*leave as is*/
}
.haccordion li{
margin: 0;
padding: 0;
display: block; /*leave as is*/
overflow: hidden; /*leave as is*/
float: left; /*leave as is*/
}
/* -- End Accordion -- */
Javascript
var haccordion={
//customize loading message if accordion markup is fetched via Ajax:
ajaxloadingmsg: '<div style="margin: 1em; font-weight: bold"><img src="ajaxloadr.gif" style="vertical-align: middle" /></div>',
accordioninfo: {}, //class that holds config information of each haccordion instance
expandli:function(accordionid, targetli){
var config=haccordion.accordioninfo[accordionid]
var $targetli=(typeof targetli=="number")? config.$targetlis.eq(targetli) : (typeof targetli=="string")? jQuery('#'+targetli) : jQuery(targetli)
if (typeof config.$lastexpanded!="undefined") //targetli may be an index, ID string, or DOM reference to LI
{
config.$lastexpanded.stop().animate({width:config.paneldimensions.peekw}, config.speed); //contract last opened content
config.$lastexpanded.removeClass('active');
}
$targetli.stop().animate({width:$targetli.data('hpaneloffsetw')}, config.speed) //expand current content
config.$lastexpanded=$targetli
if($targetli.attr('class') != 'active')
$targetli.addClass('active');
},
urlparamselect:function(accordionid){
var result=window.location.search.match(new RegExp(accordionid+"=(\\d+)", "i")) //check for "?accordionid=index" in URL
if (result!=null)
result=parseInt(RegExp.$1)+"" //return value as string so 0 doesn't test for false
return result //returns null or index, where index is the desired selected hcontent index
},
getCookie:function(Name){
var re=new RegExp(Name+"=[^;]+", "i") //construct RE to search for target name/value pair
if (document.cookie.match(re)) //if cookie found
return document.cookie.match(re)[0].split("=")[1] //return its value
return null
},
setCookie:function(name, value){
document.cookie = name + "=" + value + "; path=/"
},
loadexternal:function($, config){ //function to fetch external page containing the entire accordion content markup
var $hcontainer=$('#'+config.ajaxsource.container).html(this.ajaxloadingmsg)
$.ajax({
url: config.ajaxsource.path, //path to external content
async: true,
error:function(ajaxrequest){
$hcontainer.html('Error fetching content.<br />Server Response: '+ajaxrequest.responseText)
},
success:function(content){
$hcontainer.html(content)
haccordion.init($, config)
}
})
},
init:function($, config){
haccordion.accordioninfo[config.accordionid]=config //cache config info for this accordion
var $targetlis=$('#'+config.accordionid).find('ul:eq(0) > li') //find top level LIs
config.$targetlis=$targetlis
config.selectedli=config.selectedli || [] //set default selectedli option
config.speed=config.speed || "normal" //set default speed
//KEY_CHANGE_BEGIN
var maxWidth = $targetlis.parent ().width ();
$targetlis.each ( function () { maxWidth -= $(this).outerWidth (true); } );
$targetlis.each(function(i){
var $target=$(this).data('pos', i) //give each li an index #
var lclMaxWidth = maxWidth + $target.find ('.hpanel:eq(0)').outerWidth (true);
$target.css ('width', config.paneldimensions.fullw);
//get offset width of each .hpanel DIV (config.dimensions.fullw + any DIV padding)
var hpaneloffsetw = $target.find ('.hpanel:eq(0)').outerWidth (true);
if (hpaneloffsetw > lclMaxWidth)
hpaneloffsetw = lclMaxWidth;
$target.data('hpaneloffsetw', hpaneloffsetw);
$target.css ('width', '');
//KEY_CHANGE_END
$target.click(function(){
haccordion.expandli(config.accordionid, this)
config.$lastexpanded=$(this);
})
if (config.collapsecurrent){ //if previous content should be contracted when expanding current
config.$lastexpanded.removeClass('active');
$target.click(function(){
$(this).stop().animate({width:config.paneldimensions.peekw}, config.speed); //contract previous content
})
}
}) //end $targetlis.each
var selectedli=haccordion.urlparamselect(config.accordionid) || ((config.selectedli[1] && haccordion.getCookie(config.accordionid))? parseInt(haccordion.getCookie(config.accordionid)) : config.selectedli[0])
selectedli=parseInt(selectedli)
if (selectedli>=0 && selectedli<config.$targetlis.length){ //if selectedli index is within range
config.$lastexpanded=$targetlis.eq(selectedli)
config.$lastexpanded.css('width', config.$lastexpanded.data('hpaneloffsetw')) //expand selected li
}
$(window).bind('unload', function(){ //clean up and persist on page unload
haccordion.uninit($, config)
}) //end window.onunload
},
uninit:function($, config){
var $targetlis=config.$targetlis
var expandedliindex=-1 //index of expanded content to remember (-1 indicates non)
$targetlis.each(function(){
var $target=$(this)
$target.unbind()
if ($target.width()==$target.data('hpaneloffsetw'))
expandedliindex=$target.data('pos')
})
if (config.selectedli[1]==true) //enable persistence?
haccordion.setCookie(config.accordionid, expandedliindex)
},
setup:function(config){
//Use JS to write out CSS that sets up initial dimensions of each LI, for JS enabled browsers only
document.write('<style type="text/css">\n')
document.write('#'+config.accordionid+' li{width: '+config.paneldimensions.peekw+';\nheight: '+config.paneldimensions.h+';\n}\n')
document.write('#'+config.accordionid+' li .hpanel{width: '+config.paneldimensions.fullw+';\nheight: '+config.paneldimensions.h+';\n}\n')
document.write('<\/style>')
jQuery(document).ready(function($){ //on Dom load
if (config.ajaxsource) //if config.ajaxsource option defined
haccordion.loadexternal($, config)
else
haccordion.init($, config)
}) //end DOM load
}
}
haccordion.setup({
accordionid: 'hc1', //main accordion div id
paneldimensions: {peekw:'50px', fullw:'100%', h:'100%'},
selectedli: [4, false], //[selectedli_index, persiststate_bool]
collapsecurrent: false //<- No comma following very last setting!
})
Here it is: tinker.io/f7fe4/12
This is the simplest change of all of the versions, requiring only floating the first preview to the right. Can be done programatically or with css (can be buggy in IE7+):
$('#hc1 li .preview').first().css('float','right');
or
#hc1 li:first-child .preview {
float:right;
}
--
Is this the kind of effect you're looking for?
https://tinker.io/f7fe4/8
Here's the same kind of affect, with a 'smoother' animation (it keeps the outer div still on the screen however)
https://tinker.io/f7fe4/9
And this is what I thought you were talking about at first
https://tinker.io/f7fe4/4 (this pops the left most cell over to the right and opens it, kind of like an infinite slider)