简体   繁体   中英

Dynamically generating an entire page in a Javascript bookmarklet

I am generating this page inside a bookmarklet. (For reasons...)

I am getting this error:

Uncaught TypeError: Cannot read property 'value' of null on line 10

( var inputValue = document.getElementById('input').value; ) < line 10

At the moment I am simply copy and pasting all the code into the DOM to simulate the bookmarklet.

I would prefer to use pure Javascript and no Jquery.

This is my code:

javascript:(function(){
    function genRan(){
            /*
            Generate a random value of length determined by box 'input'
            Please note that this cannot be used for any type of cryptography however it 
            is fine for password generation. Do not use for public key crypto!
            */

            /* Get the value from input field */
            var inputValue = document.getElementById('input').value;
            inputValue = parseInt(inputValue);

            var outputValue = '';
            var possibleValues = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

            /* Generate the random string */
            for(var x=0; x<inputValue; x++){
                var randomInt = Math.floor((Math.random() * possibleValues.length) + 1);
                console.log(randomInt);
                outputValue += possibleValues.charAt(randomInt);
            }

            document.getElementById('output').value = outputValue;
    }

    function decreaseCounter(){
        var inputValue = document.getElementById('input').value;
        inputValue = parseInt(inputValue);
        inputValue--;
        document.getElementById('input').value = inputValue;
        genRan();
    }

    function increaseCounter(){
        var inputValue = document.getElementById('input').value;
        inputValue = parseInt(inputValue);
        inputValue++;
        document.getElementById('input').value = inputValue;
        genRan();
    }

    /* EDIT 2: Make a document with body */
    document.open();
    document.write('<html><head></head><body>Test</body></html>');
    /* document.close(); /* Not sure if this is needed right now */


    var mainDiv = document.createElement('div');
    mainDiv.id = 'mainDiv';
    var innerDiv = document.createElement('div');
    innerDiv.id = 'innerDiv';

    /* EDIT: based on Dan's comment, I have added the following */
    mainDiv.appendChild(innerDiv);
    document.body.appendChild(mainDiv);
    /* End of edit */

    var generateButton = document.createElement("button");
    var generateButtonText = document.createTextNode("Generate Random String");
    generateButton.appendChild(generateButtonText);
    generateButton.onclick = genRan();
    innerDiv.appendChild(generateButton);

    var minusButton = document.createElement("button");
    minusButtonText = document.createTextNode("-");
    minusButton.appendChild(minusButtonText);
    minusButton.onclick = decreaseCounter();
    innerDiv.appendChild(minusButton);

    var plusButton = document.createElement("button");
    plusButtonText = document.createTextNode("+");
    plusButton.appendChild(plusButtonText);
    plusButton.onclick = increaseCounter();
    innerDiv.appendChild(plusButton);

    var textInput = document.createElement("input");
    textInput.setAttribute("id", "input");
    textInput.setAttribute("type", "text");
    textInput.setAttribute("value", "10");
    innerDiv.appendChild(textInput);

    var textOutput = document.createElement("input");
    textOutput.setAttribute("id", "output");
    textOutput.setAttribute("type", "text");
    innerDiv.appendChild(textOutput);

    genRan();/* Begin the program now */
})();

Edits:

Edit 1: Append the div with inputs to the inner and main div

Edit 2: Create document and body, then append to body

Your problem is in how you are setting the onclick handlers. See these lines:

generateButton.onclick = genRan();
...
minusButton.onclick = decreaseCounter();
...
plusButton.onclick = increaseCounter();

Here you are actually calling the functions, and setting their return values to the onclick property, rather than setting the function as the callback. This is causing the functions to run before you create the elements, thus causing your error.

Replace those line with these, and your code works.

generateButton.onclick = genRan;
...
minusButton.onclick = decreaseCounter;
...
plusButton.onclick = increaseCounter;

Corrected Code:

javascript:(function(){
    function genRan(){
            /*
            Generate a random value of length determined by box 'input'
            Please note that this cannot be used for any type of cryptography however it 
            is fine for password generation. Do not use for public key crypto!
            */

            /* Get the value from input field */
            var inputValue = document.getElementById('input').value;
            inputValue = parseInt(inputValue);

            var outputValue = '';
            var possibleValues = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

            /* Generate the random string */
            for(var x=0; x<inputValue; x++){
                var randomInt = Math.floor((Math.random() * possibleValues.length) + 1);
                console.log(randomInt);
                outputValue += possibleValues.charAt(randomInt);
            }

            document.getElementById('output').value = outputValue;
    }

    function decreaseCounter(){
        var inputValue = document.getElementById('input').value;
        inputValue = parseInt(inputValue);
        inputValue--;
        document.getElementById('input').value = inputValue;
        genRan();
    }

    function increaseCounter(){
        var inputValue = document.getElementById('input').value;
        inputValue = parseInt(inputValue);
        inputValue++;
        document.getElementById('input').value = inputValue;
        genRan();
    }

    /* EDIT 2: Make a document with body */
    document.open();
    document.write('<html><head></head><body>Test</body></html>');
    /* document.close(); /* Not sure if this is needed right now */


    var mainDiv = document.createElement('div');
    mainDiv.id = 'mainDiv';
    var innerDiv = document.createElement('div');
    innerDiv.id = 'innerDiv';

    /* EDIT: based on Dan's comment, I have added the following */
    mainDiv.appendChild(innerDiv);
    document.body.appendChild(mainDiv);
    /* End of edit */

    var generateButton = document.createElement("button");
    var generateButtonText = document.createTextNode("Generate Random String");
    generateButton.appendChild(generateButtonText);
    generateButton.onclick = genRan;
    innerDiv.appendChild(generateButton);

    var minusButton = document.createElement("button");
    minusButtonText = document.createTextNode("-");
    minusButton.appendChild(minusButtonText);
    minusButton.onclick = decreaseCounter;
    innerDiv.appendChild(minusButton);

    var plusButton = document.createElement("button");
    plusButtonText = document.createTextNode("+");
    plusButton.appendChild(plusButtonText);
    plusButton.onclick = increaseCounter;
    innerDiv.appendChild(plusButton);

    var textInput = document.createElement("input");
    textInput.setAttribute("id", "input");
    textInput.setAttribute("type", "text");
    textInput.setAttribute("value", "10");
    innerDiv.appendChild(textInput);

    var textOutput = document.createElement("input");
    textOutput.setAttribute("id", "output");
    textOutput.setAttribute("type", "text");
    innerDiv.appendChild(textOutput);

    genRan();/* Begin the program now */
})();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM