Question

I tried to run a simple code to replace strings in the body of an HTML page in JS.

document.body.innerHTML = document.body.innerHTML.replace(/foo/g,"bar");

The above code runs fine in the browser console (tested in Firefox and Chrome), but when I run the same via a JavaScript bookmarklet with a prefix of javascript:, the page breaks, losing all its style elements.

I'm just curious why the code behaves differently as I thought the JS code run in console or via bookmarklets would be run in the same environment.

Was it helpful?

Solution

The easiest way to realize what's going on here is to type javascript:"Hello world" into the location bar and hitting enter. Note that the page content is replaced, even though you didn't touch the DOM.

That's because the return value of a bookmarklet is handed over to the page content, if it exists. And in this case, (document.body.innerHTML = document.body.innerHTML.replace(/foo/g,"bar")) evaluates to the new innerHTML1. Which is just the innerHTML of the document body, so the stle information is lost when the entire document HTML is replaced.

Far better to do this:

javascript: ( function(){document.body.innerHTML = document.body.innerHTML.replace(/foo/g,"bar") }()

which has the added bonus of making all your vars private. Or you can just tack on a return false; to the bookmarklet as @diegog suggested.

1. Not undefined, in Javascript the equality operator returns the value too, much to the annoyance of those who mistype ==.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top