How to delay a submit event until another event is completed in JS? - javascript

I'm making a chrome extension that creates and pops up an overlay once a specific button is clicked. Clicking the button on the current page takes it to another one. I'd like to pop an overlay once the button is clicked, and only take it to the next page once the overlay is closed. This is my first project using JS so I'm a bit lost.
This is how I create the overlay
//injecting css
var link = document.createElement("link");
link.href = chrome.extension.getURL("css/overlay.css");
link.type = "text/css";
link.rel = "stylesheet";
document.head.appendChild(link);
//setting button's ID for easy referencing
var button = document.getElementsByName("proceedToCheckout")[0].setAttribute("id", "proceedToCheckout");
var overlay = document.createElement("DIV");
overlay.setAttribute("id", "overlay");
document.body.appendChild(overlay);
var url = chrome.extension.getURL("terry.jpg");
var img = document.createElement("IMG");
img.setAttribute("id", "terryImage");
img.setAttribute("src", url);
overlay.appendChild(img);
and this is how I go about the main click function
document.getElementById("proceedToCheckout").addEventListener("click", function()
{
alert("Do you really need that?");
document.getElementById("overlay").style.display = "block";
event.preventDefault();
//disable overlay once clicked
document.getElementById("overlay").addEventListener("click", function (){
document.getElementById("overlay").style.display = "none";
})
})
Since I'm using event.preventDefault(), it does not let me continue the event. Is there any other way I can go about this? Thanks.

Related

Javascript not calling second function

I'm trying to make a main menu for a game. The first frame contains buttons "Start game" and "Quit". The second frame contains buttons "Start", "Back" and a clickable icon for turning the in-game music on or off.
In my onload function I'm adding event listeners to both the "start game" button and the clickable icon. However, it seems, that it only registers the first event listener as when I changed the order the "start game" button stopped working too. What am I doing wrong and am I missing something about handling input with DOM?
window.onload = function (){
document.getElementById("button_play").addEventListener("click", showInstructionPage);
document.getElementById("Link_sound").addEventListener("click", setSound);
}
function setSound(){
if(sound == 1){
document.getElementById("Icon_sound").setAttribute("src", "../media/vypnuty_zvuk.png");
sound = 0;
}
else{
document.getElementById("Icon_sound").setAttribute("src", "../media/zapnuty_zvuk.png");
sound = 1;
}
}
function showInstructionPage(){
//this part is long but works
document.getElementById("button_play").innerHTML = "Start";
document.getElementById("button_play").style.left = "350px";
var quit = document.getElementById("button_quit");
var back = document.createElement("a");
var id = document.createAttribute("id");
id.value = "button_back";
back.setAttributeNode(id);
var link = document.createAttribute("href");
link.value = "#";
back.setAttributeNode(link);
text = document.createTextNode("Back");
back.appendChild(text);
document.getElementById("menu").replaceChild(back, quit);
document.getElementById("button_back").style.left = "346px";
//add instructions and sound icon
var header = document.createElement("h1");
text = document.createTextNode("Instructions");
header.appendChild(text);
document.getElementById("menu").appendChild(header);
var id = document.createAttribute("id");
id.value = "Header_instructions";
header.setAttributeNode(id);
var goal = document.createElement("p");
text = document.createTextNode("Your goal is to get as many frogs to the other side of the river without losing all your lives. To do this, you need to avoid the traffic and alligators.");
goal.appendChild(text);
document.getElementById("menu").appendChild(goal);
var id = document.createAttribute("id");
id.value = "Paragraph_goal";
goal.setAttributeNode(id);
var instructions = document.createElement("p");
text = document.createTextNode("Move in any direction using the arrow keys");
instructions.appendChild(text);
document.getElementById("menu").appendChild(instructions);
var id = document.createAttribute("id");
id.value = "Paragraph_instructions";
instructions.setAttributeNode(id);
var soundLink = document.createElement("a");
var link = document.createAttribute("href");
link.value = "#";
soundLink.setAttributeNode(link)
var id = document.createAttribute("id");
id.value = "Link_sound";
soundLink.setAttributeNode(id);
var soundImage = document.createElement("img");
var id = document.createAttribute("id");
id.value = "Icon_sound";
soundImage.setAttributeNode(id);
var source = document.createAttribute("src");
source.value = "../media/zapnuty_zvuk.png";
soundImage.setAttributeNode(source);
soundLink.appendChild(soundImage);
document.getElementById("menu").appendChild(soundLink);
}
<html>
<head>
<meta charset="UTF-8">
<title>FROGGER</title>
<link rel="stylesheet" href="../css/styles.css" type="text/css">
<script type="text/javascript" src="../js/main.js"></script>
</head>
<body>
<div id="wrapper">
<div id="menu">
<img id="game_title" src="../media/title.png">
Start game
Quit
</div>
<canvas id="canvas" width="800" height="800"></canvas>
<img src="../media/menu_background.jpg" hidden="true" id="menuBackground">
</div>
</body>
</html>
The issue was, that when I called
document.getElementById("Link_sound").addEventListener("click", setSound);
inside the .onload function it couldn't assign the event listener because at the time of loading the page the clickable image doesn't exit yet, as it is only created using DOM after clicking a button. I solved it by moving the code snipped above to the bottom of the showInstructionPage() function after creating the image element.

