Transformicons - Icon hidden behind overlay - javascript

I have been playing around with Zerodevx Transformicon where the Transformicons adds a class (tcon-transform) when the icon is transformed to the secondary version (in this case, the minus).
On clicking the "+" icon a open() function is called to open the overlay. On clicking the "-" icon, closeNav() function is called to close the overlay.
Once the overlay is opened, the "-" icon is disabled as it is behind the overlay.
See this code snippet for your reference as an example
function openNav() {
// if the element has the class tcon-transform (added/removed before calling this)
if (event.target.classList.contains("tcon-transform")) {
// the original icon was the plus: open the navigation
document.getElementById("myNav").style.left = "50%";
} else {
// the original icon was the minus: close the navigation
closeNav();
}
function closeNav() {
document.getElementById("myNav").style.left = "100%";
}
}
.overlay {
height: 100%;
width: 50%;
position: fixed;
z-index: 1;
top: 0;
left: 100%;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.5);
overflow-x: hidden;
transition: 0.5s;
}
#transformicon {
float: right;
}
<head>
<!-- Import webcomponents-lite.js polyfill -->
<script src="https://cdn.rawgit.com/webcomponents/webcomponentsjs/v0.7.19/webcomponents-lite.min.js"></script>
<!-- Import zero-transformicon build bundle -->
<link rel="import" href="https://cdn.rawgit.com/zerodevx/zero-transformicon/v0.1.0/build/zero-transformicon.build.html">
</head>
<body>
<div id="transformicon">
<zero-transformicon icon="plus-minus" onclick="openNav()">
</zero-transformicon>
</div>
<div id="myNav" class="overlay"></div>
</body>
I was thinking about how to get around this problem. One way is probably add another icon inside the overlay with the same functionality of the icon outside the overlay. When the "+" is clicked, The overlay is opened with the "-" icon inside the overlay which calls the closeNav() function, the icon outside the overlay should be hidden so that only one icon is visible.
Once the overlay is closed, the transformicon should display the "+" sign again. Would love some thoughts on the best way to achieve this. Thank you.

Related

on click function to reveal hover overlay - appears on click but won't disappear on 2nd click

