I have very simple web page with frames. I understand frames are obsolete.
When I click on a link in the sidebar, a PHP page loads in the main frame.
Page A
Page B
Page C
The pages take several seconds to load. If page A is displayed, then I click on page B, there will be no visible change, and no feedback that the click has happened, until page B is ready.
I would like, as soon as the link is clicked, to clear the main frame, and display a "please wait" sign there, while the PHP script runs. How do I do that?
I am totally open to a solution using iframes, rather than frames.
You could place the sign above the frame (using position: fixed;) and hide it (display: none;). Then make it visible as soon the link is clicked (onclick) and hide it, when frame has loaded (onload).
Here's an example:
function showSpinner() {
document.getElementById('sign').style.display = 'block';
}
function hideSpinner() {
document.getElementById('sign').style.display = 'none';
}
#sign {
display: none;
position: fixed;
}
Page A
Page B
Page C
<iframe name="Frame_Main" src="pageA.php" onload="hideSpinner()">
</iframe>
<div id="sign">
<img src="images/sign.png" alt="please wait" />
</div>
You need to use onload method inside iframe element and click on aside-bar link to set attribute value of iframe src and add active class on frame-wrapper for showing Please wait text and when your page loaded inside iframe then onload method will fire and remove active class from frame-wrapper. Below is working snippet I hope this will help you.
document.querySelectorAll('a').forEach(elem => {
elem.addEventListener('click', (e) => {
e.preventDefault();
document.getElementById('wrapper').classList.add('active');
document.getElementById('frame').setAttribute('src', e.target.href)
})
})
.frame-wrapper {
width: 320px;
height: auto;
position: relative;
}
.frame-wrapper::after {
content: attr(data-load);
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
top: 0;
left: 0;
font-size: 30px;
color: #fff;
background: rgba(0, 0, 0, 0.65);
transition: 350ms;
opacity: 0;
pointer-events: none;
}
.frame-wrapper.active::after {
opacity: 1;
pointer-events: all;
}
<aside>
Page A
Page B
Page C
</aside>
<div class="frame-wrapper active" data-load="Please wait" id="wrapper">
<iframe src="pageA.php" id="frame" onload="document.getElementById('wrapper').classList.remove('active')" width="100%" height="220"></iframe>
</div>
you done the following css approach:
<div class="holds-the-iframe"><iframe here></iframe></div>
.holds-the-iframe {
background:url(../images/loader.gif) center center no-repeat;
}
Related
I have several videos on my site, they are listed like the following :
<ul id="toolsButtons" class="ahrefs__tools__nav">
<li>
<div class="tools-icon">
<a href=https://www.youtube.com/watch?v=A1nRiiWYgZw target=_blank><img src=Traditional_vs_GATE_s.PNG></a>
<use xlink:href="#keyword-research-icon"></use>
<p class="tools-icon__text">Traditional vs GATE</p>
</li>
<li>
<div class="tools-icon">
<a href=https://www.youtube.com/watch?v=wLHfGQlLqtE target=_blank><img src=Guess_GATE_Password.PNG></a>
<use xlink:href="#competitive-analysis-icon"></use>
<p class="tools-icon__text">GATE Passcode</p>
</div>
</li>
<li>
<div class="tools-icon">
<a href=https://www.youtube.com/watch?v=5tAGemIvUeI target=_blank><img src=GATE_Demo.PNG></a>
<use xlink:href="#keyword-research-icon"></use>
<p class="tools-icon__text">How GATE Works</p>
</div>
</li>
</ul>
How can I create a viewing area below the list, so that when a video link is clicked, it will play in the viewing area?
As I suggested in the comments, I created a div, initially hidden, that plays the role of a popup modal that will be showed when an a tag that has a data-target="modal" is clicked. I made some changes to your HTML code that I will cover them in the answer.
The process:
When you click a link that has data-target="modal" (a link that has an href attribute of a video, here I added a data-target="modal" to each one just to differentiate these links from the other links that may be present in the page) the modal div that i gave it id="modal" will be showed and filled with the appropriete video. So, each time a link is clicked its href attribute will be placed in the src attribute of the iframe tag that will host the video.
The final result:
Ps: I'll provide a runnable snippet, but, it may not work as intended due to some restrictions made by Stack Overflow. For that, I made a working DEMO on CodePen that you can check and play with the code, if you want.
var modal = document.getElementById('modal'), closeBtn = modal.querySelector('.close'), ytVideo = modal.querySelector('.content .yt-video'), title = modal.querySelector('.content .title'), anchors = document.querySelectorAll('a[data-target="modal"]'), l = anchors.length;
for (var i = 0; i < l; i++) {
anchors[i].addEventListener("click", function(e) {
e.preventDefault();
title.textContent = this.dataset.videoTitle || 'No title';
ytVideo.src = this.href;
modal.classList.toggle('is-visible');
modal.focus();
});
}
modal.addEventListener("keydown", function(e) {
if (e.keyCode == 27) {
title.textContent = '';
ytVideo.src = '';
this.classList.toggle('is-visible');
}
});
closeBtn.addEventListener("click", function(e) {
e.preventDefault();
title.textContent = '';
ytVideo.src = '';
modal.classList.toggle('is-visible');
});
#modal {
display: none;
position: fixed;
width: 100vw;
height: 100vh;
max-height: 100vh;
top: 0;
left: 0;
background: rgba(24, 24, 24, .6);
z-index: 999;
}
#modal .content {
width: 55%;
height: 65vh;
margin: auto; /* allows horyzontal and vertical alignment as .content is in flex container */
}
#modal .content .yt-video {
display: block;
width: 100%;
height: calc(100% - 45px);
}
#modal .content .title {
box-sizing: border-box;
height: 45px;
line-height: 23px;
padding: 12px 4px;
margin: 0;
background: #007bff;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#modal .close {
position: absolute;
top: 0;
right: 0;
width: 35px;
height: 35px;
line-height: 35px;
text-align: center;
border: 0;
font-weight: bold;
font-size: 24px;
color: #fff;
background: #666;
cursor: pointer;
transition: background .4s;
}
#modal .close:hover, #modal .close:active {
background: #ef3658;
}
#modal.is-visible {
display: flex;
}
<ul id="toolsButtons" class="ahrefs__tools__nav">
<li>
<div class="tools-icon">
<img src="Traditional_vs_GATE_s.png">
<use xlink:href="#keyword-research-icon"></use>
<p class="tools-icon__text">Traditional vs GATE</p>
</li>
<li>
<div class="tools-icon">
<img src="Guess_GATE_Password.png">
<use xlink:href="#competitive-analysis-icon"></use>
<p class="tools-icon__text">GATE Passcode</p>
</div>
</li>
<li>
<div class="tools-icon">
<img src="GATE_Demo.png">
<use xlink:href="#keyword-research-icon"></use>
<p class="tools-icon__text">How GATE Works</p>
</div>
</li>
</ul>
<!-- the modal div that will open when an anchor link is clicked to show the related video in an iframe. -->
<div id="modal" tabindex="-1">
<button type="button" data-dismiss="modal" class="close" title="close">×</button>
<div class="content">
<h4 class="title"></h4>
<iframe class="yt-video" src="https://www.youtube.com/embed/A1nRiiWYgZw" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</div>
</div>
Changes that must be done in the HTML code:
Each a tag that holds an href attribute for a video that you want it to be showed in the modal must have a data-target attribute equals to "modal".
To display a title above the video when the modal div is showed, add a data-video-title attribute that equals to some text on these a tags. If the data-video-title is not present on a link, the title that appears above the video will be "No title".
As an illustration to the last 2 points, here's an example of a link that will open the modal when clicked: <img src="Traditional_vs_GATE_s.png">
All the videos links (in other words the href attribute of the a tags) MUST be an embed link (https://www.youtube.com/embed/A1nRiiWYgZw as an example). So, you have to use the link in the src of the iframe under the embed section under share section on YouTube. Here are some images to demonstrate that:
Why using embed instead of the regular watch link ?
That to prevent Cross-Domain-Policy restrictions. In simple words, by default servers don't allow other servers/sites to fetch their files asynchronously.
Notes on the modal div
For simplicity, I didn't done any animations as opening/closing effects, and the modal isn't responsive.
You can press ESC (Escape) button to close the modal.
A button with a "cross" sign will be placed on the top-right most of the browser window, to close the modal on click.
The markup of the modal div must be reserved to work as intended.
Why i didn't use data-href instead of href ?
I sticked with the href on the links to garantee that the video will be accessible even if JavaScript is disabled, if so, it will be redirected to the video.
Hope my answer pushed you further. I'm here for any further explanations.
I've created a vertical navigation on the left of our site. We'd like the background color for a .item to change based on the subdirectory where a user is viewing content. So if someone clicks on a nav .item, the href will redirect them to a page and we want that .item to be highlighted a unique hex color that we can customize for each nav .item. All 6 nav items would have a different color.
One point of clarification is that sometimes folks may visit our site without having ever clicked a navigation item. I want the navigation items to still be highlighted based on the current subdirectory where a person is viewing content. This helps them easily identify where they are and how to get back if they navigate to other parts of the community. Also if a person does a global search and stumbles upon content in one of our 6 main areas, we want the nav menu to instantly identify their current location (based on url) and highlight that nav .item in our vertical nav bar.
Is Javascript or Jquery the way to go? Any help would be appreciated!!
Heres a FIDDLE with all the code.
sample CSS:
.navback {
position: fixed;
top: 0;
left: 0px;
width: 100px;
height: 100%;
background: #283237;
z-index: 4;
}
.navbar {
position: fixed;
top: 44px;
left: 0px;
width: 100px;
height: 60vh;
background: #283237;
display: flex;
z-index: 5;
flex-direction: column;
}
.topbar {
border-top: 1px solid #000;
top: 44px;
}
.navbar .item {
flex: 1;
text-align: center;
display: flex;
justify-content: center;
flex-direction: column;
padding-top: 40px;
padding-bottom: 40px;
max-height: 100px;
z-index: 5;
}
.navbar .item div.label {
color: #fff;
position: relative;
top: 5px;
font-size: 13px;
font-family: -apple-system, BlinkMacSystemFont, Helvetica, Arial, "Segoe UI", sans-serif;
transition: all 300ms cubic-bezier(0.68, -0.55, 0.27, 1.55);
left: -100px;
}
Sample HTML:
<div class="topbar"></div>
<div class="navback leftnav">
<div class="navbar">
<div class="item hvr-shrink">
<a href="https://community.canopytax.com/">
<div>
<img src="https://png.icons8.com/ios/35/ffffff/home.png"/>
<div class="label">Home</div>
</div>
</a>
</div>
<div class="item hvr-shrink">
<a href="https://community.canopytax.com/community-central/">
<div>
<img src="https://png.icons8.com/ios/40/ffffff/conference-call.png">
<div class="label">Central</div>
</div>
</a>
</div>
JS/jQuery
// get the first directory by splitting "/dir/path/name" into an array on '/'
// get [1] instead of [0] b/c the first should be blank. wrap in /s.
hereDir = "/" + window.location.pathname.split("/")[1] + "/";
// rebuild the URL since you're using absolute URLs (otherwise just use hereDir)
hereUrl = window.location.protocol + "//" + window.location.host + hereDir;
$(".item")
.find("[href^='" + hereUrl + "']")
.closest(".item").addClass("here");
Note .find("[href^=...]") selects things that start with what you're looking for.
CSS
/* now use .here to style */
.item.here {
background-color: purple;
}
.item.here .label {
font-weight: bold;
}
To answer your question directly, yes this could be done also via JavaScript/jQuery but there is a far simpler way using the css :active selector.
For example, if the user clicks the .item
then the code would be:
.item:active {
background-color: #cecece; // or whatever styling you want
}
Sidenote: As a webdesigner myself, in general i'd advise using the :hover selector when it comes to navbar highlightng instead of the :active one.
Use jquery in your html (https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js)
Add the following script
$('.item').click(function(){
$('.item.active').removeClass("active");
$(this).addClass('active');
})
CSS
.item.active {
background-color: red;
}
Please see updated fiddle
If you are using jQuery you can loop through each anchor and test it against the current URL of the page like this:
$(function highlightCurrentUrl() {
var currentUrl = window.location.href;
var items = $(".item").each(function() {
var anchor = $(this).find('a');
$(this).removeClass('active');
//comparison logic
if (anchor.prop('href') == currentUrl) {
$(this).addClass("active");
}
});
});
What this does is add a class to the matching .item in the menu. (This won't work in JSFiddle due to Content Security policy so you will have to test it your own environment.)
Next, you will need to define the styles that will be applied to an .item.active DIV tag. And, if you want different colors for different items, you should probably give them ID's in you markup, so you can reference them individually:
<div class="item hvr-shrink" id="home-link">
<a href="https://community.canopytax.com/">
<div>
<img src="https://png.icons8.com/ios/35/ffffff/home.png"/>
<div class="label">Home</div>
</div>
</a>
</div>
<div class="item hvr-shrink" id="central-link">
<a href="https://community.canopytax.com/community-central/">
<div>
<img src="https://png.icons8.com/ios/40/ffffff/conference-call.png">
<div class="label">Central</div>
</div>
</a>
</div>
These rules are saying that when the active class is added to the div with the ID home-link or central-link it should have the following properties
#home-link.active {
background-color: blue;
}
#central-link.active {
background-color: green;
}
My question is based on the usage of this answer. I want to use this solution, as presented here. But instead of on mouse over I would like see the iframe on after I click the link, and be able to close it with another click. Is that possible using only css?
This live preview for Wikipedia<div class="box"><iframe src="http://en.wikipedia.org/" width = "500px" height = "500px"></iframe></div> remains open on mouseover.
.box{
display: none;
width: 100%;
}
a:hover + .box,.box:hover{
display: block;
position: relative;
z-index: 100;
}
Not with an anchor tag, but you can use the checkbox hack to do that.
.box{
width: 100%;
}
input, .box {
display: none;
}
#checkbox:checked + .box {
display: block;
position: relative;
z-index: 100;
}
<label for="checkbox">Click</label>
<input id="checkbox" type="checkbox">
<div class="box">
<iframe src="http://en.wikipedia.org/" width="500px" height="500px"></iframe>
</div>
You can show the iframe when you click on an a tag using the :target pseudo class, but 1) it will jump on the page (without javascript), and 2) you can't close it without clicking on another link on the page and changing the hash in the URL.
.box{
width: 100%;
display: none;
}
.box:target {
display: block;
position: relative;
z-index: 100;
}
click to | click to close
<div class="box" id="iframe">
<iframe src="http://en.wikipedia.org/" width="500px" height="500px"></iframe>
</div>
For a mobile sticky menu I use the following code (shortened):
<nav class="navigation--wrapper">
<div class="navigation">
<div class="navigation--hamburger js--hamburger">
<svg>
...
</svg>
</div>
</div>
<div class="navigation--mobile is-content-menu js--mobile-navigation">
...
</div>
</nav>
With the following (shortened) CSS-styles:
.navigation--wrapper {
width: 100%;
position: fixed;
z-index: 20;
top: 0;
}
.navigation {
height: 50px;
}
.navigation--hamburger {
float: left;
padding: 14px;
}
.navigation--mobile {
position: fixed;
top: 50px;
left: 0;
right: 0;
z-index: 10;
width: 100%;
height: 100%;
visibility: hidden;
opacity: 0;
}
.navigation--mobile.is-open {
visibility: visible;
opacity: 1;
}
I added an event listener to the div that wraps the hamburger-icon (js--hamburger) which toggles the menu by adding is-open class to js--mobile-navigation.
This works perfectly most of the time but after a random number of clicks, the button stops working.
I added an event listener for all clicks in the document and logged the target to the console:
jQuery(document).click(function(event) {
return console.log(event.target);
});
Now for the clicks where the menu appears, it always shows a part of the svg as target which is just fine. After a few times of clicking (randomly, sometimes also at the first time) the menu is not working an the the div with class js--mobile-navigation is shown as target and the menu stops working until I reload the page.
I think this must be a bug with fixed-positioned elements. This Problem occurs in all major browsers on desktop, tablet and mobile.
I'm trying to create a anchor link so when the user clicks an item on the menu it goes to the specified destination. My menu consists of three items (one, two, three). When I click for example Three it jumps to Three but its heading goes under the header. How can I prevent that? I want the user to be able to see the heading.
Note that I want my header to be fixed and I want the contents to scroll behind the header.
HTML:
<body>
<header>
<nav>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</nav>
</header>
<section>
<div id="one">
<h1>One</h1>
<p>Text...</p>
</div>
<div id="two">
<h1>Two</h1>
<p>Text...</p>
</div>
<div id="three">
<h1>Three</h1>
<p>Text...</p>
</div>
</section>
<footer>
</footer>
</body>
CSS:
body {
background-color: #cf8;
}
header {
background-color: #000;
height: 4em;
width: 100%;
top: 0;
left: 0;
position: fixed;
}
nav ul {
list-style: none;
}
nav ul li {
margin-top: 0em;
padding: 5px;
float: left;
}
nav ul li a {
color: white;
text-decoration: none;
}
section {
height: auto;
width: 50%;
margin-top: 4em;
margin-left: 25%;
}
#one,#two,#three {
margin-top: 1em;
}
div {
background-color: #c00;
height: auto;
width: 100%;
}
footer {
background-color: #000;
height: 2em;
width: 100%;
clear: both;
}
JSFIDDLE, JSFIDDLE (Version 2)
JSFIDDLE (FULLSCREEN), JSFIDDLE (FULLSCREEN (VERSION 2))
I would recommend using a jQuery-based solution instead (p/s: see [Edit #2] for the final code, where I also detect the window.location.hash property):
$(function() {
// Only trigger .click() event when the link points to an internal anchor
$("header a[href^='#']").click(function(e) {
// Get the ID of the target
var target = $(this).attr("href");
// Animated scrolling to the vertical offset of the target element
// PLUS the outer height of the <header> element
$("html, body").animate({
scrollTop: $(target).offset().top - $("header").outerHeight()
});
// Prevent default scrolling action
// (I didn't use return false, because it stops event bubbling, too)
e.preventDefault();
});
});
http://jsfiddle.net/teddyrised/NHtvM/13/
[Edit]: However, you should note that this method does not work when the visitor is navigating to the specific div by entering the location hash in the url (e.g. /page.html#one).
[Edit #2]: Okay, I have revised my script so that it can detect the hashed URL if present, and perform the same thing as above (updated Fiddle here). An example would be: http://jsfiddle.net/teddyrised/NHtvM/15/show/light/#three, where you want the browser to navigate directly to the <div> with the ID of "three".
$(function () {
// Scroll to function
function scrollTo(ele) {
$("html, body").animate({
scrollTop: $(ele).offset().top - $("header").outerHeight()
});
}
// Detect location hash
if (window.location.hash) {
scrollTo(window.location.hash);
}
// Detect click event
$("header a[href^='#']").click(function (e) {
var target = $(this).attr("href");
scrollTo(target);
e.preventDefault();
});
});
You can accomplish this even without using JavaScript, just add empty divs with the same height and negative top-margin as menu before every part.
Like this:
<div id="one"></div>
<div>
<h1>One</h1>
...
with CSS
h1{ margin-top:0em; }
#one,#two,#three { margin-top:-4em; height:4em; }
See: http://jsfiddle.net/NHtvM/7/ (or in full screen http://jsfiddle.net/NHtvM/7/embedded/result/)
for the <nav>-tag define the inline style as style="z-index:1; position:absolute;"
and
for the <section>-tag define the inline style as style="z-index:2; position:absolute;"
In this case the contents in the section-tag will be visible above the nav menu.