Download a text file from textarea on Button Click

I am using Jquery UI Dialog. Within the dialog there is textarea that have some text. And I need to save that text as textfile like data.txt when I click the button in the dialog.
<div id = 'metaDataDialog' title='Meta Data' >
<textarea id = 'metaText'>
Some Text
</textarea>
</div>
and this is the jquery ui dialog
$("#metaDataDialog").dialog({ //Jquery UI Dialog Intialization
autoOpen: false,
modal: true,
width: 400,
height: 300,
buttons: {
Save: function() {},
Cancel: function() { $(this).dialog( "close" ); }
},
});
and I need to save/download the text in the local machine, when the save button is clicked
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script>
$(document).ready(function () {
function saveTextAsFile() {
// grab the content of the form field and place it into a variable
var textToWrite = document.getElementById("content").value;
// create a new Blob (html5 magic) that conatins the data from your form feild
var textFileAsBlob = new Blob([textToWrite], { type: 'text/plain' });
// Specify the name of the file to be saved
var fileNameToSaveAs = "myNewFile.txt";
// Optionally allow the user to choose a file name by providing
// an imput field in the HTML and using the collected data here
// var fileNameToSaveAs = txtFileName.text;
// create a link for our script to 'click'
var downloadLink = document.createElement("a");
// supply the name of the file (from the var above).
// you could create the name here but using a var
// allows more flexability later.
downloadLink.download = fileNameToSaveAs;
// provide text for the link. This will be hidden so you
// can actually use anything you want.
downloadLink.innerHTML = "My Hidden Link";
// allow our code to work in webkit & Gecko based browsers
// without the need for a if / else block.
window.URL = window.URL || window.webkitURL;
// Create the link Object.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
// when link is clicked call a function to remove it from
// the DOM in case user wants to save a second file.
downloadLink.onclick = destroyClickedElement;
// make sure the link is hidden.
downloadLink.style.display = "none";
// add the link to the DOM
document.body.appendChild(downloadLink);
// click the new link
downloadLink.click();
}
function destroyClickedElement(event) {
// remove the link from the DOM
document.body.removeChild(event.target);
}
$("#download").click(function (e) {
e.preventDefault();
saveTextAsFile();
});
});
</script>
</head>
<body>
<input type="button" id="download" value="Download" />
<textarea id="content">In trying to keep this plugin as simple as possible, all four states are always assumed to be present. You should prepare your button image as a single image the width you want your button, and four times the height of the button. All four states should then live in that one image in the same order as the previous list from top to bottom.</textarea>
</body>
</html>

Having issue in javascript code. light box does not open second time

I have a code which opens lightbox when user click a link. What it does it opens lightbox, then when user clicks on overlay it closes or hides overlay and lightbox. But when user click on link again to open lightbox again then it does not open. Here is my code
var el = document.getElementById('element');
var body = document.getElementsByTagName('body');
el.innerHTML = '<p><a id="clickme" href="#">Click me</a></p>';
document.getElementById('clickme').onclick = function (e) {
e.preventDefault();
if (overlay) {
overlay.style.display = 'block';
} else {
document.body.innerHTML = '<div id="overlay" style="display:block;position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000;"></div>'+document.body.innerHTML;
}
document.body.innerHTML = '<iframe id="frame" style="position:absolute;display:block;z-index:101;width:50%;height:50%;margin:10% 20%;border:10px solid #ccc;border-radius:10px;" src="http://www.example.com/"></iframe>'+document.body.innerHTML;
document.getElementById('overlay').onclick = function() {
document.getElementById('overlay').style.display = 'none';
document.getElementById('frame').style.display = 'none';
}
}
How can I open this lightbox again when user clicks link second time?
You set style to display:none on close but clicking the link doesn't change the display property. Effect: the box stays invisible.
Simple solution: add display:block or whatever you need there to the opening function.
In addition: your opening function will create a new element each time it is executed. You could add a test to prevent that:
var overlay = document.getElementById('overlay');
if(overlay){
overlay.style.display = 'block';
} else {
//create box
}
The problem is that as soon as you edit the DOM by adding or replacing document.body.innerHTML, the event on your element (your a href) will no longer exist. you would need to append the event again after you performed document.body.innerHTML.

