One quirk of Google's Blogger platform is that when you preview
posts it sets up an invisible HTML element overlaying the page that keeps
click events from being delivered.
For example, in preview mode, this link
can't be clicked on. In the preview page source code, Google names this element
appropriately: blogger-clickTrap. Click trap, indeed.
If you right-mouse click on the preview page and select 'Inspect'
you can see the details of this overlay:
Removing the click trap using the inspector panel is
straightforward.
Add display: none to the blogger-clickTrap
element's style and clicks work again.
For years I've either ignored the click trap, or when necessary,
manually removed it.
Yesterday, however, I wrote a post that made heavy use of click
events. While composing the post I found I needed to frequently
refresh the page and then take a few moments to manually remove the
overlay. After the 100th time of doing this, I stopped what I was
doing and took a moment to consider: could I automatically disable
the blogger-clickTrap element?
Tampermonkey to the Rescue
With a few minutes of consideration, I realized that Tampermonkey
should be able to save the day. Tampermonkey allows custom code to
be injected on the page of your choice. All I needed was to write a
few lines of code that would set
display: none on the right element when the page loaded,
and the click trap would be a distant memory.
I created a new Tampermonkey script to get started:
// ==UserScript==
// @name Bye-bye clicktrap!
// @namespace http://blogbyben.com/
// @version 0.1
// @description Remove blogger preview's clicktrap
// @author Ben Simon
// @match https://draft.blogger.com/blog/post/edit/preview/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=blogger.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
console.log("Is this thing on?");
})();
I loaded up the preview page and success!
I then updated the code to show that it could find the offending
element:
// ==UserScript==
// @name Bye-bye clicktrap!
// @namespace http://blogbyben.com/
// @version 0.1
// @description Remove blogger preview's clicktrap
// @author Ben Simon
// @match https://draft.blogger.com/blog/post/edit/preview/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=blogger.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
var found = document.querySelector('.blogger-clickTrap');
console.log("Found it!", found);
})();
And that's where I hit a problem: no matter how or when I queried
the document, my Tampermonkey script couldn't find the click trap
element. In the inspector, I could see it was there, and yet, I
couldn't programatically access it.
After much debugging I realized that the preview page is a
generic shell and imports a specific post by using an
iframe pointed to
https://<something>.blogspot.com/b/blog-preview?token=.
my attempts to access the iframe's contents via the main
page were being denied, apparently because they weren't from the
same origin.
My first thought was: I'm already mucking with these requests,
perhaps I can turn off this security policy that's blocking me?
However in my search to figure out how to do this, I realized
there's a much simpler solution. I needed to be running my
Tampermonkey script not on the preview page, but on
*.blogspot.com/b/blog-preview*.
When I updated the @match rule on the script above, my code
began to work:
Once I was running the Tampermonkey code on the right URL, having it
remove the click trap itself was trivial. Here's the final
Tampermonkey script:
// ==UserScript==
// @name Bye-bye clicktrap!
// @namespace http://blogbyben.com/
// @version 0.1
// @description Remove blogger preview's clicktrap
// @author Ben Simonm
// @match https://*.blogspot.com/b/blog-preview*
// @icon https://www.google.com/s2/favicons?sz=64&domain=blogger.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
var found = document.querySelector('.blogger-clickTrap');
found.style.display = 'none';
})();
Happy clicking!