I have a portfolio grid of images and when a user hovers or taps on a mobile a transparent overlay with some text and a button appears
I am using the on click function
It works fine on my touch screen laptop but not on my iOS phone or tablet
The overlay appears on first tap, but when I tap again it does not disappear unless I tap another grid image.
I would like it to disappear on 2nd tap
I have tried various ways of making this work, and the closest I have got it for it to disappear when another grid image is tapped
Here is my code:
HTML
<div class="col-xs-12 col-sm-7"><div class="image-wrap">
<div onclick="on()">
<img src="assets/images/pic.jpg">
<div class="overlay blue">
<h3>Portfolio item 1</h3>
<hr>
<p><strong>Coming Soon</strong><br> some overlay text here</p>
<br>
View Website
</div>
</div>
</div>
</div>
JS
function on() {
document.getElementById("overlay").style.display = "block";
}
function off() {
document.getElementById("overlay").style.display = "none";
}
CSS
.image-wrap {
display: inline-block;
position: relative;
}
.overlay {
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
color:white;
opacity: 0;
transition:opacity .5s ease-out;
text-align: center;
hr {
border: 1px solid #fff;
width: 10%;
}
}
.image-wrap:hover .overlay {
opacity: 1;
}
.red {
background: rgba(102,67,154,0.7);
}
.blue {
background: rgba(23,56,179,0.7);
}
.purple1 {
background: rgba(140,23,179,0.7);
}
.purple2 {
background: rgba(71,13,142,0.7);
}
}
I initially tried this with just CSS which gave me the desired result on all devices apart from iOS!
So I have decided to use the on click function to be more sure it works on all devices. I added the on click function to my existing code which I wrote to be used with CSS, but as I am rather new to JS I am wondering if I have it in the wrong place (the on-click)? I have tried lots of variations but this is the best I can get it to work
Any ideas of suggestions on how I can make the overlay disappear on the 2nd click would be great!
js fiddle
https://jsfiddle.net/49h450g9/14/
Please note: This works fine on touch-screen laptops, just not mobiles!
Thanks!
Your functions on and off on jsfiddle example are not working at all. What happening is your hover effect on normal screen which as the behavior of mobile work like focus on mobile device.
Moreover, from your description here I believe that you have more than one portfolio on your project. So you have several element with the id overlay and multiple use of same id is not validate for html and also will cause JavaScript error.
To let your project work properly follow my list below:
Make sure you have jQuery added on your project (generally before </body>)
Now let us thinks of these portfolio item below
<div class="portfolio">
<img src="images/portfolio-1.jpg" alt="...">
<div class="overlay">Link</div>
</div>
<div class="portfolio">
<img src="images/portfolio-2.jpg" alt="...">
<div class="overlay">Link</div>
</div>
<div class="portfolio">
<img src="images/portfolio-3.jpg" alt="...">
<div class="overlay">Link</div>
</div>
Then give the normal hover css styles inside media query like this. So that it never effect your js styles (I decide medias less than 992px as mobile device):
.portfolio{
background-color: #f1f1f1;
position: relative;
}
.portfolio .overlay{
background-color: rgba(0, 0, 0, 0.7);
display: block;
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: all 0.3s ease;
width: 100%;
height: 100%;
}
#media all and (min-width:992px){
.portfolio:hover .overlay{
opacity: 1;
}
}
Now with jQuery you can use event while user click any of the .portfolio item and toggle a class on it by which we will add further css to it:
$(document).ready(function(){
'use strict';
$(.portfolio).on('click', function(){
$(this).siblings('.portfolio').removeClass('hovered');
$(this).toggleClass('hovered');
});
});
Now it will add hovered class on 1st click and remove the hovered class on 2nd click. Also it will remove .hovered from other portfolio items. Now add the same css to it as the hover effect:
.portfolio.hovered .overlay{
opacity: 1;
}
Try this:
$("*").on("click, touchend", function(e) { $(this).focus(); });
or to achieve the opposite;
$("*").on("click touchend", function(e) { $(this).hover(); });
However the hover event doesn't work well on ios or other mobiles.
Another suggestion is to try replace any css using
:hover with :active.

Add body overlay when a sidebar menu opens

I have a working sidebar menu that opens up when clicked. However, the background overlay doesn't work efficiently as the website has many elements. Here's the JS that does the work of adding background color to opacity of 0.4
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
document.getElementById("mainbody").style.marginRight = "0";
jQuery("body").addClass("mySidenav_intro");
document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
}
When clicked; the body of the pages change to
<body id="mainbody" class="mySidenav_intro" style="margin-right: 0px; background-color: rgba(0, 0, 0, 0.4);">
However, it changes only the background color of the website. I want to create an overlay of sort like a modal does when it opens. How should I achieve this?
Rather than change the background colour of the body, what you want is an element that will sit on top with some opacity, for instance using the approach here.
At its simplest, you could have a div with class overlay, use JS to trigger an enabled class on it, and use CSS:
.overlay {
display: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1;
background-color: rgba(0,0,0,0.9);
}
.overlay.enabled {
display: initial;
}
By default this will cover everything, to keep it from covering your sidebar just make sure it has a z-index higher than the overlay (i.e. 2).

How to close a side bar when i pressed anywhere

