How to freeze browser window intentionally (like alert, confirm and prompt does)? - javascript

Is there any way of freezing the browser window intentionally like alert, confirm and prompt (in short: "acp") does?
I want to show a modal dialog with custom css instead of the native popups for "acp" but also want to have the ability to freeze the browser until I have users feedback just like "acp".
But man, why? This is bad practice (uh I have to downvote)!
So when it is bad practice - then why does "acp" actually offer this synchronous behavior? Because in some particular scenarios its just exactly the right tool for an appropriate UX. Those native modals do look so ugly and are also very limited at the same time.
Here's just one quick and dirty example where it would be totally fine to freeze the browser until the user gives feedback. Lets say we have a form with an input[type="reset"]-element. So before we really let the form reset we ask the user something like: "Are you sure you want to reset (data will be lost)?".
If I would be fine with the native modal look (which I'm not) I could do:
document.querySelector('form').addEventListener(
'reset', e => confirm('Are you sure you want to reset (data will be lost)?') || e.preventDefault()
);
<form>
<input placeholder="type something, reset and cancel to keep input value" style="width:100%">
<input type="reset">
</form>
So "everybody" should agree (edit: or at least somebody could) this isn't bad practice, right?
But how can we achieve the same with a custom styled modal/dialog/popup?
I'm -of course- not asking for the HTML/CSS part but for the capability of freezing the browser window via JavaScript!
To be honest, I actually expect some downvotes for this but maybe there is this one Killer JavaScript Ninja, who have this one special hack to make it possible...

You can't freeze the browser application like the native dialogs do. Those are not built with JavaScript, they are built with native code and can affect the browser application in any way. JavaScript is prohibited from affecting the client application in such ways.
But, you can freeze interactions with your page content within the browser window....
Just place a window sized div above the page with fixed positioning. That will prevent the user from being able to interact with anything on the main page (behind it). Then, display your modal dialog on top of that. When the user clears the modal, hide it and the window sized div, thus making the main page interactive again.
let modal = document.querySelector(".modal");
let pageCover = document.querySelector(".pageCover");
let main = document.querySelector("main");
document.getElementById("open").addEventListener("click", function(){
modal.classList.remove("hidden");
pageCover.classList.remove("hidden");
main.addEventListener("focus", preventFocus);
});
document.getElementById("close").addEventListener("click", function(){
modal.classList.add("hidden");
pageCover.classList.add("hidden");
main.removeEventListener("focus", preventFocus);
});
function preventFocus (evt){
evt.preventDefault();
}
.hidden { display:none; }
.pageCover {
position:fixed;
z-index:10;
background-color:rgba(0,0,0,.25);
width:100vw;
height:100vh;
top:0;
left:0;
}
.modal {
position:absolute;
z-index:100;
background-color:aliceblue;
border:2px double grey;
width:200px;
height:200px;
top:30%;
left:30%;
text-align:center;
}
.modalTitle {
margin:0;
background-color:#00a;
color:#ff0;
padding:5px;
font-weight:bold;
font-size:1.1em;
}
#close {
background-color:#800080;
color:#ff0;
border:1px solid #e0e0e0;
padding:5px 10px;
}
#close:hover { background-color:#c000c0; }
<main>
<h1>This is some page content</h1>
<p>And more content</p>
<button id="open">Click Me To Show Modal</button>
<div>More content</div>
</main>
<div class="hidden pageCover"></div>
<div class="hidden modal">
<div class="modalTitle">Modal Title Here</div>
<p>
Now, you can only interact with the contents of this "modal".
</p>
<button id="close" >Close</button>
</div>

