Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make a "keydown" event that only works the first time it is pressed?

Below is all of the HTML and the relevant parts of the javascript. The javascript snippet is everything from the top and then I've only showed two "keydown" events otherwise there would be a lot to read through. These two events are labelled "SECTION 1" AND "SECTION 2".

I have several different "keydown" events that add various different HTML content. This web page is designed almost entirely out of javascript simply as a demonstration.

Each time the user presses the relevant key I want the content to be added to the HTML document. Currently the same piece of content can be added an infinite amount of times by simply pressing the same key repeatedly. This is not what I want.

How do I make it so that the event can only be carried out the once?

/* ////////// INTIAL TITLE ////////// */

var initialTitle = document.createElement("h1");
var intialTitleContent = document.createTextNode("Please press the \"1\" key on your keyboard.");
initialTitle.appendChild(intialTitleContent);
document.body.appendChild(initialTitle);

/* ////////// KEYPRESS FUNCTIONS ////////// */

window.addEventListener("keydown", checkKeyPress, false);
function checkKeyPress(key) {
    
// SECTION 1 - Paragraph explaining what this page is about and what to do.
    if (key.keyCode == "49") // "1"
    {
        var pElement = document.createElement("p");
        var content = document.createTextNode("Welcome! This page is made entirely out of javascript. It is completely impractical to create a webpage in this manner. This page is simply a demonstration of how javascript can be used to create and add HTML element and CSS to a HTML document. Meaning within the HTML document the <body> element only contains a link to the javascript code and what the javascript code has added. You can add content by pressing the \"1\" through to \"9\" keys. Each piece of content can then be styled by pressing the \"s\" key.");
        pElement.appendChild(content);
        document.body.appendChild(pElement);
    }
    
// SECTION 2 - TABLE
    else if (key.keyCode == "50") // "2"
    {
        var tableDiv = document.createElement("div");
        var tableElement = document.createElement("table");

        tableDiv.classList.add("div_1");
        
        for (var z = 1; z <= 4; z++) { //Creating "tr" elements.
            var trElement = document.createElement("tr");
            
            tableElement.appendChild(trElement);
            
            for (var i = 1; i <= 4; i++) { //Creating "td" elements within the "tr" elements.
                var tdElement = document.createElement("td");

                tdElement.classList.add("tableCell");
                trElement.appendChild(tdElement);
            }
        }
        
        tableDiv.appendChild(tableElement);
        document.body.appendChild(tableDiv); 
        
        /* Table styling below this point */
        
        var tableCellStyling = document.getElementsByClassName("tableCell");
        
        for (var y = 0; y < tableCellStyling.length; y++) {
            tableCellStyling[y].style.width = "80px";
            tableCellStyling[y].style.height = "80px";
            tableCellStyling[y].style.border = "2px solid #303030";
        }
    }
<!doctype html>
<html lang="en-gb">
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, intial-scale= 1.0"/>
    <title>Javascript Only Site</title>
</head>
<body>

    <script src="js/JOS.js"></script>
</body>
</html>
like image 657
srWebDev Avatar asked Dec 14 '22 14:12

srWebDev


2 Answers

If you want an event to be only ever fired once, you would removeEventListener inside the callback for the event. You will need a variable which contains a reference to the handler to do this, so it would look like:

var eventHandler = function(event){
  //do things
  document.removeEventListener('keypress', eventHandler);
}

document.addEventListener('keypress', eventHandler);

But looking at your snippet, if you wanted to only fire each keycode behavior once, you could create a map which tracks which keys have been previously been pressed and then short return.

var pressedKeys = {};

/* ////////// INTIAL TITLE ////////// */

var initialTitle = document.createElement("h1");
var intialTitleContent = document.createTextNode("Please press the \"1\" key on your keyboard.");
initialTitle.appendChild(intialTitleContent);
document.body.appendChild(initialTitle);

/* ////////// KEYPRESS FUNCTIONS ////////// */

window.addEventListener("keydown", checkKeyPress, false);
function checkKeyPress(key) {



    /** ADDED CODE **/
    if(pressedKeys[key.keyCode] !== undefined){//return if we've seen this key before
      return;
    }
    pressedKeys[key.keyCode] = 1;//just assign a value
    /** END ADDED CODE **/
    
    
    
    
// SECTION 1 - Paragraph explaining what this page is about and what to do.
    if (key.keyCode == "49") // "1"
    {
        var pElement = document.createElement("p");
        var content = document.createTextNode("Welcome! This page is made entirely out of javascript. It is completely impractical to create a webpage in this manner. This page is simply a demonstration of how javascript can be used to create and add HTML element and CSS to a HTML document. Meaning within the HTML document the <body> element only contains a link to the javascript code and what the javascript code has added. You can add content by pressing the \"1\" through to \"9\" keys. Each piece of content can then be styled by pressing the \"s\" key.");
        pElement.appendChild(content);
        document.body.appendChild(pElement);
    }
    
// SECTION 2 - TABLE
    else if (key.keyCode == "50") // "2"
    {
        var tableDiv = document.createElement("div");
        var tableElement = document.createElement("table");

        tableDiv.classList.add("div_1");
        
        for (var z = 1; z <= 4; z++) { //Creating "tr" elements.
            var trElement = document.createElement("tr");
            
            tableElement.appendChild(trElement);
            
            for (var i = 1; i <= 4; i++) { //Creating "td" elements within the "tr" elements.
                var tdElement = document.createElement("td");

                tdElement.classList.add("tableCell");
                trElement.appendChild(tdElement);
            }
        }
        
        tableDiv.appendChild(tableElement);
        document.body.appendChild(tableDiv); 
        
        /* Table styling below this point */
        
        var tableCellStyling = document.getElementsByClassName("tableCell");
        
        for (var y = 0; y < tableCellStyling.length; y++) {
            tableCellStyling[y].style.width = "80px";
            tableCellStyling[y].style.height = "80px";
            tableCellStyling[y].style.border = "2px solid #303030";
        }
    }
like image 115
dgeare Avatar answered Dec 16 '22 03:12

dgeare


Declare a boolean at the top of your script:

let keyDownAllowed = true;

Then inside your keydown event:

if(keyDownAllowed){
   //Set keyDownAllowed to false;
   keyDownAllowed = false;
   //Add to your HTML
}else{
   //Just return or do anything else which you want to do on every key down
   return;
}
like image 36
Ryan Wilson Avatar answered Dec 16 '22 03:12

Ryan Wilson