Search code examples
javascripthtmldomjquery-eventsbookmarklet

How can I use a bookmarklet to temporarily disable an event handler in my website?


I made a simple button clicker website in which every time you click the button, it adds to a counter. here is the url:

https://joeceb.w3spaces.com/button-clicker.html

the code was pretty basic and it looked something like this

/* original code */

let clicks = 0
                
function Click() {
  document.getElementById("btn").innerHTML = `${clicks += 1} clicks`
  if (clicks >= 100) {          // achievement at 100 clicks
      document.getElementById("btn").innerHTML = `${clicks} &#x2605 clicks`
  }
}


/* generates button */

function addButton() {
    document.body.style.textAlign = "center";
    var btn = document.createElement("BUTTON");
    btn.innerHTML = `0 clicks`;
    var att = document.createAttribute("id");
    att.value = "btn";                           
    btn.setAttributeNode(att);
    btn.style.padding = "12pt";
    btn.addEventListener("click", Click);
    document.body.appendChild(btn);
}
addButton()
   

once you reach 100 clicks you'll get a star ★ beside your number. in the original, it would have been unlocked once you had reached 10 000 ★ clicks

the problem was if you clicked the button once and then held down the enter key, it would rapidly and continuously increase, so I used jquery to prevent this from happening.

heres the changed script with enter disabled:

/* i stole this answer from another question */
function loadJQuery() {                   // i'm using jquery ver 3.6 btw
import('https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js').then(()=>{
$(document).keydown( function(event) {
    if (event.which == 13) {
        event.preventDefault();
    }
});
})
}
loadJQuery();



/* original code */

    let clicks = 0
                    
    function Click() {
      document.getElementById("btn").innerHTML = `${clicks += 1} clicks`
      if (clicks >= 100) {          // achievement at 100 clicks
          document.getElementById("btn").innerHTML = `${clicks} &#x2605 clicks`
      }
    }

    
    /* generates button */

    function addButton() {
        document.body.style.textAlign = "center";
        var btn = document.createElement("BUTTON");
        btn.innerHTML = `0 clicks`;
        var att = document.createAttribute("id");
        att.value = "btn";                           
        btn.setAttributeNode(att);
        btn.style.padding = "12pt";
        btn.addEventListener("click", Click);
        document.body.appendChild(btn);
    }addButton();

now it's a little bit harder to reach 100 clicks.

but my question is how could you use an external script like a bookmarklet to bypass it incase i need to test something.

i disabled the enter key for a reason. but if i have to re-enable it, I dont want to edit the scource every time and yould rather have something that i could click to temporarily deactivate it. also i cant use any server-side scripts or the debug console as its disabled by the administrator.

you may need to use the websites original source so here it is

<script src="/content/jquery-3.6.0.min.js"></script>
<script>
$(document).keypress( function(event){
  if (event.which == '13') {
    event.preventDefault();
  }
});
</script>

Edit: i used to be able to do this (() => {my-variable = 9999; myFunction();})(); until i fixed it by moving all the code in the same script element and inside braces{} changing the variable scope


Solution

  • To prevent enter exploits, all you need to do is prevent keydown events from being dispatched to the button - and you don't need a huge library like jQuery for something that trivial:

    document.addEventListener('keydown', (e) => {
      if (e.target.matches('#btn') && e.key === 'Enter') e.preventDefault();
    });
    

    document.addEventListener('keydown', (e) => {
      if (e.target.matches('#btn') && e.key === 'Enter') e.preventDefault();
    });
    
    /* original code */
    
    let clicks = 0
    
    function Click() {
      document.getElementById("btn").innerHTML = `${clicks += 1} clicks`
      if (clicks >= 100) { // achievement at 100 clicks
        document.getElementById("btn").innerHTML = `${clicks} &#x2605 clicks`
      }
    }
    
    /* generates button */
    
    function addButton() {
      document.body.style.textAlign = "center";
      var btn = document.createElement("BUTTON");
      btn.innerHTML = `0 clicks`;
      var att = document.createAttribute("id");
      att.value = "btn";
      btn.setAttributeNode(att);
      btn.style.padding = "12pt";
      btn.addEventListener("click", Click);
      document.body.appendChild(btn);
    }
    addButton()

    Using e.target.matches checks if the enter is going to the #btn - if it is, then the key press won't do anything. If the enter is going to anything else (like a <textarea>), it won't be interfered with.

    Still, if you wanted to bypass the prevention of enter with a script, all you need to do is .click() on the button.

    for (let i = 0; i < 100; i++) {
      document.querySelector('#btn').click();
    }
    

    document.addEventListener('keydown', (e) => {
      if (e.target.matches('#btn')) e.preventDefault();
    });
    
    /* original code */
    
    let clicks = 0
    
    function Click() {
      document.getElementById("btn").innerHTML = `${clicks += 1} clicks`
      if (clicks >= 100) { // acheivement at 100 clicks
        document.getElementById("btn").innerHTML = `${clicks} &#x2605 clicks`
      }
    }
    
    
    /* generates button */
    
    function addButton() {
      document.body.style.textAlign = "center";
      var btn = document.createElement("BUTTON");
      btn.innerHTML = `0 clicks`;
      var att = document.createAttribute("id");
      att.value = "btn";
      btn.setAttributeNode(att);
      btn.style.padding = "12pt";
      btn.addEventListener("click", Click);
      document.body.appendChild(btn);
    }
    addButton()
    
    // userscript or bookmarklet code:
    for (let i = 0; i < 100; i++) {
      document.querySelector('#btn').click();
    }