You can place everything within a div except for your popup. You can then turn on/off pointer events via css.
Everything within the div will no longer be interactable. This will give the appearance of freezing the browser window.
.freeze { pointer-events: none; }
Note: When adding pointer-events to an element this affects all child elements as well, so placing it on the body would also lock the popup.
Once the popup has been closed, we can remove the freeze class from the div and everything will start working again.
const content = document.getElementById('content')
const overlay = document.querySelector('.overlay')
const a = document.querySelector('.open-overlay')
const close = document.querySelector('.overlay .close')
// Open a popup and freeze the browser content
a.addEventListener('click', e => {
e.preventDefault()
content.classList.add('freeze')
overlay.classList.remove('hidden')
})
// Close the popup window and unfreeze the browser content
close.addEventListener('click', e => {
e.preventDefault()
content.classList.remove('freeze')
overlay.classList.add('hidden')
})
.freeze { pointer-events: none; }
.hidden { display: none; }
.overlay {
position: fixed;
z-index: 100;
padding: 20px;
background: white;
border: solid 1px #ccc;
width: 300px;
top: 20px;
left: 0;
right: 0;
margin: auto;
}
<div class="overlay hidden">
<h1>Overlay</h1>
Close
</div>
<div id="content">
Open Overlay
<p>Hello World</p>
<p>Hello World</p>
<p>Hello World</p>
<p>Hello World</p>
<p>Hello World</p>
<form>
<input type="text">
</form>
</div>

Related

Why toggling doesn't work on Firefox Developer Tools?

I don't know why my javascript code is not toggling on firefox developers tools, and that's my code:
const hamburger = document.querySelector('.header .nav-bar .nav-list .hamburger');
const mobile_menu = document.querySelector('.header .nav-bar .nav-list .menu');
const header = document.querySelector('.header-container')
hamburger.addEventListener('click',() => {
hamburger.classList.toggle('active');
});
Maybe you can check, if your element is clicked or not with console.log()
hamburger.addEventListener('click', function(){
console.log("test")
})
I suggest you not to use arrow function in addEventListener, because of 'this' problem in arrow function
When you open developer tools in Firefox, on the left hand side of the menu there are tab header for "inspect", "console", network" and so on.
On the right hand side of the same menu bar, there is an icon of a framed document that shows "Select an iframe as the currently targeted document" when you hover over it. Click the icon and select the iframe containing the .header-container element.
Assuming the correct nested elements have been set up in HTML, the posted code now runs if you paste it after the script input prompt and press enter, and you can click the hamburger icon to toggle its active cf class.
Use of the const declaration in the pasted script prevents it being run more than once without reloading the page, which is a good thing - an even number of anonymous listeners that each toggle active would not affect the class list of the hamburger element.
FWIW, some HTML that can be used to show the code in the post "just works" when run in the Firefox console:
<style>
div { margin: 0.5rem; margin-left: 2rem; border: thin solid maroon;}
.active {background-color: yellow;}
</style>
<div class="header-container">
.header-container
<div class="header">
.header
<div class="nav-bar">
.nav-bar
<div class="nav-list">
.nav-list
<div class="hamburger">
.hamburger
</div>
<div class="menu">
.menu
</div>
(nav-list)
</div>
(nav-bar)
</div>
(header)
</div>
(header-container)
</div>
However, if the hamburger menu structure is inside an iframe element it needs to be selected first to prevent generating an error that hamburger is null.

Inline(html) onclick function doesn't work as expected on mobile devices