What I want to do is to dismiss the sidebar when I press anywhere on the screen.
How can it be done? How can I make it so that when I hover over my image, my text would appear instead of it being visible the whole time?
function openNav() {
document.getElementById("mySidenav").style.width = "300px";
document.getElementById("toggle").style.position = "static";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.getElementById("toggle").style.marginRight = "0";
document.getElementById("toggle").style.position = "relative";
}
#toggle {
position: relative;
left: 400px;
font-size: 1.2em;
visibility: visible;
}
#toggle:hover {
color: white;
transition: 0.5s;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: transparent;
overflow-x: hidden;
transition: 0.5s;
padding-top: 50px;
}
.sidenav a {
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
.sidenav a:hover,
.offcanvas a:focus {
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
<div>
<ul id="topBar">
<li id="ixora">Ixora</li>
<li class="lists">2014</li>
<li class="lists">2015</li>
<li id="toggle" onclick="openNav() ">☰</li>
</ul>
</div>
<div id="mySidenav" class="sidenav">
×
<span class="textImage">Outing</span>
<img src="outing.jpg">
<span class="textImage">Prom Night</span>
<img src="prom.jpg">
<span class="textImage">PortDickson Trip</span>
<img src="pd.jpg">
<span class="textImage">Merdeka</span>
<img src="merdeka%20(2).jpg">
</div>
I honestly think you should be using jQuery here as it's fantastic for DOM manipulation. If for some reason you have to use vanilla js then it's going to be a little trickier.
Adding jQuery to your project is easy and well explained on the jQuery site. Here;s a comparison of selecting an element in js/jquery:
Vanilla JS:
document.getElementById("mySidenav")
jQuery:
$('#mySidenav')
To get things to happen when events happen (i.e. button press, or clicking away from a menu) you set up event handlers.
It's hard to picture from your code as there seems to be CSS missing for #topBar so I can't see your site very well (here's your code running in jsfiddle).
But lets say you have a button with ID of #openToggle. You would set up your sideNav in css with the correct width, height, etc, and leave it as display: none. Then we create an event handler to do something when you click that button:
//event handlers go at the bottom of your js file or script tag
$('#openMenu').on('click', openMenu);
That example is basically saying when the element with ID 'openMenu' is 'clicked' the run the 'openMenu' function - simple! :)
The openMenu function would look something like (basic example):
function openMenu() {
var $menu = $('#sideNav');
$menu.show();
};
A better way would be to have a toggle function that toggles the menu based on whether it's already open or closed:
function toggleMenu() {
var $menu = $('#sideNav');
if (($menu).is(':visible')) { //if it's visible
$menu.hide(); //hide the menu
} else { //else it's hidden
$menu.show(); //so show it
}
};
// event handler for menu toggle button
$('#menuToggle').on('click', toggleMenu);
With regards to closing the menu when you click away from it, you could bind an event handler to the body of the page and use jQuery's .one() function (runs only once) which will detect if the body is clicked and then run the menuToggle funtion - you'd end up with 2 handlers for this:
// event handler for menu toggle button
$('#menuToggle').on('click', toggleMenu);
$('body').one('click', toggleMenu);
Alternatively you could have the menu close when your mouse pointer leaves the menu?:
//event handlers
$('#menuToggle').on('click', toggleMenu);
$('#sideNav').mouseleave(toggleMenu);
The mouseleave handler is basically saying, once the mouse pointer leaves the element with ID of 'sideNav' then run the toggleMenu function.
I'm a newb too so my examples may not be great, but I hope I helped at least a little. Hopefully some real javascript devs will be along shortly to add to this or give better examples.
Cheers,
Dave
JQuery
$( document ).onclick(function() {
$("#mySidenav").hide();
}
Reference documentation:
JQuery .on
JQuery .hide
With javascript, you can do the following:
document.onclick = function(e){
if(e.target.id == "mySidenav"){
return false;
}
closeNav();
}
I see that you already have functions to open and close your sidebar,
clicking "anywhere" is the same as "clicking on the body", But I guess that you don't want your sidebar to close when you're clicking on it.
So, here's what you can do :
var myNav = document.getElementById("mySidenav");
myNav.onclick = function(e) {
e.stopPropagation();
}
document.body.onclick = function(e) {
closeNav();
}
So, when you click on your sidebar, you won't click on the body because the event propagation is stopped, and when you click elsewhere, it will close your sidebar.
Hope it helps,
best regards

TypeScript Modal Window

I need to show a Modal in TypeScript. I don't want to use any library(bootstrap,..) to style it, I have to use own less styling for it. what I can use to Create a Modal? it can be a javascript modal that supported by typescript and by all browsers.
I tried to use showModal() like this:
This is my TypeScript Code:
function CreateModal() {
document.getElementById("myDialog").showModal();
}
It gave me this error - showModal is not exists.
even if It works it is not supported in IE and Firefix only works in chrome.
and this is my index.html
<script src="scripts/TypeScripts/Modal.js"></script>
<button onclick="CreateModal()">Show dialog</button>
<dialog id="myDialog">This is a dialog window</dialog>
I tried to use Onclick as well but it says does not existed.
span.onclick = function () {
modal.style.display = "none";
}
I know it's been a few months since this question was asked, but I recently had the same problem and was able to get a solution working.
In the typescript, you can ignore the need for the HTMLDialogElement by casting your dialog to type any.
openMyDialog() {
let myDialog:any = <any>document.getElementById("myDialog");
myDialog.showModal();
}
In your HTML, you just attached this function to the angular (click).
<button (click)="openMyDialog()">Open My Dialog</button>
The same technique can be used for the dialog's show() and close() functions.
If you're up for doing everything manually, you can place a partially transparent grey DIV over everything on the page, then a single DIV on top of it with your dialog. Toggle visibility with JS/CSS, and you're able to style any way you like it.
Here's a quick example, with a significant need for improved styling:
div.greyModal {
opacity: 0.7;
background-color: grey;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
div.modalContent {
opacity: 1;
position: fixed;
width: 75%;
left: 50%;
margin-left: -37.5%;
height:100px;
background-color: white;
border: solid 4px black;
border-color: black;
}
<div>
This is the web page content. <span style="color:red">This is red text that appears faded when the modalToggle divs are visible</span>
</div>
<div class="greyModal modalToggle">
</div>
<div class="modalContent modalToggle">
This is the content of my modal dialog
</div>

On touching uppermost div selects contents of div under it - z-index property

I have a strange problem though, when i click the content with z-index 20, the thing with z-index 1 gets selected in my phone.
The image has both the screen shot - the part on the right side of the image is only for illustrating my problem, as such the white gray div is behind my content div.
Can someone please rescue.
Related CSS files:
#content {
background: #000000;
background: url(../img/WireFrame_test.png) center center no-repeat;
box-shadow: 0 0 15px 15px #222222;
overflow-x: hidden;
z-index: 20;
}
.snapjs-right .snap-drawer-right {
display: block;
z-index: 10;
}
.snapjs-right .snap-drawer-left {
display: block;
right: 0;
left: auto;
z-index: 1;
}
As requested related HTML scripts:
<body>
<div class="snap-drawers" id="leftid">
...
<div class="snap-drawer snap-drawer-right overthrow">
<div>
<h3>Questions</h3>
<div class="demo-social">
</div>
<h4>Java</h4>
<ul>
<li>What is Java?</li>
<li>Uses of Inheritence?</li>
...
</div>
</div>
<div id="content" class="snap-content">
my content goes here
</div>
</div>
</body>
Surely because "Uses of inheritance" is the only link element (other than "What is java"), it will be selected - there's nothing else to select!
Try setting the display of that element to "none" when it is hidden.
You could try to hook into the event when clicking / dragging on the content panel and do an event.stopPropagation(); or an event.preventDefault(); when the panel is closed.
As far as i know, you can see that coz Snap.js add's corresponding classes like (class="snapjs-right" or class="snapjs-left") to the body in order to indicate if a panel is open or not.
So first you've got to check that.
With jQuery it would look something like this:
$(document).ready(function() {
$("#UsesofInheritence_Anchor_ID").bind("click", function() {
if (!($('body').hasClass("snapjs-right"))){
event.stopPropagation();
event.preventDefault();
}
});
});

Categories

Resources