Javascript - Function works once, but never again

I'm building a very simple lightbox script; when you click a button, the lightbox is created. When you click on the lightbox background, it is removed.
The first time you call the function it works just fine. Click button, lightbox shows, click lightbox, it disappears. However, if you try to click the button AGAIN, nothing happens - the div isn't called. No console errors or anything, don't know what the problem is.
JSFIDDLE http://jsfiddle.net/3fgTC/
CODE
function closeLightBox(){
document.body.removeChild(lightBox);
}
function createElem(){
var elem = "<div id='lightBox'></div>";
var bodyElem = document.body;
bodyElem.innerHTML = elem + bodyElem.innerHTML;
var lightBox = document.getElementById("lightBox");
lightBox.style.width = "100%";
lightBox.style.height = "800px";
lightBox.style.backgroundColor = "rgba(0,0,0,.5)";
lightBox.onclick = function(){
closeLightBox();
}
}
var button = document.getElementsByClassName("btn");
for (var i = 0; i<button.length; i++){
button[i].onclick = function(){
createElem();
}
}
Any ideas?
Don't prepend to innerHTML; that makes the browser re-parse the HTML and re-create every DOM element, losing event handlers in the process. Instead, use document.createElement:
var lightBox = document.createElement('div');
document.body.insertBefore(lightBox, document.body.firstChild);
Furthermore, inline closeLightBox:
lightBox.onclick = function() {
document.body.removeChild(lightBox);
}
Try it.

Execute jQuery after changing DOM

This piece of code adds images to the DOM after dragging them into a div-element.
var showImage = function (ev) {
var file = ev.target.file;
var thumb = new Image(100,100);
thumb.src = ev.target.result;
thumb.className = 'thumbFoto';
thumb.title = file.name;
thumb.alt = file.name;
var anchor = document.createElement('a');
anchor.className = 'thumbLink';
anchor.href = ev.target.result;
anchor.rel = 'album1';
anchor.title = file.name;
anchor.appendChild(thumb);
dropZone.appendChild(anchor);
}
This code is linked to the page using
<script type="text/javascript" src="js/code.js"></script>
After the images are added to the webpage, I would like preview them using Fancybox.
When the page is loaded (before I dragged any image onto it), this script is executed in the html-header:
<script type="text/javascript">
$(document).ready(function() {
/* Apply fancybox to albums */
$("a.thumbLink").fancybox();
});
</script>
Now how do I make sure I can preview the recently added images using Fancybox?
I assume you use jQuery UI draggable object, you can call your fancybox on stop() event of your draggable object, like this:
$( ".selector" ).draggable({
stop: function( event, ui ) {
$("a.thumbLink").fancybox();
}
});
EDIT:
Based on your code you can simply put your fancybox caller in function of showFileInList, like this:
var showFileInList = function (ev) {
var file = ev.target.file;
if(document.getElementById("fileDropText")){
var textToBeRemoved = document.getElementById("fileDropText");
var imageToBeRemoved = document.getElementById("fileDropImg");
textToBeRemoved.parentElement.removeChild(textToBeRemoved);
imageToBeRemoved.parentElement.removeChild(imageToBeRemoved);
}
var thumb = new Image(100,100);
thumb.src = ev.target.result;
// var thumb = createThumb(ev.target.result);
thumb.className = 'thumbFoto';
thumb.title = file.name;
thumb.alt = file.name;
var anchor = document.createElement('a');
anchor.className = 'thumbLink';
anchor.href = ev.target.result;
anchor.rel = 'album1';
anchor.title = file.name;
// anchor.addEventListener("click", showImagePreview, false);
anchor.appendChild(thumb);
// fileList.insertBefore(anchor, dropZone);
dropZone.appendChild(anchor);
// show fancybox
$("a.thumbLink").fancybox({type: "inline", href: "#fileDrop"});
}
See working code HERE
Try routing all of your DOM changes through a single object using the "Chain of Responsibility" pattern. That way the object can keep track of any changes to the dom. Then I would use ConversationJS to fire a function that does whatever you want on DOM change: https://github.com/rhyneandrew/Conversation.JS

Categories