Stopping Google from tracking Search results I've created a brief UserScript (GitHub repository) for TamperMonkey to stop Google from hijacking Search results URLs for tracking purposes when you click them:

// ==UserScript==
// @include     http*://www.google.*/*
// @run-at      document-start
// ==/UserScript==
(function () {
    'use strict';
    function handleNodes(nodes) {
        for (var i = 0, j = nodes.length; i &lt; j; i++) {
            handleNode(nodes[i]);
        }
    }
    function handleNode(node) {
        if (node.tagName === 'A' &amp;&amp; node.onmousedown) {
            node.onmousedown = null;
        }
        handleNodes(node.childNodes);
    }
    document.onclick = null;
    var observer = new MutationObserver(function (mutations, observer) {
        for (var i = 0, j = mutations.length; i &lt; j; i++) {
            var mutation = mutations[i];
            for (var k = 0, l = mutation.addedNodes.length; k &lt; l; k++) {
                handleNode(mutation.addedNodes[k]);
            }
        }
    });
    observer.observe(document, { childList: true, subtree: true });
} ());


The script seems to work for both Google "Classic" and Google Instant doing its job.

Since I'm not a UserScript or DOM guru I'd like some feedback on it. Did I make any mistake or inefficiency? Is there something that can be improved?
to stop Google from hijacking Search results URLs for tracking purposes when you click them


Wrong, there's a lot of ways websites profile you. One other method is your device fingerprint, the combination of hardware, software and network information that normally gets sent to the server. A server can then compute a hash and link it to you.

No matter how you block the click-jacked search results, if you end up on a page that happens to have some widget that reports back to their server (with the same hardware, software and network info), consider yourself tracked. These "widgets" come in a variety of forms, like ads, like buttons, tweet buttons, follow buttons etc.

As for your code...

node.onmousedown = null


You are only removing the inline/property handler. You're not preventing handlers that are assigned via addEventListener and delegated (handlers assigned to ancestors to listen to a descendant).



function foo(message){
  alert('No stopping ' + message);
}

var link = document.querySelector('a');

// Assigned as a property
link.onmousedown = function(){
  foo('property');
};

// Assigned as listener
link.addEventListener('mousedown', function(){
  foo('handler');
});

// Body property
document.body.onmousedown = function(){
  foo('delegated property');
};

// Delegated handler
document.body.addEventListener('mousedown', function(){
  foo('delegated handler');
});

// Your script only does this:
link.onmousedown = null;
&lt;a href="#foo" onmousedown="foo('inline')"&gt;Test&lt;/a&gt;




Now there's several steps needed to prevent it.

First, we cannot prevent addEventListener handles since removeEventListener requires the reference of the handle function which we normally don't have access to. The best we could do is to clone the node, which doesn't copy over handlers assigned via addEventListener. 

Then we override the inline onmousedown by defining your own function. Then we prevent delegated handlers by calling stopPropagation.

Lastly, we replace the original element with the clone.



function foo(message){
  alert('No stopping ' + message);
}

var link = document.querySelector('a');

// Assigned as a property
link.onmousedown = function(){
  foo('property');
};

// Assigned as listener
link.addEventListener('mousedown', function(){
  foo('handler');
});

// Body property
document.body.onmousedown = function(){
  foo('delegated property');
};

// Delegated handler
document.body.addEventListener('mousedown', function(){
  foo('delegated handler');
});

var clone = link.cloneNode(true);

clone.onmousedown = function(event){
  event.stopPropagation();
}

link.parentNode.replaceChild(clone, link);
&lt;a href="#foo" onmousedown="foo('inline')"&gt;Test&lt;/a&gt;