I have 10 div elements, and all of them are 500px width and height;
<div class="cont_1">a lots of content here..</div>
<div class="cont_2">a lots of content here..</div>
<div class="cont_3">a lots of content here..</div>
<div class="cont_4">a lots of content here..</div>
<div class="cont_5">a lots of content here..</div>
<div class="cont_6">a lots of content here..</div>
<div class="cont_7">a lots of content here..</div>
<div class="cont_8">a lots of content here..</div>
<div class="cont_9">a lots of content here..</div>
<div class="cont_10">a lots of content here..</div>
and my css
div{
width:500px;
height:500px;
background:#f0f0f0;
border:1px solid #ccc;
margin:10px;
padding:10px;
}
And my seventh div is hidden with display:none. Once the user scrolls to this element how can I display it?
You'll have to attach a scroll event to your page that checks the position of each element after scrolling:
function CheckIfVisible(elem){
var ElemPos = elem.getBoundingClientRect().top;
elem.style.display = (ElemPos > 0 && ElemPos < document.body.parentNode.offsetHeight)?"block":"none";
}
window.addEventListener("onscroll", function(){
var elem = document.getElementsByClassName("cont_1")[0];
CheckIfVisible(elem);
});
window.addEventListener("onscroll", function(){
var elem = document.getElementsByClassName("cont_2")[0];
CheckIfVisible(elem);
});
window.addEventListener("onscroll", function(){
var elem = document.getElementsByClassName("cont_3")[0];
CheckIfVisible(elem);
});
and so on...
Related
Im trying to right align the Title on top of the last Div. As per the below image , the text should be on top of "Hello 5 / 4 / 3". When we resize the window button will float which is working and the text should be always be on top of the last button.
Unsure why the wrapper div is adding extra space to the right of the button and not aligning to the edge of the right most div. Extra space is coming even if the Title is not there , any insights about Div width calculation would be great.
I tried calculating the number of buttons in the top row using javascript and added offset to the title , but it seems tedious and not aligning at certain resolution.
http://jsbin.com/nonexegiqa/embed?html,css,console,output
HTML
<div class="wrapper">
<div class="title">Title</div>
<div class="clear"/>
<div class="btn">Hello 1</div>
<div class="btn">Hello 2</div>
<div class="btn">Hello 3</div>
<div class="btn">Hello 4</div>
<div class="btn">Hello 5</div>
<div class="btn">Hello 6</div>
<div class="clear"/>
</div>
CSS
.wrapper{
border:solid gray 1px;
}
.btn{
width:96px;
height:46px;
float:left;
border:solid gray 1px;
margin-left : 11px;
margin-bottom : 11px;
text-align:center;
}
.title{
float:right;
}
.clear{
clear:both;
}
You need to find count of .btn in first row when page resizing, Then set position of .title to last .btn in first row.
$(window).on("resize", function(){
var parWidth = $(".wrapper").innerWidth();
var chiWidth = $(".wrapper .btn").first().outerWidth(true);
var childCount = 0;
while(parWidth >= chiWidth){
parWidth -= chiWidth;
childCount ++;
}
var left = $(".btn:eq("+(childCount-1)+")").position().left;
$(".title").css("margin-left", left);
});
To better understanding, i create demo but because you can't change demo page size in here, i create it in JSFiddle.
yes, display:flex may be very helpful. As a work around you could set the width of the .wrapper to 70vw, or something similar. The .wrapper div width is creating the "extra space."
I have a content like
<div id="sContainer">
<div class="message0" id="l0">Initial Content 111</div>
<div class="message1" id="l1">Initial Content 222</div>
<div class="message2" id="l2">Initial Content 333</div>
<div class="message3" id="l3">Initial Content 444</div>
<div class="message4" id="l4">Initial Content 555</div>
<div class="message5" id="l5">Initial Content 666</div>
<div class="message6" id="l6">Initial Content 777</div>
</div>
http://jsfiddle.net/LRLR/0sbdttds/
Even inside div, i have some more divs (not shown)
Is there any which to find which all divs are visible on screen ?
Requirement:
1. everytime div is focussed, i want to add css property
2. i need to store a variable
You can use the :visible property selector to fetch shown elements
$(function() {
var divs = $('[id^=l]:visible');
console.log('shown divs', divs);
alert('divs shown: ' + divs.length);
});
/* for testing purpose */
[id^=l] {
/* id starting with `l` */
display: none;
}
[id^=l]:nth-child(3n) {
/* every third element */
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sContainer">
<div class="message0" id="l0">Initial Content 111</div>
<div class="message1" id="l1">Initial Content 222</div>
<div class="message2" id="l2">Initial Content 333</div>
<div class="message3" id="l3">Initial Content 444</div>
<div class="message4" id="l4">Initial Content 555</div>
<div class="message5" id="l5">Initial Content 666</div>
<div class="message6" id="l6">Initial Content 777</div>
</div>
Use Jquery Visible Selector With Starts With Selector
$("div[id^='l']:visible").addClass("Your_Class_Name");
You can use event delegation to find which element is being focused on. Please see this: http://jsfiddle.net/0sbdttds/1/
The key is to add a listener to the parent, like this:
$("#sContainer").click(showMessage);
Then in the handler, use the event to check the target, like this:
var focusedElement = $("#" + e.target.id);
focusedElement then contains a jQuery object that points to the element that was targeted by the action (which in the case of the fiddle is a click.)
The above fiddle works on clicks. If you want focus check out How to focus div?
Also, the CSS in your fiddle can be improved. It isn't DRY: http://csswizardry.com/2013/07/writing-dryer-vanilla-css/
The ids can be filtered out for visible elements using :visible pseudo selector. I have set tabIndex so that the <div>s are fucusable.
Please checkout the working code snippet below:
var dataAbc = '<div class="message7" tabindex="1">Focus Shifted Here</div>';
// I am prepending just 1 <div> as of now. To prepend multiple <div>s, make sure to increment the tabIndex using a for loop.
setTimeout(function(){ $(dataAbc).prependTo("#sContainer");},3000);
$("div:visible").each(function(){
console.log($(this).attr('id'));
});
$(document).on("focusin", "div div", function(){
$(this).css("background", "yellow");
});
$(document).on("focusout", "div div", function(){
$(this).css("background", "white");
});
.message0 {margin: 30px;height: 200px;border: 10px solid green;}
.message1 {margin: 30px;height: 200px;border: 10px solid yellow;}
.message2 {margin: 30px;height: 200px;border: 10px solid pink;}
.message3 {margin: 30px;height: 200px;border: 10px solid blue;}
.message4 {margin: 30px;height: 200px;border: 10px solid black;}
.message5 {margin: 30px;height: 200px;border: 10px solid cyan;}
.message6 {margin: 30px;height: 200px;border: 10px solid orange;}
.message7 {margin: 30px;height: 200px;border: 10px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sContainer">
<div class="message0" id="l0" tabindex="2">Initial Content 111</div>
<div class="message1" id="l1" tabindex="3">Initial Content 222</div>
<div class="message2" id="l2" tabindex="4">Initial Content 333</div>
<div class="message3" id="l3" tabindex="5">Initial Content 444</div>
<div class="message4" id="l4" tabindex="6">Initial Content 555</div>
<div class="message5" id="l5" tabindex="7">Initial Content 666</div>
<div class="message6" id="l6" tabindex="8">Initial Content 777</div>
</div>
Updated jsFiddle
Checkout the documentation links below:
http://api.jquery.com/visible-selector/
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.tabIndex
To find the divs that are in the viewport requires a little more than what jQuery provides out of the box. You might need something like Viewport, which is a class I wrote for this kind of problem.
var viewport = new Viewport(window);
viewport.addEventListener("scroll:complete", function(vp) {
viewport.querySelectorAll("div.message", function(div) {
div.classList.add("foo");
});
});
Each div that you want to detect in the viewport should have one common class to make your code easier to maintain. Please note that Internet Explorer is supported starting at version 9, plus the normal standards compliant browsers.
I think that you looking for
$(document).ready(function(){
var i,classes;
var divs_num = $('#sContainer div').length;
for(i = 0 ; i < divs_num; i++){
Ids= $('#sContainer div:visible').eq(i).attr('id');
if(typeof Ids !== 'undefined'){
alert(Ids);
if(Ids == 'l3' ){
$('#'+Ids).css('background','blue');
}
}
}
$('#sContainer div').on('click',function(){
$('#sContainer div').css('border','5px solid blue');
$(this).css('border','5px solid red');
});
});
DEMO the code get all visible divs and alert all visible div Ids.. then check for example for id l3 if its visible change its background to red .. and in click event When click in any div change its border to red and change all another divs to blue border
Right now I have divs that show when you scroll past a certain mark but realized that this gets broken when the browser is resized. Is there any way I can make this responsive? I'm not sure if adding $(window).resize(checkY); would work either.
EDIT:
The end goal is to show the title when the associated content comes into view
HTML
<div class="title" data-position="400,1150">Yama</div>
<div class="title" data-position="1150,1800">Modurra</div>
<div class="title" data-position="1800,2600">Computer</div>
<div class="title" data-position="2600,3300">Maru</div>
<div class="title" data-position="3300,3900">Sushi</div>
<div class="title" data-position="3900,4700">Summit</div>
<div class="title" data-position="4700,10000">Lights Out</div>
JS
<script>
//Note you do not need to make an anonymous
//function just to do the call for checkY
//just pass the function
$(window).scroll(checkY);
function checkY() {
//save this value so we dont have to call the function everytime
var top = $(window).scrollTop();
console.log(top);
$(".title").each(function () {
var positionData = $(this).data("position").split(",");
if (top > positionData[0] && top <= positionData[1]) {
console.log("Show");
$(this).show();
} else {
console.log("Hide");
$(this).hide();
}
});
}
checkY();
</script>
EDIT
.title {
position:fixed;
top:0px;
left:45%;
display:none;
padding:10px;
background:rgba(255,255,255,0);
color:#000;}
#Yama {
position:absolute;
display:block;
height:900px;
font-family: Arial, Helvetica, sans-serif;
font-size:70pt;
letter-spacing:0px;
font-weight:100;
-webkit-font-smoothing: antialiased;
text-align:center;}
This is the wrapper holding everything.
#mini {width:100%; height:100%;
padding-top:140px;}
What you want to do is find the target content and determine if the element is within the viewport. If it is then you show the title.
With this you won't need to use data-* attributes. You can just put the title in the main content's element, and then use jQuery's .closest method to get the closest parent (the content element). And from there do the tests.
HTML
<div id="Yama" class="content">
<div class="title">Yama</div>
</div>
<div id="Modurra" class="content">
<div class="title">Modurra</div>
</div>
<div id="Computer" class="content">
<div class="title">Computer</div>
</div>
<div id="Maru" class="content">
<div class="title">Maru</div>
</div>
<div id="Sushi" class="content">
<div class="title">Sushi</div>
</div>
<div id="Summit" class="content">
<div class="title">Sushi</div>
</div>
<div id="LightsOut" class="content">
<div class="title">Lights Out</div>
</div>
JS
$(window).scroll(checkY);
function checkY(){
var top = $(window).scrollTop();
$(".title").each(function(){
var target = $(this).closest(".content");
//The start range value is just offset().top
var tTop = target.offset().top;
//The end range value is the start range value plus
//the content elements height
var tBottom = tTop+target.outerHeight();
if(top >= tTop && top <= tBottom){
console.log("Show");
$(this).show();
} else {
console.log("Hide");
$(this).hide();
}
});
}
checkY();
JSFiddle Demo
Hitting a wall with this one, hope someone can lend a hand. I have a wrapper div containing many fixed-width "content" divs. It's like a table, except that the number of items "per row" aren't fixed, so that whenever the screen size is wide, more items fit onto the screen. Pretty basic.
Also, each of these "content" divs has an adjacent "details" div that is hidden by default ("style=display:none"), and an adjacent "separator" div that is empty, containing only the style "clear:both;".
Each content/details/separator div has a unique number in its ID, so that I can tell they are related (e.g., content123, details1234, separator1234)
Now, when one of these content divs is clicked, I want to reveal its "details" div below it. That part, I've got working partially, by wrapping an anchor tag around the content div, which fires an onClick javascript event, which in turns runs a jQuery statement to make visible the details and separator divs jQuery(".details1234").css("display","block");"
But you can imagine my problem. Once that "separator" div is reveled, it pushes down (clears) any "content" divs that appears to the right of it, ugly. My thought, what I have been wrestling with for hours, is to reveal the "separator" div of the content div, that is the last one appearing in the "row" that was clicked. That way, a new "row" will be opened up by the separator, so that when the "content" div is revealed it appears below the clicked item in the new row. To do that, I need to figure out the elementID of the last content div in the "row", and I was thinking about using the Y-coord of the mouse click event, plus the X-coord = to the right-most edge of the wrapper div minus half the width of the fixed-width content div. Something like that. But I am smashed into a wall and can't figure it out.
Can anyone help me do that? Or offer a different solution?
If sample code would help let me know, I could whip up an example, but it may take some screen space in this post.
Thanks everyone.. going nuts with this.
EDIT: the sample code below is based on my site. When a cell is clicked, you can see its "details" div appear below it, but unfortunately the other divs in the "row" get pushed down. that is the effect I'm trying to avoid. When a cell is clicked, I want the "details" to appear below it, but also the other divs to stay in their positions above the other cell's details, basically I want to keep the "row" intact. In the code, you can see my fruitless experiments using a "separator" div, because my assumption is that if I can insert that after the last div in the row, then the "details" div will become the next row, followed then by the next row of cells. Hope I explained it OK. Thanksgiving feast causing blood to divert from brain ;)
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentcell{
border: 2px solid blue;
padding: 4px;
float: left;
width: 200px;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
width:450px;
display:none;
float:left;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
//now highlight the clicked div and reveal its content div
var contentHI = "#content"+contentid;
var detailsON = "#details"+contentid;
var separatorON = "#separator"+contentid;
$(contentHI).css("border","2px solid green");
//$(separatorON).css("display","block");
$(detailsON).css("display","block");
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01">
<div id="content01" class="contentcell">cell01</div>
<div id="details01" class="details">here are details about cell01</div>
<div id="separator01" class="separator"> </div>
</div>
<div id="contentwrapper02">
<div id="content02" class="contentcell">cell02</div>
<div id="details02" class="details">here are details about cell02</div>
<div id="separator02" class="separator"></div>
</div>
<div id="contentwrapper03">
<div id="content03" class="contentcell">cell03</div>
<div id="details03" class="details">here are details about cell03</div>
<div id="separator03" class="separator"></div>
</div>
<div id="contentwrapper04">
<div id="content04" class="contentcell">cell04</div>
<div id="details04" class="details">here are details about cell04</div>
<div id="separator04" class="separator"></div>
</div>
<div id="contentwrapper05">
<div id="content05" class="contentcell">cell05</div>
<div id="details05" class="details">here are details about cell05</div>
<div id="separator05" class="separator"></div>
</div>
<div id="contentwrapper06">
<div id="content06" class="contentcell">cell06</div>
<div id="details06" class="details">here are details about cell06</div>
<div id="separator06" class="separator"></div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>
User ,
if you give as regular position be default , it pushes the other contents definetly down as they come in squence.
Change the hidden divs position to absolute so that it will go out of sequence and you can position at anywhere on the page by top and left property.
get the offset of the div you want next to...
http://api.jquery.com/offset/
it will have top and left property , use those property's and position next to them.
let me know if you need anything else.
give a bigger z-index for the hidden divs.
What about showing the details div with position: absolute, on top of everything else? (See here, the code's a little messy but you get the idea).
I partially figured it out, but the logic may be very clunky. I basically walk left by 100px from the width of the container div until I find a content div. Plus it doesn't work in IE8, because IE is not getting the same results from jQuery's offset() or position() as firefox, it always reports "19". So in IE, I can never get a Y-coordinate value. I'm too sleepy now to work on this anymore today. If someone can lend a hand or tell me how to improve the javascript that would be cool.
Here is the working code for Firefox (I changed javascript and css of the detail divs, compared to original question):
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentcell{
border: 2px solid blue;
padding: 4px;
float: left;
width: 200px;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
display:none;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
//now highlight the clicked div and reveal its content div
//first, figure out which separator to display.
//1.get the y-pos from the clicked element, this gives y-coord of the row
contentClicked = "#content"+contentid;
var clickedoffset = $(contentClicked).offset();
var ypos = clickedoffset.top;
var wrapperwidth = $("#overallwrapper").width();
for (var xpos=wrapperwidth; xpos>0; xpos-=100){
var elematpos = document.elementFromPoint(xpos, ypos);
var elematposid = elematpos.id;
if (elematposid.substring(0,7) == "content") {
var lastcontentdivID = elematposid.substring(7);
break;
}
}
$(contentClicked).css("border","2px solid green");
var detailsON = "#details"+contentid;
$(detailsON).css("display","block");
var lastidonscreen = "#content"+lastcontentdivID;
$(detailsON).insertAfter(lastidonscreen);
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01">
<div id="content01" class="contentcell">cell01</div>
<div id="separator01" class="separator"> </div>
<div id="details01" class="details">here are details about cell01</div>
</div>
<div id="contentwrapper02">
<div id="content02" class="contentcell">cell02</div>
<div id="separator02" class="separator"></div>
<div id="details02" class="details">here are details about cell02</div>
</div>
<div id="contentwrapper03">
<div id="content03" class="contentcell">cell03</div>
<div id="separator03" class="separator"></div>
<div id="details03" class="details">here are details about cell03</div>
</div>
<div id="contentwrapper04">
<div id="content04" class="contentcell">cell04</div>
<div id="separator04" class="separator"></div>
<div id="details04" class="details">here are details about cell04</div>
</div>
<div id="contentwrapper05">
<div id="content05" class="contentcell">cell05</div>
<div id="separator05" class="separator"></div>
<div id="details05" class="details">here are details about cell05</div>
</div>
<div id="contentwrapper06">
<div id="content06" class="contentcell">cell06</div>
<div id="separator06" class="separator"></div>
<div id="details06" class="details">here are details about cell06</div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>
EDIT:
Blasted IE. I just can't trust it to determine screen coordinates. I got it working though, but only for Firefox. again IE is trying to drive me insane by not handling insertAfter properly. arrgh! here is the final code:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentwrapper{
}
.contentcell{
padding: 4px;
float: left;
width: 200px;
height: 100px;
border: 2px solid blue;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
display:none;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
var contentClicked = "#content"+contentid;
var thisypos = $(contentClicked).offset().top;
var nextdivid = contentClicked;
var countid = contentid;
do
{
var prevdivid = nextdivid;
var nextcontentid = (countid * 1) + 1;
var nextcontentid = '' + nextcontentid;
if ( nextcontentid.length < 2)
{ nextcontentid = "0" + nextcontentid; }
nextdivid = "#content" + nextcontentid;
if ( $(nextdivid).length ) {
var nextypos = $(nextdivid).offset().top;
countid++;
} else {
break;
}
}
while (thisypos == nextypos);
$(contentClicked).css("border","2px solid green");
var detailsON = "#details"+contentid;
$(detailsON).css("display","block");
$(detailsON).insertAfter(prevdivid);
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01" class="contentwrapper">
<div id="content01" class="contentcell">cell01</div>
<div id="separator01" class="separator"> </div>
<div id="details01" class="details">here are details about cell01</div>
</div>
<div id="contentwrapper02" class="contentwrapper">
<div id="content02" class="contentcell">cell02</div>
<div id="separator02" class="separator"></div>
<div id="details02" class="details">here are details about cell02</div>
</div>
<div id="contentwrapper03" class="contentwrapper">
<div id="content03" class="contentcell">cell03</div>
<div id="separator03" class="separator"></div>
<div id="details03" class="details">here are details about cell03</div>
</div>
<div id="contentwrapper04" class="contentwrapper">
<div id="content04" class="contentcell">cell04</div>
<div id="separator04" class="separator"></div>
<div id="details04" class="details">here are details about cell04</div>
</div>
<div id="contentwrapper05" class="contentwrapper">
<div id="content05" class="contentcell">cell05</div>
<div id="separator05" class="separator"></div>
<div id="details05" class="details">here are details about cell05</div>
</div>
<div id="contentwrapper06" class="contentwrapper">
<div id="content06" class="contentcell">cell06</div>
<div id="separator06" class="separator"></div>
<div id="details06" class="details">here are details about cell06</div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>
I am trying to recreate the "Styles" section of the Office ribbon:
http://www.winsupersite.com/images/reviews/office2007_b2_06.jpg
I like how it starts out as only one row, then you can scroll through the rows, then click the arrow to expand all into a table like above. Does anyone have any ideas on how to recreate this whole interactivity??
CSS
#container { width:200px;height:50px;overflow-x:hidden;overflow-y:auto;
border:1px solid black; position:relative }
#expander { position:absolute;right:0;bottom:0px;font-size:10px;margin:0;padding:1;
border:1px solid black; border-width:1px 0 0 1px }
.item { float:left; font-size:30px;height:40px;width:50px;
margin:5px; background:gainsboro;text-align:center }
HTML
<div id='container'>
<div class='item'>A</div>
<div class='item'>B</div>
<div class='item'>C</div>
<div class='item'>D</div>
<div class='item'>E</div>
<div class='item'>F</div>
<div class='item'>G</div>
<div class='item'>H</div>
<div class='item'>I</div>
<div class='item'>J</div>
<div class='item'>K</div>
<button id='expander' onclick='expand()'>▲</button>
</div>
JS
function $(id) { return document.getElementById(id); }
function expand() {
$('container').style.overflow = "auto";
$('container').style.height = "300px";
$('container').style.width = "300px";
}
function contract() {
$('container').style.overflow = "hidden";
$('container').style.height = "50px";
$('container').style.width = "200px";
}
...should get you started. It's got a few bugs you'll have to figure out:
When to call contract()
Button isn't positioned directly under scrollbar
Button scrolls with content (and disappears)