I am using jPlayer for a client, where the progress bar is the title of the track. It changes color as the track progresses. I'm accomplishing this by having a div with the title in one color, and absolutely positioning the progress bar on top of it, with the title in another color. So as the progress bar expands, it reveals the new colored text. In case my description is terrible (I'm sure it is), you can take a look at the dev site here:
http://sublimio.matthew-ferry.com/sublimio/
As you can see, the progress works just fine on single word titles. But on multiple word titles, the first word reveals fine, then for the subsequent words they aren't displayed until the whole word is finished.
Is this a browser rendering problem or is there something I could do to fix this?
first the js:
$('.track').each(
function()
{
var player_id = '#' + $('.jp-jplayer', this).attr('id');
var audio_id = '#' + $('.jp-audio', this).attr('id');
$('.jp-jplayer', this).jPlayer(
{
"cssSelectorAncestor": audio_id,
swfPath: "js",
supplied: "mp3",
wmode:"window"
}
);
$('.song', this).click(
function(eve)
{
eve.preventDefault();
$(this).jPlayer("progress");
$('.jp-jplayer').jPlayer("stop");
$(player_id).jPlayer(
"setMedia",
{
mp3: $(this).attr("href")
}
);
$(player_id).jPlayer("play");
return false;
}
);
}
);
Now the (simplified) HTML:
<ul>
<li class="track">
<div>
<div class="jp-controls">
<span><a class="jp-play song" tabindex="1">play</a></span>
<span><a class="jp-pause" tabindex="1">pause</a></span>
</div>
<div class="title">Title With Multiple Words</div>
<div class="progress">
<div class="jp-seek-bar">
<div class="jp-play-bar">Title With Multiple Words</div>
</div>
</div>
</div>
</li>
...etc...
</ul>
Ha, figured it out. The progress bar at 0% width was wrapping the overflow text onto multiple lines. Fix was using white-space: nowrap; on the progress bar text
Related
I want to hide all the elements on the page, but only show the contents of div.k1. There are many more elements on the page. How do i do it in pure CSS?
<div>1-this will hidden</div>
<div class="k1">
2-this div will displayed
<p>3-this will displayed</p>
<p>4-this div will displayed</p>
<div>
5-this will displayed
<p>6-this will displayed</p>
<div>
7-this will displayed
<p>8-this will displayed</p>
</div>
</div>
</div>
<div>9-this will hidden</div>
<div>10-this will hidden</div>
<div>1-this will hidden</div>
<div class="k1">
2-this div will displayed
<p>3-this will displayed</p>
<p>4-this div will displayed</p>
<div>
5-this will displayed
<p>6-this will displayed</p>
<div>
7-this will displayed
<p>8-this will displayed</p>
</div>
</div>
</div>
<div>9-this will hidden</div>
<div>10-this will hidden</div> 11,12,13..
If all the elements you want to hide are div's that are directly within the body you can do something like the following.
var items = document.querySelectorAll("body>div:not(.k1)");
for (var i = 0; i < items.length; i++) {
items[i].style.display = 'none';
}
Basically what this does is select all the div elements that are directly within the body that do not have the class k1. Then it does a for loop on those items and sets each item to not display.
For a CSS solution you could just do something similar if the conditions are the same as I mentioned above.
body>div:not(.k1) {
display: none;
}
If you are interested in learning more about CSS selectors I'd encourage you to take a look at the W3 schools page on it.
Here's a crude way of doing this for divs nested up to 2 layers deep (as in your example). As you can see here, the problem is hiding all divs based on the tagName ('div'), unless they either have the className "k1" or are children of a div with that className. So we actually have to check at least 3 conditions before applying the hidden property. You can, of course, go deeper, if needed, by adding parentNode.parentNode.parentNode... and so on. But I would almost certainly approach this instead by assigning a class to the elements I want hidden, with an ID on the one I want to reveal. This is just a way of doing the job without changing any of your html.
const allDivs = document.getElementsByTagName('div');
for (let i = 0; i < allDivs.length; i++) {
if(allDivs[i].className !== "k1" && allDivs[i].parentNode.className !== "k1"){
if (allDivs[i].parentNode.parentNode.className !== "k1"){
allDivs[i].hidden = true;
}
}
};
<div class="k1">
2-this div will displayed
<p>3-this will displayed</p>
<p>4-this div will displayed</p>
<div>
5-this will displayed
<p>6-this will displayed</p>
<div>
7-this will displayed
<p>8-this will displayed</p>
</div>
</div>
</div>
<div>9-this will hidden</div>
<div>10-this will hidden</div>
Cheers!
I'm using Foundation, and would like a sticky top bar with sub links to internal parts of the page. The problem is, if I do it naïvely, i.e.:
<div class="sticky">
<nav class="top-bar" data-topbar role="navigation">
<section class="top-bar-section">
<ul class="left">
<li>Intro</li>
<li>Basic</li>
</ul>
</section>
</nav>
</div>
... not much stuff ...
<a name="/intro"></a>
<h2>Intro</h2>
... much stuff ...
<a name="/basic"></a>
<h2>Basic</h2>
... much stuff ...
... then the top of the page scrolls to the top of the header, which is then obscured by the sticky top bar. See the jsfiddle and click on the top links to see what I mean.
How can I keep a sticky top bar, yet have clicks on the top bar scroll the page such that the header is right below the top bar, instead of obscured?
Solution #1
Add an <h2> style rule to the CSS, something like:
h2 {
margin-top: 30px;
}
Solution #2
If you want to minimise the extra white-space added to the document, you might try something like the following, instead:
a[name]:target {
padding-top: 30px;
}
This will only add white-space to the <a> element which is currently targeted.
I ended up writing a function to do this.
It changes the window location, so acts as if the user clicked an <a href='#internal-ref></a> link.
It scrolls to the link anyway using scrollIntoView() (thanks to this answer for making me aware of its existence).
It then scrolls back by $("nav.top-bar").height() pixels using window.scrollTo().
The code:
function scrollToAnchor(name) {
// change location
window.location = '#' + name;
// scroll to element anyway
var element = $("a[name='" + name + "']")[0];
if (!element) {
console.error("No such anchor with name", name);
return;
}
element.scrollIntoView();
// scroll back to leave room for sticky nav
var stickyNavHeight = $("nav.top-bar").height();
console.log(stickyNavHeight);
window.scrollTo(window.scrollX, window.scrollY - stickyNavHeight);
}
Live demo.
I'm using bootstrap scrollspy on my project, basically I have a click here link which has the following url format http://example.com/#positionA and on the page that it loads I have the following html code
<p></p>
<h3 id="positionA">Position A</h3>
<p>This is a test code</p>
The issue that I had is that the page loads on the position that I want but the scroll stops on the This is a test code position instead of the Position A.
How I can fix the position that the scrollspy stops so that I will stop before the title of the paragraph and display the title as well? Thank you
[UPDATE]
The project is a prestashop website and I'm working on the Terms and Conditions of the website. So on the delivery page I have the click here where if the client clicks it it will take him to the terms and conditions page on the specific sections. On the body I have this one
<body id="cms" class="cms cms-3 cms-terms-and-conditions-of-use hide-right-column lang_en two-columns" data-spy="scroll" data-offset="50">
And all the text belogs to this div
<div id="center_column" class="center_column col-xs-12 col-sm-9">
<div class="rte">
</div>
</div>
So on the delivery page I have the following code
<li>Terms and conditions for delivery, refund and returns please click here</li>
I have found the solution, here is my code how i fixed it
var hash = false;
if(window.location.hash) {
hash = true;
}
if (hash)
{
hash = document.URL.substr(document.URL.indexOf('#')+1);
var anchor = $('#'+hash).offset();
console.log("left" + anchor.top);
anchor.top = anchor.top - 100;
console.log("top" + anchor.top);
$('html, body').animate({
scrollTop: anchor.top
}, 500);
}
Use Scrollspy offset
By adding
data-offset="10"
to
<a data-spy="scroll" data-target="#positionA" data-offset="20" href="#positionA" >
it will 'offset from top when calculating position of scroll' in pixels
I was wondering how would I be able to make a sub nav where only the sub nav changes once I've clicked one of the links in the navigation bar instead of the whole page refreshing if you can help me much appreciated
http://jsfiddle.net/qrn8Q/
Thank you.
HTML Code:
<header class="header">
<div class="container">
<div class="header-primary_container">
<a class="header_brand" href="#"></a>
<div class="navigation-primary_right">
<div class="navigation-primary">
<nav class="navigation-primary_links"> Home
Designs
About Us
</nav>
</div>
</div>
</div>
</div>
</header>
<nav class="sub_nav">
Home
Sign in
Sign up
</nav>
</div>
What you need to do is to use either Ajax or iFrame. For onclick event of those links, you can write your javascript codes to load the new content.
You can accomplish this with jQuery. check out my code. it's pretty simple and easy:
http://jsfiddle.net/mELsr/
$('.nav_icon').click(function() {
$('nav.sub_nav:visible').fadeOut(300); // 1
$('.selected').removeClass('selected'); // 2
var classKey = $(this).attr('id'); // 3
$('nav.'+classKey+'_sub_nav').fadeIn(500); // 4
$(this).addClass('selected'); // 5
return false; // 6
});
In plain english: whenever on of the .nav_icon's is clicked, fade out the visible sub_nav (1) and remove .selected class from the .nav_icon that was selected (2). fetch the clicked item's id attribute (3) and find the sub_nav related to it and fade it in (4) and then add .selected class to the clicked item (5). at last return false; in order to ignore the links default behavior (6).
Hope it help you get started.
I've got three elements with IDs "albums", "about", and "contact", and three links to show/hide them via the toggle() function, with IDs "togglealbums", "toggleabout", and "togglecontact". I only want one of these elements to be able to be seen at any time, so I wrote the following functions:
$('#togglealbums').click(function() {
if( $('#about').is(':visible') ) {
$('#about').toggle(function() {
$('#albums').toggle();
});
} else if( $('#contact').is(':visible') ) {
$('#contact').toggle(function() {
$('#albums').toggle();
});
} else {
$('#albums').toggle();
}
});
$('#toggleabout').click(function() {
if( $('#albums').is(':visible') ) {
$('#albums').toggle(function() {
$('#about').toggle();
});
} else if( $('#contact').is(':visible') ) {
$('#contact').toggle(function() {
$('#about').toggle();
});
} else {
$('#about').toggle();
}
});
$('#togglecontact').click(function() {
if( $('#albums').is(':visible') ) {
$('#albums').toggle(function() {
$('#contact').toggle();
});
} else if( $('#about').is(':visible') ) {
$('#about').toggle(function() {
$('#contact').toggle();
});
} else {
$('#contact').toggle();
}
});
First of all, if these are wildly inefficient or there is an easier way to do this, please let me know.
What I've found is that if none of the three DIVs is visible, clicking one of the toggle links will show/hide the respective div with no animation. However, if one of the DIVs is visible, clicking another toggle link will cause the div to shrink and fade and the new one expands and fades in, which I don't want (at least for now). This can be seen here: http://new.e17.paca.arvixe.com.
Can anyone tell me why this is happening?
Thanks!
EDIT:
Markup is here:
<body>
<div id="main">
<div id="nav">
<div id="menu">
<ul>
<li>Albums</li>
<li>About Me</li>
<li>Contact</li>
</ul>
</div>
</div>
<div id="albums">
Albums go here
</div>
<div id="about">
About info goes here
</div>
<div id="contact">
Contact info goes here
</div>
</div>
</body>
Your shrink-and-fade was happening because, if .toggle() is given a callback function, it assumes you want to animate the toggle instead of just switching it on/off. (According to the docs, as of this writing, that's only supposed to happen when you provide a duration. I've submitted a bug report about this.)
See http://jsfiddle.net/mblase75/byKeP/1/ for a reduced example of this. To solve it, just remove the callbacks and put the same code in the next line of your function.
As for streamlining your code, classes are your friends. HTML:
toggle albums
toggle about
toggle contact
<div class="toggleblock" id="albums">ALBUMS</div>
<div class="toggleblock" id="about">ABOUT</div>
<div class="toggleblock" id="contact">CONTACT</div>
Note the data- attributes, which jQuery will parse and make accessible through the .data() method. This makes it easy to store a unique div ID on the hyperlink itself, which in turn streamlines our JavaScript immensely. JS:
$('.togglelink').on('click',function(e) {
var id = $(this).data('block');
$('#'+id).toggle().siblings('.toggleblock').hide();
});
http://jsfiddle.net/mblase75/byKeP/