I am using the following javascript code to update my HTML.
document.querySelector(".long-copy").innerHTML = "Once, there was a boy who became bored when he watched over the village sheep <a class=\"word-button\">grazing</a> on the hillside.";
This updates my HTML DOM (this one) dynamically.
<div>
<p class="long-copy"></p>
</div>;
Now, in my code - the word "grazing" is a tag. When someone clicks on this "grazing" button, a modal window should open. BUT this is not working as when I run this javascript code, I get an error "Cannot read property 'addEventListener' of null". Please help.
const btn1OpenModal = document.querySelector(".word-button");
btn1OpenModal.addEventListener("click", openModal);
const openModal = function () {
modal.classList.remove("hidden");
overlay.classList.remove("hidden");
};
CSS added >>
.hidden {
display: none;
}
.word-modal-one {
position: absolute;
top: 56%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
height: 80%;
background-color: white;
padding: 6rem;
border-radius: 10px;
box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.3);
z-index: 10;
overflow: auto;
}
.word-modal-one::-webkit-scrollbar {
display: none;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(1px);
z-index: 5;
}
Instead change your <a> tag HTML to this:
var myHTML = "text text more text <a href='javascript:void(0);' onclick='openModal()'>My a element</a> more text text more text";
function openModal() {
//Open that modal
}
I added the javascript:void(0) because without that, some browsers like to use the <a> tag to redirect, because it does signify a link, and that void stops the link from executing a redirect to the same page and lets you carry on with your JS on the same page
The reason why your addEventListener fails is because the script looks for an element that doesn't exist yet, and so you can bypass that by attaching the event listener yourself onto the element
Related
I know my issue is event propagation related, but I can't manage to figure it out.
The code I attached is a loop on the page with a couple of items.
function popItUp() {
document.querySelector(".popuptext").classList.add("show");
document.querySelector("body").style.overflow = "hidden";
}
function popItDown() {
document.querySelector(".popuptext.show").classList.remove("show");
document.querySelector("body").style.overflow = "visible";
}
function cancelBubble(e) {
var evt = e ? e : window.event;
if (evt.stopPropagation) evt.stopPropagation();
if (evt.cancelBubble != null) evt.cancelBubble = true;
}
// define all popup elements.
let popups = document.querySelectorAll(".popup");
let popuptext = document.querySelector(".popuptext");
// add listener to each popup element, which binds handler function to click event.
popups.forEach((popup) => popup.addEventListener("click", popItUp));
.popup .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 20px;
padding: 8px 0;
z-index: 1;
}
.popup .popuptext.show::before {
content: "";
position: fixed;
top: -10%;
left: 0%;
width: 100%;
height: 200%;
background-color: rgba(0, 0, 0, 0.4);
/* Black w/opacity/see-through */
z-index: -50;
border-color: #555 transparent transparent transparent;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.popup .popuptext::after {
content: "";
position: fixed;
}
.popuptext.show {
visibility: visible;
-webkit-animation: fadeIn 1s;
animation: fadeIn 1s;
position: fixed;
top: 15%;
left: 11%;
justify-content: center;
display: block;
width: 75%;
height: 80%;
overflow-y: auto;
overflow-x: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="popup popup--maxwidth" onclick="popItUp()">
CLICK ME FOR POPUP
<div class="popup--container" onclick="cancelBubble()">
<span class="popuptext">
<span class="popup--close" onclick="popItDown()"><i class="fa fa-close" style="font-size:36px; color:white;">CLOSEBUTTON</i></span>
<div class="partner-container">
Awesome Content
</div>
</div>
</div>
</div>
So this kind of works. Clicking on popItUp() opens up the popup, clicking on popItUp() closes it up.
Issue 1: ISSUE FIXED
However, it is quite unseemly, as every time I open it up, I get an error of:
Popup.js?ver=1.0:4 Uncaught TypeError: this.querySelector is not a function
at popItUp (Popup.js?ver=1.0:4)
at HTMLDivElement.onclick (hu:663)
Issue 2:
It is a clients request, that if we click outside of the popups container (so the target of the click in this case would be .popup--maxwidth, as it covers the whole body), then the popup should close up as well. Now the problem is, that if I take out cancelBubble(e) this sort of works, but it also closes up the popup if i click anywhere inside the popup, which is not really helpful. :)
If someone can help me out it would be greatly appreciated.
Issue 1: ISSUE FIXED -- was a typo in popItUp(), used this.querySelector instead of document. Code updated.
Background
I have an HTML div which contains a ‘tooltip’-like feature (i.e., a text box pops up when a certain element is clicked or hovered over); this tooltip has decorative pseudo-elements to make it look like a ‘speech bubble,’ added in css as :before and :after .
I have a JS script, which is intended to show and hide the tooltip and decoration, in response to click events (i.e., toggle them between ‘show’ and ‘hide’ states).
Problem
I can’t get the decorative pseudo-elements to hide when the tooltip is hidden; as pseudo-elements, they are not part of the DOM and so I can’t use normal selectors to manipulate them.
When the tooltip is hidden on click, the decorative pseudo-elements persist, which is not a usable result.
I can’t do away with the decorative elements, they are part of the work specification.
Approach tried so far
Based on this question, my thought was to add an empty span with its own class, to which I’d prepend and append these pseudo-elements. Then, add or remove the class on click based on whether it exists already, or not.
I have also tried setting the class to which the pseudo-elements are pre/appended to display:none on click, but this also seems not to work
However, I cannot convince the pseudo-elements to hide on click.
I’ve included a screenshot of what these remnant pseudo-elements look like in the live environment.
Note: I tried to work up a running simulation for the purpose of this question, but I wasn’t able to and the original css file is massive; the code included below is for reference only.
All guidance is much appreciated!
const barContainer = document.querySelector(".bar-container");
const decorationElement = document.querySelector("#decoration");
document.addEventListener('click', function(event) {
console.log('click event listener triggered');
if (event.target.closest('.link') || event.target.classList.contains('link')) {
if (barContainer.classList.contains('open')) {
barContainer.classList.remove('open')
decorationElement.classList.remove('decoration')
document.querySelector('.tooltip-container').setAttribute('style', 'display:none');
} else {
barContainer.classList.add('open')
decorationElement.classList.add('decoration')
document.querySelector('.tooltip-container').setAttribute('style', 'display:block');
}
} else {
barContainer.classList.remove('open')
decorationElement.classList.remove('decoration')
document.querySelector('.tooltip-container').setAttribute('style', 'display:none');
}
});
.foo-container {
height: auto;
position: relative;
}
.bar-container {
height: auto;
position: relative;
text-align: center;
}
.bar-container:hover .tooltip-container,
.tooltip-container:hover,
.bar-container.open .tooltip-container {
position: absolute;
display: block;
text-align: left;
background-color: #ffffff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
bottom: 50px;
right: 5%;
border-radius: 4%;
font-weight: 300;
max-width: 90%;
font-size: 14px;
padding: 20px 0;
}
/*the below two rule sets create the rotated 'decoration' */
.bar-container:hover .tooltip-container:before,
.tooltip-container:hover:before,
.bar-container.open .tooltip-container:before,
.foo-container .bar-container:hover .decoration:before {
content: "";
width: 65px;
height: 35px;
position: absolute;
overflow: hidden;
transform: rotate(-180deg);
z-index: 10;
bottom: 0;
left: 170px;
background-color: white;
}
.foo-container .bar-container.open .decoration:before,
.foo-container .bar-container:hover .decoration:before {
content: "";
position: absolute;
width: 30px;
height: 30px;
background: #fff;
transform: rotate(45deg);
left: 30px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
z-index: 2;
top: -42px;
}
/* end 'deocration' */
<div class="foo-container">
<div class="bar-container">
<p>text <span class='link'>the-link<span id='decoration' class='decoration'></span></span>
</p>
<div class='tooltip-container'>
<p>lorem </p>
</div>
</div>
</div>
Screenshot of the undesirable 'persistent pseudo-elements' behavior -->
I am using the Kube framework (http://imperavi.com/kube/) which includes a modal function. Unfortunately the documentation is kind of sparse or I am too dumb (http://imperavi.com/kube/tools/js-modal/).
They have sample code showing how to launch modals on button clicks, but I am trying to launch it on body load. Can anyone with either experience with Kube or a better understanding of JS/JQuery help me do that? I wan to make sure I can specify settings like width and blur.
I know there are many many modal plugins out there, but I am trying to limit my project to just this one framework.
This will run on window ready. http://jsfiddle.net/418hmnjy/2/. This uses no libraries Just HTML, CSS and JavaScript.
HTML
<div id="modal">
<div class="modalconent">
<h1></h1>
<p>fasfsdfasfsfsdfsdfsdsffsd</p>
<button id="button">Close</button>
</div>
</div>
JavaScript
window.onload = function () {
document.getElementById('button').onclick = function () {
document.getElementById('modal').style.display = "none"
};
};
CSS
#modal {
position: fixed;
font-family: Arial, Helvetica, sans-serif;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
z-index: 99999;
height: 100%;
width: 100%;
}
.modalconent {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #fff;
width: 80%;
padding: 20px;
}
Sorry if this is a silly question (I am still new to web development), but is it possible to have a link in a basic confirmation dialog message?
Right now, I have a basic confirmation popup
if (confirm("Bunch of text here"))
...
But a customer wants me to add a link in that confirmation box which would open in a new window. Adding html tags in the message doesn't work since it's a message string.
Any suggestions would be appreciated.
Thanks!
You could make a modal and display it like that, or, even simpler, use bootstrap's built in modal.
HTML:
<div class="button">Click</div>
<div class="overlay">
<div class="modal"></div>
</div>
CSS:
.button {
background-color: #aa0000;
color: #fff;
padding: 5px 40px;
display: inline-block;
cursor: pointer;
}
.overlay {
background-color: rgba(0, 0, 0, 0.8);
position: fixed;
height: 100%;
width: 100%;
display: none;
top: 0;
left: 0;
}
.modal {
left: 50%;
margin-left: -100px;
top: 50%;
margin-top: -100px;
background-color: #fff;
position: fixed;
height: 200px;
width: 200px;
}
JS:
$(function() {
var button = $('.button'),
overlay = $('.overlay'),
message = 'Message text',
modal = $('.modal');
button.on('click', function() {
overlay.css('display', 'block');
modal.html( message + '' + 'link' + '');
});
});
http://jsfiddle.net/HNe95/
That's not possible with the Javascript's confirm function. In order to do that you need a custom modal dialog.
If you use jQuery, you could create one by use one of these: vex, alertify, and apprise to name a few.
If you don't use jQuery, you can create one by applying some CSS and Javascripts for events. You could also follow this guide.
I have a script that is dived as:
HTML:
<div id="wrapper">
<div id="container">
<div id="button">Click me!</div>
<form>
<input type="file" />
</form>
</div>
<div id="notice">File is uploaded!</div>
</div>
JavaScript(JQuery 2):
$(document).ready(function () {
$("input").on("change", function () {
$("div#notice").fadeIn();
//$("form").submit(); //If you want it to submit on your site uncomment this
});
});
CSS:
div#wrapper {
background-color: #ccc;
position: absolute;
width: 300px;
height: 200px;
}
div#wrapper > form > input {
color: rgba(0, 0, 0, 0);
zoom: 1;
filter: alpha(opacity=0);
opacity: 0;
color: rgba(0, 0, 0, 0);
}
div#container {
width: 200px;
height: 20px;
overflow: hidden;
}
div#button, input {
position: absolute;
top: 0px;
left: 0px;
cursor: pointer;
}
div#button {
z-index: 1;
background-color: #AAA;
}
input {
z-index: 2;
background-color: rgba(0, 0, 0, 0);
opacity: 0;
alpha: filter(opacity=0);
font-size: 25px;
color: rgba(0,0,0,0);
filter: alpha(opacity=0);
zoom: 1;
}
div#notice
{
background-color: green;
display: none;
position: absolute;
bottom: 0px;
left: 0px;
}
Note: This issue was there before blur was put to hide the flashing icon in IE.
In Chrome and Firefox the button only requires a single click. In IE 10 it requires a double click, which I don't want. I am trying to think of a way to make it single click.
The only thing I've tried so far is to .render("click") on the input, but that didn't work.
JSFiddle: http://jsfiddle.net/plowdawg/mk77W/
I had the same problem and found different approach. I just made that button be as big as I need with font-size on it. Then person simply can't click on text section.
<div class="divFileUpload">
<input class="fileUpload" type="file" />
</div>
and css:
.divFileUpload {
background-color: #F60;
border-radius: 5px;
height: 50px;
margin-left: auto;
margin-right: auto;
overflow: hidden;
position: relative;
width: 50%
}
.fileUpload {
cursor: pointer;
font-size: 10000px; /* This is the main part. */
height: 100%;
opacity: 0;
position: absolute;
right: 0;
top: 0;
width: 100%
}
To follow up on what SDLion said....
This might be what you see
But really on top of that there is a file upload control that has been made transparent.
Clicking on the browse button brings up the file upload dialog with one click.
In IE You have to double click the text box to the left of it if you want to see the file upload dialog.
Increase the font size of the file input to fill the button image
While #bastos.sergio is right about it happening in the text section there is a way to get around this if you are comfortable using JavaScript.
You will need:
A wrapper div tag
An inner dev tag
Some sort of form input
JQuery (tested on 2.1)
Steps:
Create the "wrapper" div
Create an inner "button " div
Place the form element underneath the inner "button" div
Set the "wrapper" and "inner" divs to the same size
Set overflow:hidden on the wrapper
Create a JQuery script for the "inner" div setting the on click function
In the "inner" function click function call .click() on the input
Seems to work for me in IE 10.
$(document).ready(
function()
{
$("#open_dialog").on("click",function()
{
$("input").click();
});
$("input").on("change",function()
{
alert($("input"));
$("#notice").html("uploading");
});
});
#open_dialog
{
position: relative;
width: 200px;
height: 50px;
color: white;
font-family: "Arial";
font-size: 14pt;
text-align: center;
top: 25px;
margin-top: -.5em;
z-index: 1;
}
#wrapper
{
width: 200px;
height: 50px;
overflow: hidden;
cursor: pointer;
border-radius: 10px;
background: green;
z-index: 0;
}
input
{
margin-top: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="open_dialog">Click Me</div>
<input type="file" />
</div>
<div id="notice">Nothing to upload</div>
The double click is happening on the text portion of the file upload, like #TravisPessetto stated.
Since it's not possible to hide/remove the text portion out of the file input control, I recommend that you put a regular button over the file input.
See here for more details.
I found another more simple solution, just trigger the event "click" on mousedown for this element only:
$("input").mousedown(function() {
$(this).trigger('click');
})
in order to avoid problems on other browsers, apply this solution to IE only:
if ($.browser.msie && parseInt($.browser.version, 10) > 8) {
$("#your_file_input").mousedown(function(event) {
if (event.which == 1) {
$(this).trigger('click');
}
})
}
here's your jfiddle modified, check it on IE 9-10:
http://jsfiddle.net/7Lq3k/
Edit: example modified in order to limit the event handling for left click only
(see: How to distinguish between left and right mouse click with jQuery for details)
I mixed various solutions to get this one that works for me (on every browser). It's written using LESS nesting.
HTML
<!--/* Upload input */-->
<div class="input-file">
Select image
<input type="file" />
</div>
LESS CSS
/*
* Input "file" type Styling
* Based on http://goo.gl/07sCBA
* and http://stackoverflow.com/a/21092148/1252920
*/
.input-file {
position: relative;
overflow: hidden;
margin: 10px;
input[type="file"] {
opacity: 0;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: 0;
padding: 0;
cursor: pointer;
width: 100%;
height: 100%;
font-size: 10000px;
}
// For Chrome
input[type=file]::-webkit-file-upload-button {
cursor: pointer;
}
}