Am currently working with the Soundcloud API to pull images and track links for songs. Am currently showing track info through a modal window upon clicking the album image. However, for the songs on the bottom of the screen, the modal window only appears at the top of the screen, requiring a user to scroll up to see the track info. Probably has something to do with the css positioning but removing position:absolute only puts the modal window at the bottom of all the album images, requiring a scroll down. How can I make it so that a user's click on an image will open and start the modal window right where they currently are, without scrolling? Javascript / jquery /css answers all welcomed.
My CSS:
#modal {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
position: absolute;
top: 0;
left: 0;
}
#trackinfo {
width:380px;
height: 180px;
padding: 20px;
margin-right: auto;
margin-left: auto;
margin-top: 100px;
box-shadow: 10px 10px 5px;
border-radius: 15px;
text-align: center;
background: #c4e5c1;
font-family: Rockwell, "Courier Bold", Courier, Georgia, Times, "Times New Roman", serif;
}
.hidden {
display:none;
}
My Javascript for show and hide modal:
function doSearch() {
var searchTerm = document.getElementById('search').value;
// Search soundcloud for artists
SC.get('/tracks', { q: searchTerm}, function(tracks) {
for(track in tracks) {
var img = document.createElement('img');
img.setAttribute("src", (tracks[track]["artwork_url"]));
var title = tracks[track].title.replace("'", "\\\'").replace("\"", "\\\"");
linky = document.createElement('a');
linky.setAttribute("href", (tracks[track].permalink_url));
console.log(linky);
img.setAttribute("onclick", "showTrackInfo('" + title + "\\n"+ tracks[track].uri + " " + "\\n\\n(click to close) " + "')");
console.log(img);
if (tracks[track]["artwork_url"] == null) {
console.log(""); }
else {
var Catalog = document.getElementById('catalog');
Catalog.appendChild(img);
$('div#catalog').append('<img src="http://i.imgur.com/rGdvfl7.png">');
}
}
});
};
function showTrackInfo(track) {
var trackInfoElement = document.getElementById("trackinfo");
trackInfoElement.appendChild(document.createTextNode(track));
var modal = document.getElementById("modal");
modal.setAttribute("class", "");
}
function hidemodal() {
var trackInfoElement = document.getElementById("trackinfo");
trackInfoElement.childNodes;
while ( trackInfoElement.firstChild ) trackInfoElement.removeChild( trackInfoElement.firstChild );
var modal = document.getElementById("modal");
modal.setAttribute("class", "hidden");
}
The functions all work well, I just need to know how to position the modal box upon click so that the user doesn't need to scroll to see the trackinfo. Any help much appreciated.
Try position: fixed; on the dialog box, should make it fill the page no matter where they are on it
Related
I have this simple collapsible menu on www.keokuk.com
I would like for the previous menu to close when you click on the next one.
this is the javascript:
<script>
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function () {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
</script>
I worked on a solution on your website.
But it appears you set max-height manually in an other javascript function so you can just do the same thing in the commented line.
document.querySelectorAll('.collapsible').forEach(el => {
el.addEventListener('click', (e) => {
document.querySelectorAll('.collapsible').forEach(e => {
e.classList.remove('active');
e.nextSibling.nextElementSibling.style.maxHeight = "0px";
});
e.target.classList.toggle('active');
e.target.nextSibling.nextElementSibling.style.maxHeight =
`${el.nextSibling.nextElementSibling.scrollHeight}px`;
});
});
Details are commented in example
// Collect all .switch into an array
const switches = [...document.querySelectorAll(".switch")];
// Bind each .switch to the click event
switches.forEach(s => s.addEventListener("click", openClose));
// Event handler passes Event Object as default
function openClose(event) {
// Reference the tag proceeding clicked tag
const content = this.nextElementSibling;
// Get the height of content
let maxHt = content.scrollHeight + 'px';
// Find the index position of clicked tag
let index = switches.indexOf(this);
// The clicked tag will toggle .active class
this.classList.toggle('active');
// Remove .active class from all .switch
switches.forEach((btn, idx) => {
/*
If current index does NOT equal index of
clicked tag...
...remove .active
*/
if (idx != index) {
btn.classList.remove('active');
}
});
/*
If clicked has .active class...
...set style property of max-height using CSS variables
*/
if (this.classList.contains('active')) {
content.style.setProperty('--maxH', maxHt + 'px');
} else {
content.style.setProperty('--maxH', '0px');
}
}
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box
}
:root {
font: 300 1.5ch/1.2 'Segoe UI';
--maxH: 0px;
}
body {
width: 100%;
min-height: 200%;
padding: 15px;
}
header {
width: max-content;
margin: 10px 0 0;
padding: 5px 10px;
border: 3px ridge black;
border-radius: 4px;
background: #aaa;
cursor: pointer;
}
section {
position: relative;
max-height: var(--maxH);
margin: 0;
padding: 5px 10px;
border: 3px ridge black;
border-radius: 4px;
background: #ddd;
opacity: 0;
pointer-events: none;
}
.active+section {
z-index: 1;
opacity: 1.0;
}
<header class='switch'>Read more...</header>
<section>
<p>Merchandise Morty, your only purpose in life is to buy & consume merchandise and you did it, you went into a store an actual honest to god store and you bought something, you didn't ask questions or raise ethical complaints you just looked into
the bleeding jaws of capitalism and said 'yes daddy please' and I'm so proud of you, I only wish you could have bought more, I love buying things so much Morty. Morty, you know outer space is up right? Are you kidding? I'm hoping I can get to both
of them, Rick! And there's no evidence that a Latino student did it.</p>
</section>
<header class='switch'>Read more...</header>
<section>
<p>Oh, I'm sorry Morty, are you the scientist or are you the kid who wanted to get laid? Why don't you ask the smartest people in the universe, Jerry? Oh yeah you can't. They blew up. Looossseeerrrrr. I am not putting my father in a home! He just came
back into my life, and you want to, grab him and, stuff him under a mattress like last month's Victoria's Secret?!
</p>
</section>
//Overlay mobile menu open
$('#burger-icon').on('click', function(e) {
e.stopPropagation();
document.getElementById('fp-menu').style.height = "100%";
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
if (screen.width < 1000) {
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "white";
}
//changes the social icons to white if in mobile view.
document.getElementById('instagram').src = "instagram_white.svg";
document.getElementById('linkedin').src = "linkedin_white.svg";
document.getElementById('twitter').src = "twitter_white.svg";
//gets rid of the pipe in menu that is visible for the desktop version
//removes sidetabs while in overlay menu
pipe.style.display = "none";
contact.style.display = "none";
case_studies.style.display = "none";
//changes how the elements are displayed when overlay is triggered
$('#fp-menu .news').removeClass("col-sm-2");
$('#fp-menu .portfolio').removeClass("col-sm-3");
$('#fp-menu #social').removeClass("col-sm-6");
}
});
function closeOverlayMenu() { //closes the overlay mobile menu
// e.stopPropagation();
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "black";
}
//changes icons to black on slide up of overlay
document.getElementById('instagram').src = "instagram.svg";
document.getElementById('linkedin').src = "linkedin.svg";
document.getElementById('twitter').src = "twitter.svg";
//restores elements of the original homepage that were hidden for overlay
pipe.style.display = "block";
contact.style.display = "block";
case_studies.style.display = "block";
$('#fp-menu .news').addClass("col-sm-2");
$('#fp-menu .portfolio').addClass("col-sm-3");
$('#fp-menu #social').addClass("col-sm-6");
};
document.getElementsByTagName('body')[0].onresize = function() {
closeOverlayMenu();
};
//overlay mobile menu close
$('#closebtn').on('click', function(e) {
e.stopPropagation();
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
//if overlay mobile menu is down, close it by clicking the X
if (screen.width < 1000) {
closeOverlayMenu();
console.log(document.querySelectorAll("#social"));
}
});
//overlay menu styling
.overlay {
height: 0;
width: 100%;
position: fixed;
z-index: 999;
top: 0;
left: 0;
background-color: #000000;
overflow-x: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
top: 5%;
width: 100%;
text-align: center !important;
margin-top: 90px;
.row{
padding: 50px 30px 50px 30px;
.column{
float: left;
width: 33.33%;
padding: 0 5px 0 5px;
}
}
img {
width: 50px;
}
div {
padding: 30px 0 30px 0;
}
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #FFFFFF;
}
.overlay a:hover, .overlay a:focus {
color: #f1f1f1;
}
#closebtn {
display:block;
position: relative;
top: 5px;
right: 20px;
font-size: 60px;
}
#social{
position: relative;
top: 10px;
a {
padding: 5% 5% 5% 5%;
}
}
#fp-menu{
display: block;
color: $menu_black;
}
.pipe{
display: block;
transition: 0.4s;
}
<div id="fp-menu" class="overlay">
<div id="closebtn" style="color: white;">X</div>
<div class="column overlay-content">
<!-- <div class="column"> -->
<div class="col-sm-2 news">
NEWS
</div>
<div class="col-sm-1 pipe">
|
</div>
<div class="col-sm-3 portfolio">
PORTFOLIO
</div>
<div id="social" class="col-sm-6">
<img id="instagram" src='instagram.svg' />
<img id="linkedin" src='linkedin.svg' />
<img id="twitter" src='twitter.svg' />
</div>
</div>
</div>
So the weirdest thing, I've got 1 function that is to trigger under 2 conditions: when the window is resized and when the exit button is clicked.
This relates to an overlay menu that's actually intended for mobile users.
The functions work as they are supposed to, in both cases, when I have the inspection console open in chrome. However, when I close this and return to the normal browser window, the functions cease to execute.
On the mobile it is fine. I have only encountered this problem on the desktop/laptop (as I tried it on different desktops [iMacs] and 2 laptops [Macbooks, but the type of hardware I don't think matters]).
Currently the icons in the "#social" div are not being changed to white, which is what I expect to happen when opened, and when closed, they return to black. They are staying black throughout the execution.
Has anyone ever experienced this before? This is related to a Wordpress platform site. Totally custom built, no themes.
Please let me know if this description helps. If any code is needed, please let me know.
Ps: I thought it was a caching problem, on the terminals or on the server, and I cleared the cache on both but the issue still persists.
function closeOverlayMenu(){//closes the overlay mobile menu
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "black";
}
//changes icons to black on slide up of overlay
document.getElementById('instagram').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/instagram.svg";
document.getElementById('linkedin').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/linkedin.svg";
document.getElementById('twitter').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/twitter.svg";
//restores elements of the original homepage that were hidden for overlay
pipe.style.display="block";
contact.style.display="block";
case_studies.style.display="block";
$('#fp-menu .news').addClass("col-sm-2");
$('#fp-menu .portfolio').addClass("col-sm-3");
$('#fp-menu #social').addClass("col-sm-6");
};
I would expect that the function would trigger without the dev console being active. Please let me know if any further description or information would help.
Writing a small extension that once an anchor tag is clicked, the link is turned into regular text and a popup box comes up. Once this happens, a gif is supposed to autoplay inside the popup box, however, I see the stock 'image hasn't loaded' image once the popup box is animated in. My popup box element is appened through JQuery on click. I've tried setting the attr() to the filepath and using 'background-image' in CSS as well.
Javascript:
var counter = 0;
$(function() {
$("a").on("click", togglePopup);
});
function togglePopup() {
var popup = '<div class="popup"><img id="gif" src="boom.gif"/></div>';
counter++;
if (counter === 2) {
counter = 0;
$(".popup").remove();
}
if ($(this).children(".popup").length > 0) {
$(".popup").slideFadeToggle();
} else {
$(this)
.attr("href", null)
.css({
"text-decoration": "none",
color: "#333"
});
$(this).append(popup);
$(".popup").slideFadeToggle();
}
}
$.fn.slideFadeToggle = function() {
return this.animate({ height: "toggle" }, "fast");
};
CSS:
.popup {
border: 1px solid #999999;
border-radius: 10px;
cursor: default;
display: none;
position: relative;
width: 200px;
z-index: 100;
padding: 25px 25px 20px;
}
I would like to develop a popup function (html,css,js) and use it anywhere in the webpage.
Here is the pop function:
function pop (options) {
var mod = function( options ) {
var that = this;
this.op = { title: 'new pop' }; // for startup
for( var option in options ){
this.op[ option ] = options[ option ];
};
this.title = options.title;
this.build();
this.remove = function() { // remove this pop
document.body.removeChild( that.cover );
};
};
mod.prototype.build = function() { // create new pop
this.cover = document.createElement('div');
document.body.appendChild( this.cover );
};
return new mod( options );
}; // pop
var callpop = pop( { title: 'make a pop' } ); // so i can call
callpop.remove(); // and remove it
First question, is this design pattern make sense?
Second question, can i do :
this.remove = function() { // remove this pop
document.body.removeChild( that.cover );
that = undefined; // add this line to make the callpop undefined
};
console.log( callpop ); // so i can check if pop is display, than i can remove it by callpop.remove(), and make a new one callpop = pop()
beside give me a link, can u give me some short example please? Many thank!
Update 1:
I just would like to know, if you get a job to write a popups function, how would you code it? is my example make sense?
Since you are driving the whole popup flow with javascript thus it would be hard to make modifications on markup side. It's better to keep html in either markup or templates. Because it's easier to make edits in markup for the display part.
One very nice example of this would be how bootstrap manages its modal popups. Have a look at here. They drive it completely by markup and events are attached at the time of page load.
You can customize this behavior as per your needs but try to keep javascript in .js and html in .html or .templates.
Also, have a look at their source code for modal.
And for using template for modal you should have look at how angular-ui-bootstrap handles those scenarios.
Update:
For a basic reference see this demo in jsbin. And code here.
<SCRIPT TYPE="text/javascript">
function popup(mylink, windowname)
{
if (!window.focus)
return true;
var href;
if (typeof(mylink) == 'string')
href=mylink;
else href=mylink.href;
window.open(href, windowname, 'width=400,height=200,scrollbars=yes');
return false;
}
</SCRIPT>
popup('autopopup.html', 'ad')
Hi you can use this popup. Below the complete example of custom design
popup.
$(document).ready(function() {
// When site loaded, load the Popupbox First
loadPopupBox();
$('#popupBoxClose').click(function() {
unloadPopupBox();
});
$('#container').click(function() {
unloadPopupBox();
});
});
function unloadPopupBox() {
// TO Unload the Popupbox
$('#popup_box').fadeOut("slow");
$("#container").css({
// this is just for style
"opacity": "1"
});
}
function loadPopupBox() {
// To Load the Popupbox
$('#popup_box').fadeIn("slow");
$("#container").css({
// this is just for style
"opacity": "0.3"
});
return false;
}
/* popup_box DIV-Styles*/
#popup_box {
display: none;
/* Hide the DIV */
position: fixed;
_position: absolute;
/* hack for internet explorer 6 */
height: auto;
width: auto;
background: #FFFFFF;
top: 150px;
z-index: 100;
/* Layering ( on-top of others), if you have lots of layers: I just maximized, you can change it yourself */
margin-left: 15px;
/* additional features, can be omitted */
border: 2px solid #ff0000;
padding: 15px;
font-size: 15px;
-moz-box-shadow: 0 0 5px #ff0000;
-webkit-box-shadow: 0 0 5px #ff0000;
box-shadow: 0 0 5px #ff0000;
}
#container {
background: #d2d2d2;
/*Sample*/
width: 100%;
height: 100%;
}
a {
cursor: pointer;
text-decoration: none;
}
/* This is for the positioning of the Close Link */
#popupBoxClose {
font-size: 20px;
line-height: 15px;
right: 5px;
top: 5px;
color: #6fa5e2;
font-weight: 500;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<!-- HTML Structure for popup box-->
<div id="popup_box">
<!-- OUR PopupBox DIV-->
<h1>This IS A Cool PopUp</h1>
<div runat="server" id="dvContent"></div>
<a id="popupBoxClose">Close</a>
</div>
<!-- Main Page -->
<div id="container">
<h1>Click on link to load sample popup</h1>
<input type="button" value="Click Me" id="btnClick" onclick="loadPopupBox();" />
</div>
I have searched several posts but cannot find something similar to what I need to do, or what I have found I cannot get to work - pretty sure that is just me though!
So, there are 3 links on a page. When a link is clicked it should display the photo (on the same page) with an overlay applied to it. I can get the image to open but for the life of me cannot figure out how to get the overlays to attach. When the image opens it should stay on the same page (with the links visible through the overlay). The user should be able to click a close button or the image itself to go back to the links display.
I know the code is a mess as I've been trying anything I can think of to try and get this to work, since I'm currently stuck on getting everything to display properly and have not even gotten to the close function yet if someone can give me a hint I would really appreciate it.
Thanks!
HTML
<!doctype html>
<html>
<head>
<title> Image preview </title>
<meta charset="utf-8">
<link rel="stylesheet" href="preview.css">
<script src="preview.js"></script>
<script>
window.onload = function() {
Preview.init();
};
</script>
</head>
<body>
<ul>
<li><a href="https://courses.oreillyschool.com/advancedjavascript
/homework/images/image1.jpg" data-preview="image1">Mt. Rainier,
1</a></li>
<li><a href="https://courses.oreillyschool.com/advancedjavascript
/homework/images/image2.jpg" data-preview="image2">Mt. Rainier,
2</a></li>
<li><a href="https://courses.oreillyschool.com/advancedjavascript
/homework/images/image3.jpg" data-preview="image3">Mt. Rainier,
3</a></li>
</ul>
</body>
</html>
CSS
.previewOverlay {
position: absolute;
display: none;
top: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.7);
width: 100%;
height: 100%;
}
.previewOverlay img {
position: relative;
border: 20px solid white;
border-radius: 10px;
top: 50px;
left: 50px;
}
.close {
position: absolute;
top: 0px;
left: 0px;
color: #fdfdfd;
font-size: 50px;
text-shadow: 0px 0px 5px black;
}
.close:after {
content: "\2717";
}
.close:hover {
color: orange;
}
JavaScript
function Preview () {
var mtnPics = document.querySelectorAll("a");
console.log(mtnPics);
mtnPics.addEventListener("click", function(event) {
event.preventDefault()
});
for (var i = 0; i < mtnPics.length; i++) {
mtnPics[i].onclick = showPicture;
}
function showPicture (pictureURL) {
var picPicked = document.getElementById("a").value;
console.log(picPicked);
//Create Div's for image display.
var ul = document.getElementById("ul");
var picDiv = document.createElement("div");
picDiv.setAttribute("class", "previewOverlay");
var imgDiv = document.createElement("div");
imgDiv.setAttribute("class", "previewOverlay img");
var imgSelected = document.getElementById("a").value;
console.log(imgSelected);
imgDiv.src = imgSelected;
var buttonClose = document.createElement("button");
//Assign divs and buttons
buttonClose = document.setAttribute("class", "close");
ul.appendChild(imgDiv);
imgDiv.appendChild(pictureURL);
imgDiv.appendChild(buttonClose);
picDiv.appendChild(imgDiv);
picDiv.insertBefore(ul, picDiv.firstChild);
//document.body.appendChild(picDiv);
buttonClose.onclick = closePicture;
}
function closePicture(targetURL) {
document.removeElement('picDiv');
}
}