I have a div html tag which has a "onclick" function. On a mobile device, to be specific web browser(blackberry work) on iPhone 12, I have to click on a particular div several times to invoke onclick function. I have looked into similar problems on StackOverflow but all of them talk about using $('#div').on('click touchstart'). In my case, I cannot do that. I'm looking for alternative solution that works for both desktop and mobile page consistently without screwing the user experience.
function changeText(){
$("#text-tag").text('Text replaced');
}
.div-button {
border-radius:50%;
border: 1px solid blue;
background: blue;
width:30px;
height:30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h4> Click on the blue circle to do magic!</h4>
<div class="div-button" onclick="changeText()">
</div>
<p id="text-tag">This text will be replaced</p>

simulate real user click bypassing a web honeypot

I would like to scrape a web page but I can't be detected as a bot. I am using js to fetch data, fill inputs or click buttons.
I have read that I have to take into account some "diplayed: none" attributes as they seems to be honeypots. In my webe there is a div which shows this:
// When mouse is not used
<div style="position: absolute; top: 0px; left: 0px; display: none; z-index: 10000;"><div class="tip">
// When mouse has moved but not on any clickable point
<div style="position: absolute; top: 264px; left: 272px; z-index: 10000; display: none;"><div class="tip">
// When mouse on a clickabel point
<div style="position: absolute; top: 264px; left: 272px; z-index: 10000;"><div class="tip">
This make me think the web check if the click has been done programmatically or if it is from a real user.
Thereby
Is this something I have to work with or it is insignificant??
If so, how could I bypass it??
Thank you very much
display:none; isn't your only problem, one could also use negative left:-100px; or top:-100px; values, and/or color:white; on a white background, and so forth.
But they are all foolhardy attempts to prevent bots when all they had to do is this...
Luckily, JavaScript already provides a mechanism for determining if an event was user-initiated via the "isTrusted" boolean property. Usage is as follows...
<button id="logon" onclick="if(event.isTrusted){SomeFunction();}">Logon</button>
Any JavaScript attempt to click this button such as logon.click(); would fail this test and the function would never run, and no there's no way you can simulate a human gesture.
Hackers exploit bad programmers who use foolish tricks like the ones you and I mentioned.
Good point raised by Dave, but the version posted was for clarity purposes.
See if you can fool this little modification...
<!DOCTYPE html>
<head>
</head>
<body>
<script type="text/javascript">
function SomeFunction(event){
if(event.isTrusted){
alert('This came from a human');
} else {alert('This came from a bot');}
}
</script>
<button id="logon" onclick="SomeFunction(event);">Logon</button>
<button onclick="logon.click();">BOT clicking button</button>
<button onclick="SomeFunction(true);">BOT running function directly</button>
</body>
</html>
NB: For the last button, we are simulating a BOT here through a button so we have the luxury of passing the human onclick event to get through, but that won't be the case for a BOT and hence the boolean variable I added.

How to make a tab (i.e. Home, About, Contact) clickable in HTML?

I want to make my menu button clickable so that it navigates to the desired section or another page with another content. For example in my website I have a menu "About me". I want that as soon as an user clicks on it should be able to see the paragraph about "ABOUT ME" which I stored in my HTML file.
I have another problem and that is when I make the window size smaller the paragraph text moves into unwanted position (in my case below menu area). Otherwise, in full sized window it's fine.
I left my javascript class empty because I haven't needed any .js functinality yet.
My code:
main.html:
<!--
All the html code will go in this file. This is the main core file of any website.
Some php code may be included if necessary.
-->
<!DOCTYPE html>
<html>
<head>
<html lang="en">
<html charset="utf-8">
<title>Welcome to Fatah's world!</title>
<link rel="stylesheet" href="main_design.css"/>
<!--<img src="bricks.JPG" alt="blue bricks" width="300" height="1000">-->
<style type="text/css">
<!--right now nothing to do here-->
</style>
</head>
<body>
<h1 id="style_header">Welcome to my green world!</h1></div>
<div id="menu_area" >
<div id="home">HOME</div><br /><br /><br />
<div id="about_me">ABOUT ME</div><br /><br /> <br />
<div id="gallery">GALLERY</div><br /><br /> <br />
<div id="contact_me">CONTACT ME</div><br /><br /> <br />
<div id="my_diary">MY DIARY</div><br /><br /> <br />
<div id="blog">BLOG</div><br /><br /> <br />
</div>
<!-- I want to call the home.html class here so that the paragraph is shown in my homepage under the home menu.-->
<p id="paragraph_home"><b>
Thank you for spending your time to visit my website.
My name is Jabir Al Fatah. I live in Sweden. I have
a lot of interest in web developing and 3d graphics
designing. I am a travel addicted guy. I love to travel and
have experience about diversity among life and nature.
I am passionate. I don't do everything just becuase I
am obliged to do,rather I like to take risk to be done
with something just because I like.I haven't have a
wonderful childhood in my life. But I admit it that my
parents were surprisingly aware of my future and even
every singlestep in my life. Their love and affection
fulfilled all of my demand.Well, I just admired them a
little. There are tons of others stuff I can say.
However, in my life, changes happen very fast.
</b></p>
<p id="paragraph_aboutme">This paragraph should appear while clicking on "About me". Beisides,
it's not accurately placed in the window. I need to fix that
.Another problem is that this paragraph moves under the menu area by
pushing it up when I make the window size smaller. </p>
<div id="footer">Developed by Jabir Al Fatah</div>
</body>
</html>
main_design.css:
/*
All the css properties will go in this file. CSS properties design the site to look it prettier.
*/
#style_header {
background-color:blue;
text-align:center;
padding:20px;
margin:-8px;
border:4px solid red;
}
#paragraph_home{
text-align:center;
display:inline-block;
width:300px;
vertical-align:top;
font-family:verdana;
color:blue;
size:20px;
margin:9px;
}
#paragraph_aboutme {
text-align:center;
display:inline-block;
width:200px;
vertical-align:bottom;
font-family:verdana;
color:blue;
size:20px;
margin:9px;
}
#menu_area {
border:4px solid red;
margin:-8px;
background-color:#FFD700;
padding-top:30px;
margin-top:4px;
height:600px;
width:150px;
display:inline-block;
vertical-align:top;
}
body {
background-image:url(green.JPG);
background-repeat:no-repeat;
}
#footer {
background-color:gray;
margin:-8px;
margin-top:6px;
border:2px solid green;
text-align:center;
/*margin-bottom:-20px;*/
width:99.6%;
position:absolute;
}
#home {
font:bold 20px Tahoma;
text-align:left;
}
#about_me {
font:bold 20px Tahoma;
text-align:left;
}
#gallery {
font:bold 20px Tahoma;
text-align:left;
}
#contact_me {
font:bold 20px Tahoma;
text-align:left;
}
#my_diary {
font:bold 20px Tahoma;
text-align:left;
}
#blog {
font:bold 20px Tahoma;
text-align:left;
}
main_interaction.js:
/*
All the java script code will go in this file. This class will add all the interaction and behaviour functionality for
the website.
*/
Here's basically what you want.
Do note that I used Bootstrap as a CSS framework, which makes it alot easier to create lay-outs like yours. I took the liberty to build your lay-out from the ground up, without any special colors.
DEMO: JSFiddle
HTML:
<div class="row">
<div id="header" class="col-xs-12">
<h1>Welcome to my green world!</h1>
<hr />
</div>
<div class="col-xs-3">
<ul>
<li id="home">HOME</li>
<li id="gallery">GALLERY</li>
<li id="about">ABOUT ME</li>
<li id="contact">CONTACT ME</li>
<li id="diary">MY DIARY</li>
<li id="blog">BLOG</li>
</ul>
</div>
<div class="col-xs-9 home">
<p>Thank you for spending your time to visit my website. My name is Jabir Al Fatah. I live in Sweden. I have a lot of interest in web developing and 3d graphics designing. I am a travel addicted guy. I love to travel and have experience about diversity among life and nature. I am passionate. I don't do everything just becuase I am obliged to do,rather I like to take risk to be done with something just because I like.I haven't have a wonderful childhood in my life. But I admit it that my parents were surprisingly aware of my future and even every singlestep in my life. Their love and affection fulfilled all of my demand.Well, I just admired them a little. There are tons of others stuff I can say. However, in my life, changes happen very fast.</p>
</div>
<div class="col-xs-9 gallery hidden">
<p>This is the gallery.</p>
</div>
<div class="col-xs-9 about hidden">
<p>This paragraph should appear while clicking on "About me". Beisides, it's not accurately placed in the window. I need to fix that .Another problem is that this paragraph moves under the menu area by pushing it up when I make the window size smaller.</p>
</div>
<div class="col-xs-9 contact hidden">
<p>Contact me here.</p>
</div>
<div class="col-xs-9 diary hidden">
<p>My diary will be here.</p>
</div>
<div class="col-xs-9 blog hidden">
<p>Blog posts appear here.</p>
</div>
<div id="footer" class="col-xs-12">
Developed by Jabir Al Fatah</div>
</div>
CSS:
.row {
margin: 0;
}
#header {
text-align: center;
padding: 20px;
}
.col-xs-9 {
font-family:'Verdana';
font-size: 13pt;
}
.col-xs-3 {
border-right: 1px solid #DDD;
line-height: 40pt;
font-family:'Tahoma';
font-size: 15pt;
font-weight: bold;
margin: 0;
padding: 0;
}
.col-xs-3 ul {
list-style-type: none;
}
#footer {
border-top: 1px solid #DDD;
text-align: center;
position: absolute;
bottom: 0;
left: 0;
padding: 5px;
}
li:hover {
cursor: pointer;
text-decoration: underline;
}
JS:
$("li").on('click', function () {
$(".col-xs-9").addClass("hidden");
$("." + $(this).attr("id")).removeClass("hidden");
});
If you insist on having about the same colors you used back, then use this link: JSFiddle
Alright, so here are a few techniques that could work:
if you want that paragraph to show up ONLY when they are in that section of the website (like home, about, etc), just put it in a div, and name the div what you want that paragraph to be called, example
<div id="about">
This is the about paragraph!
</div>
then go to your CSS and add this:
#about {
display: none;
}
what this will do is make it so that the web page doesn't render it at all.
Ok so next you need to make your about link button (this technically isn't a link though, your just rendering and hiding a div). Once you find your button add this code somewhere in the tag
onclick="showabout()"
this will make it so that when they click this button it will run this showabout() function
in your javascript:
function showabout() {
//THIS CODE HIDES ALL OF THE OTHER DIVS \/ \/ \/
document.getElementById("home").style.display = "none";
document.getElementById("Gallery").style.dispaly = "none";
//FOR EACH PARAGRAPH ADD ONE OF THE ABOVE LINES OF CODE AND SIMPLY CHANGE THE ID, LIKE HOME, OR GALLERY, ETC
//THIS LINE OF CODE BELOW THEN SHOWS THE PARAGRAPH \/ \/ \/
document.getElementById("about").style.display = "block";
}
so then just list your paragraphs in your HTML like so:
<div id="home">This is the Home paragraph!</div>
<div id="about">This is the About paragraph!</div>
<div id="gallery">This is the Gallery paragraph!</div>
(Etc)
and that's it! Your code will swap out the paragraphs for you!
If you don't want to do it that way you could simply just make several different pages and then make hyperlinks between them... Which honestly I don't understand why you don't just want to do it that way, its normally a lot easier and looks just as good.
If you don't want to do it that way you could put an IFrame in your website and just have them as separate pages but then show the iFrame below, but Iframes are kinda hated by search engines so its going to really hurt you if you want your page high on the search results....
If you still don't want to do it that way don't fear, there is an actual language that is programmed to do what you want to do, its called Meteor.js. You would also have to use iron-router though, and that means you are going to also need to install meteorite.
Concerning your paragraph that keeps moving when you change your screen size. I faced this problem a lot before I knew the simple answer, which is:
1) Use Floating (a css property to push the div or element as far to one horizontal direction as possible)
2) Don't use px in css, use %! This way your paragraphs change when your screen size changes. (% or percent is a measurement based of the screen size, so 20% is 20% of the screen size)
3) If you don't want it to move at all, use CSS Position Property!
Best of luck!!!

Focus change disturbing the UI in chrome and IE

I'm trying to recreate the issue i was facing at my work. It can roughly be translated as follows.
Here goes the code.
<button style="margin:20px 0;">Click this button first and press tab </button>
<div class="div2">
</div>
<div class="div1">
<span>ABCDEFGHIJKLMNOPQRST</span>
<button >moved out </button>
</div>
.div1
{
width:200px;
overflow: hidden;
background-color:#ff0;
margin-left:50px;
}
div button
{
width:50px;
margin-left:180px;
}
.div2
{
position:fixed;
height:100%;
width:50px;
background-color:#f00;
}
Please use this for better clarification jsfiddle in chrome and IE.
The problem is- if we press the first button and press tab the focus will move to the second button. Along with that the second button is appearing from partly hidden state and pushing the contents of the container div, which is making the UI distorted.
Actually behavior should be button should still be in hidden state and should not push the div. Is there a simple way to handle this other than writing JS to push back the div again.

Categories