Define number of visible elements - javascript

Some introduction:
Hello, i wanted to ask, if there is an easy way, to know how many of "tabs" are visible for user when he clicks on some button?
Description of what i have so far:
http://jsfiddle.net/L7bPc/7/
Here, on jsfiddle, you can see example of tabs i am thinking of, when you widen or narrow the width, more or less tabs are visible (rest disappears thanks to "overflow:hidden;").
Question:
My question is, is there any easy way to get to know, how many tabs are visible once clicking on red square in top right corner?
Explanation of what i want to achieve:
Why? Because i will try to generate a list of "not visible" tabs, once clicked on red square later (i will style it properly ofcourse). I want it to look similar to many programs with tabs, when there are too many of them, you can find a little arrow on the end of it, to expand the rest of tabs, in drop down menu.
I am asking how to know how many tabs are visible, and how many not (so i know which to generate after clicking on it in dropdown), i am NOT asking how to create the dropdown.
This part is generated by php, getting data from MySQL database, and style them in css to look like tabs (i didn't use php in jsfiddle, just plain html):
<div class="tabs">
<ul>
<li id=090NCI class='active'><a href='#' class='active'><span class='active'>090NCI</span></a></li>
<li id=061PPP><a href='#'><span>061PPP</span></a></li>
<li id=072KWM><a href='#'><span>072KWM</span></a></li>
<li id=057ALS><a href='#'><span>057ALS</span></a></li>
<li id=099AKG><a href='#'><span>099AKG</span></a></li>
<li id=090WPW><a href='#'><span>090WPW</span></a></li>
<li id=020MSM><a href='#'><span>020MSM</span></a></li>
<li id=014LSP><a href='#'><span>014LSP</span></a></li>
<li id=010AAV><a href='#'><span>010AAV</span></a></li>
<li id=080MKS><a href='#'><span>080MKS</span></a></li>
<li id=006ALS><a href='#'><span>006ALS</span></a></li>
<li id=007KSG><a href='#'><span>007KSG</span></a></li>
<li id=091AOW><a href='#'><span>091AOW</span></a></li>
<li id=004ALO><a href='#'><span>004ALO</span></a></li>
<li id=003WWW><a href='#'><span>003WWW</span></a></li>
<li id=002KSO><a href='#'><span>002KSO</span></a></li>
<li id=001NWD><a href='#'><span>001NWD</span></a></li>
</ul>
<div style="position: absolute; right:5px; top:26px; background: red; color:red; width:20px; height: 20px;" onclick="dosomething()"></div>
</div>
Any tips? Solutions might be both, in jQuery and javascript, no big difference for me.

Try this:
$("#redbox").click(function() {
var visibleLis = $("li").filter(function() {
var offset = $(this).offset();
return $(document.elementFromPoint(offset.left, offset.top)).closest(this).length > 0;
});
alert(visibleLis.length);
});
http://jsfiddle.net/L7bPc/11/
If you defined the .tabs to fully vertically contain the tabs, you can use far more optimized version:
$("#redbox").click(function() {
var boundingBox = $(".tabs")[0].getBoundingClientRect(),
bbRight = boundingBox.left + boundingBox.width,
bbBottom = boundingBox.top + boundingBox.height,
bbLeft = boundingBox.left,
bbTop = boundingBox.top;
var visibleLis = $("li").filter(function() {
var box = this.getBoundingClientRect(),
left = box.left,
top = box.top,
right = box.left + box.width,
bottom = box.top + box.height;
return left >= bbLeft && right <= bbRight && top >= bbTop && bottom <= bbBottom;
});
alert(visibleLis.length);
});
http://jsfiddle.net/L7bPc/13/

Related

Javascript removeClass/toggleClass works on desktop but not responsive page

I bought this theme a while back and have been chopping it up and modifying it to add/remove functionality. There is this slidein menu that appears on the page once a link is clicked from the navbar menu. The issue is that there is an X button to close the menu that is supposed to toggle/remove a class from the #btn-offcanvas-menu element when it is clicked (#btn-close-canvasmenu is clickable element); it works on the desktop but not the responsive mobile site. The only way it is toggled/removed on mobile is if the original link is clicked again. I have looked at the below questions here, and several others, including trying to use the closest/find options but nothing seems to work. What am I missing?
Desired behavior: the isLeft class should toggle/be removed when the #btn-close-canvasmenu link is clicked. It is on desktop but not mobile.
Javascript not working on mobile but works on desktop.
JavaScript - removeClass not working?
ToggleClass and RemoveClass not working
JQuery - ToggleClass/AddClass/RemoveClass
How to toggle class of closest element jquery toggle class on closest span
This is relevant portion of the index page...
<li id="recent-mobile"><!-- this is hidden by CSS on desktop -->
<a id="btn-offcanvas-menu" href="#">Recent Results</a>
</li>
<li id="recent-results"><!-- this is hidden by CSS on mobile -->
<div class="header-buttons pull-right hidden-xs hidden-sm">
<div class="navright-button">
<i class="fa fa-bars"> Recent Results</i>
</div>
</div>
</li>
<!-- Menu OffCanvas right begin -->
<div class="navright-button">
<div class="compact-menu-canvas" id="offcanvas-menu">
<h3>menu</h3><a id="btn-close-canvasmenu"><i class="fa fa-close"></i></a>
<nav>
<ul class="clearfix">
<li>Home</li>
<li>Features</li>
<li>Pages</li>
<li>Portfolios</li>
<li>Shop</li>
<li>Blog</li>
<li>Contact Us</li>
</ul>
</nav>
</div>
</div>
<!-- Menu OffCanvas right close -->
This is the relevant portion of the javascript compact.js file...
$("#btn-close-canvasmenu").on("click", function() {
$("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300), $("a#btn-offcanvas-menu").removeClass("isLeft")
});
$(document).on("click", "#btn-offcanvas-menu, #btn-offcanvas-menu-mobile", {} , function(a){
var id = $(this).attr('id');
if (id === "btn-offcanvas-menu-mobile") {
$("#btn-close-canvasmenu").toggleClass("mobile");
}
return a.preventDefault(), $(this).hasClass("isLeft") ? $("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300) : $("#offcanvas-menu").stop().animate({
right: "0px"
}, 300), $(this).toggleClass("isLeft"), false
});
EDIT (fixed 2/16/20): I edited the js file file to reflect this updated function: $("#btn-close-canvasmenu").on("click", function()
Essentially, what fixed it was changing the selector from #btn-offcanvas-menu to a#btn-offcanvas-menu. Not sure why that worked as opposed to using closest/find method but once I did, it toggled/removed the class on both desktop and mobile correctly. If anyone has anything thoughts on why the a made the difference with the selector, I'd appreciate the feedback as I am not an expert on js/jQuery. Otherwise, this can be considered closed.
Changing the selector in the compact.js file from #btn-offcanvas-menu to a#btn-offcanvas-menu fixed the issue and while this worked, it was the wrong way to correct the issue as connexo pointed out due to the duplicate ids.
The correct way to resolve this was to change the mobile navbar itself so I could use an id specifically for the mobile that only appeared there.
<nav id="mobile-menu" class="site-mobile-menu hidden-lg hidden-md">
<ul>
<li id="recent-mobile">
Recent Results
</li>
</ul>
</nav>
Next I changed the js function that populated the html for the mobile menu to use prepend instead of append so it populated everything above the Recent Results link...
$("#desktop-menu > ul").children().clone().prependTo($("#mobile-menu > ul")), $("#show-mobile-menu").on("click", function() {
$(this).toggleClass("clicked"), $("#mobile-menu > ul").stop(true, true).slideToggle()
});
Then I tweaked the js function to toggle the class to mobile for the #btn-close-canvasmenu if the selector was #btn-offcanvas-menu-mobile to be used later...
$(document).on("click","#btn-offcanvas-menu,#btn-offcanvas-menu-mobile", {} , function(a){
var id = $(this).attr('id');
if (id === "btn-offcanvas-menu-mobile") {
$("#btn-close-canvasmenu").toggleClass("mobile");
}
return a.preventDefault(), $(this).hasClass("isLeft") ? $("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300) : $("#offcanvas-menu").stop().animate({
right: "0px"
}, 300), $(this).toggleClass("isLeft"), false
});
Finally, I tweaked the js function that closed the menu to check the class to determine which id to toggle the isLeft class for...
$(document).on("click","#btn-close-canvasmenu", {} , function(a){
var id = $(this).attr('id');
if ($(this).hasClass("mobile")) {
var container = $("#btn-offcanvas-menu-mobile");
$("#btn-close-canvasmenu").toggleClass("mobile");
} else {
var container = $("#btn-offcanvas-menu");
}
$("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300), container.removeClass("isLeft")
});

Dynamically position nested UL based on parent LI width

Trying to implement the following effect
The HTML Code would like this:
<ul class="product-selection">
<li>
Level One
<ul>
<li>
Level Two
<ul>
<li>
Level Three
</li>
</ul>
</li>
</ul>
</li>
</ul>
Each nested UL will be absolutely positioned from the left and I would like to set UL's Left value based on it's parent LI's width so that they appear right next to each other.
I was able to achieve this for the first nested UL with the following code, can someone please provide a better version of this.
var ulWidth = 0;
$j(function() {
ulWidth = ulWidth + $j('ul.product-selection > li').width();
$j('ul.product-selection > li > ul').css({'left': ulWidth});
});
Solution to my question:
$j('.product-selection a').on('click', function(e) {
e.preventDefault();
var prevLevel = $j(this).parents('.list-wrap').width();
$j(this).next('.list-wrap').show();
$j(this).next('.list-wrap').css({'left': prevLevel});
});

JQuery rotate a span on clic

I'm working on my website (still need work), on the mobile nav, I have an expanding submenu, which has a span with a font character. What I want is for this character to rotate 180 degrees when clicked the first tima and go back to zero when clicked again, so far I've only been able to make it ratate the first time I click on it.
<ul>
<li class="parent"><span class="icon-house"></span>Home</li>
<li class="parent"><span class="icon-network"></span>Networks</li>
<li class="parent"><span class="icon-users"></span>Artists</li>
<li class="parent"><span class="icon-pictures"></span>Visual Art</li>
<li class="submenu parent genres">
<span class="icon-music"></span>Genres<span class="icon-arrow-down6 caret flechitauno"></span>
<ul class="children">
<li>House <span class="icon-music3"></span></li>
<li>Trance <span class="icon-music3"></span></li>
<li>Drum & Bass <span class="icon-music3"></span></li>
</ul>
</li>
<li class="parent"><span class="icon-info"></span>About this site</li>
</ul>
this is the jquery that I've been trying to use:
$(document).ready(main);
var flechitauno = 1;
//flip
$('.genres').click(function(){
if(flechitauno == 1){
$('.flechitauno').css({
transform: 'rotate(180deg)'
});
flechitauno = 0;
}else{
flechitauno = 1;
$('flechitauno').css({
transform: 'ratate(0deg)'
});
}
});
}
This is the adress of the website: http://66.68.113.215/design-3
the js file is /js/menu.js,
and the css is /css/menu.css
Try something like this (see effect working here: https://jsfiddle.net/p1xfuc1t/):
HTML:
<li class="submenu parent genres">
<span class="icon-music"></span>Genres<span class="icon-arrow-down6 caret flechitauno"></span>
<ul class="children">
<li>House <span class="icon-music3"></span> </li>
<li>Trance <span class="icon-music3"></span></li>
<li>Drum & Bass <span class="icon-music3"></span></li>
</ul>
CSS:
#keyframes roll {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
JS
$(document).ready(function() {
$('.genres').on('click', function() {
$('.flechitauno').css(
"animation", "roll 3s"
)
});
});
Aslo check your syntax for the .css() method, it dosent seem right.
Well either this or you use an external library like: http://jqueryrotate.com/.
So, I decided to listen to jsfiddle.net/0oo0fyra/1 – timo, who asked why not use plain javascript, so I researched a little bit more and came up with this solution
For the html, I used some in-line js to trigger the function 'flip' in a separate js file, since this a tag was already styled as block with css, I decided to use it to activate the onclick function, sending the span id as an argument to the function
<span class="icon-music"></span>Genres<span class="icon-arrow-down6 caret" id="genres"></span>
In the js file 'menu.js' I defined a variable to work with the function, and the 'flip' function, I defined the starting value of the variable 'voltear to 1' outside of the function as a global one to that it won't be reassigned every time the onclick function triggers, then the function receives the id of the span and uses it to target the span, then I just wrote what I wanted my span to do
var voltear = 1
function flip(id){
if (voltear == 1) {
document.getElementById(id).style.transform = "rotate(180deg)";
voltear = 0;
}else{
document.getElementById(id).style.transform = "rotate(0deg)";
voltear = 1;
}
}

JQuery Scrolling/Paging Tabs

I am trying to create a simple tab bar for a site that has the ability to scroll for tabs that do not fit on the page. This is quite simple and does not need to have any ajax or dynamically loaded content...it simply displays all the tabs, and when you click one, it takes you to another page.
I have scoured the internet and can not seem to find anything other than:
http://www.extjs.com/deploy/dev/examples/tabs/tabs-adv.html
however this is very heavy and complicated...I am looking for a lightweight example in jquery. If anyone can help I would be grateful!
I ended up writing it myself with a div who's overflow is set to hidden. Then used the jquery below to move the tabs in the div.
$(document).ready(function()
{
$('.scrollButtons .left').click(function()
{
var content = $(".tabs .scrollable .content")
var pos = content.position().left + 250;
if (pos >= 0)
{
pos = 0;
}
content.animate({ left: pos }, 1000);
});
$('.scrollButtons .right').click(function()
{
var content = $(".tabs .scrollable .content")
var width = content.children('ul').width();
var pos = content.position().left - 250;
//var width = content.width();
if (pos <= (width * -1) + 670)
{
pos = (width * -1) + 600;
}
content.animate({ left: pos }, 1000);
});
});
My Html looked like this:
<div class="tabs">
<div class="scrollable">
<div class="content">
<ul>
<li>Tab1</li>
<li>Tab2</li>
<li>Tab3</li>
<li>Tab4</li>
<li>Tab5</li>
</ul>
</div>
</div>
<div class="scrollButtons">
<ul>
<li>
<div class="left">
</div>
</li>
<li>
<div class="right">
</div>
</li>
</ul>
</div>
</div>
I have just created a plugin myself:
Project home: http://jquery.aamirafridi.com/jst
Could you simply wrap the tabs in a DIV with overflow-x: auto set in the CSS?
I always use JQuery UI tabs as a starting point for tabs. You can customize the JQuery UI download in the download section of the website. This method should be lighter than any other implementation, if you are already using JQuery on your website.
Out of the box, the JQuery UI tabs will not give you the scrolling you desire. This I believe could be achieved by altering the CSS, but more than likely will be easier if you alter the navigation of your site (i.e. create more levels, use shorter titles).
Hope this helps

jquery heirarchical menu design

edit:
ok, the line:
$( <?php echo("'#".$_GET['item']."'") ?> ).parent().show();
Is obviously and attempt to keep the menu open at the right place. I don't think this ever worked (got I hate working on other ppls code).
Then my current problem is how to access the <ul class="myul"> directly above the <li id="001" > using that item id=001 ??
Hi
I am trying to fix up a piece of code left to me by a now lost programmer. It works but there is a feature missing; I does not stay opened in the correct place when a menu item is selected.
Jquery:
$.swapImage(".swapImage");
$( <?php echo("'#".$_GET['item']."'") ?> ).parent().show();
$('.myul').hide();
$('.slide_ul li:not(:first-child)').hide();
$('.hideMe').click(function(){
$(this).next('ul').slideToggle('fast').siblings('ul:visible').slideUp('fast');
});
$('.myul a').click(function(e){
var url = $(this).attr('href');
var index = url.indexOf('=');
var substr = url.slice(index+1);
$('#productContainer >div').hide();
$('#productContainer').load("products/"+substr+"/product.html", function(){
$(this).fadeIn('slow');
var i = 0;
$('.slide_ul li:not(:first-child)').hide();
});
});
HTML:
<!-- Right Navigation -->
<div id="rightNav">
<div id="navMenu">
<h2 id="navMenuheader">Catalogue</h1>
<h3 class="hideMe">Widgets</h3>
<ul class="myul">
<h4 class="hideMe">Widget Coins</h2>
<ul class="myul">
<li id="001" >
The South African Widget
</li>
The result of the menu click is to injectContent into a black div in the middle of the page. Does $(document).ready(function(){ happen everytime this occurs? Otherwise I can't see why all the menu positions are updated.
I guess I need some more code to identify the place in the menu we are and leave them open. There are ants on my desk.
looks to me like the bad closing tag on
<h4 class="hideMe">Widget Coins</h2>
is your main problem, when it gets clicked on
$(this).next('ul')
fails to find a ul because it is a child instead of a sibling of the h4
changing it to
<h4 class="hideMe">Widget Coins</h4>
makes it work better, not sure if that was all you were looking for
$( <?php echo("'ul:has(#".$_GET['item'].")'");  ?> ).show();
will open every ul that has a descendant with the specified id
just using .parent() wasn't getting the top ul to show
Just had to add some jquery to reopen the relevant section of the menu after it has all been hidden. So right after the line $('.myul').hide() I reopen the menu section based on the url query ( products.php?item=001 ):
var item = <?php echo("'".$_GET['item']."'") ?>;
if (item != '')
{
item = "li#" + item;
$(item).parent().show();
$(item).parent().parent().show();
}

Categories

Resources