Help us understand the problem. What is going on with this article?

Z̩̮̜͉̣͎͉̤͇͂̇͊̇̅̚ͅa̠͌̔l̨̢̞̘͉̟̰̱̭̜͍̙̣̬̂̿̌̐̾̾͂̍̽̓̓̇̄g̨̢̡̢̛͍̪̠̠̹̜̪̘̱͌̆̒̅̐ỏ̡̱̞̣̖̦̰̙͊́̋́̃̂̓̍̃

T̡̨͈͇̟̼̱̤̹̠́͆̂̋̂̀̄̋́̚ö̴̮̬̙͎͈̳̯́̈́̄̿̔̿͌̀̈́̀̊͊͊̌̈̓̕ͅ i̷̢̛̖͈̗̇n̶̝͂̂̂v̸̹͈͍̮̰̺̰̯̬̀̋̎̃̅́̓o̸̢͈̪͍̦̫̬̪̬̞̫̗̅̑͊́̓͋̕̚k͉̣͆̄e̷̶̡̳̤̤͇̠̤̼̭̠̭͈̻͆̃́̒̂̊̇̂ ẗ̵̢̢̛͉̪͈̪̥̞̣̪̙́̈́̓̃̂̆̀h̨̗̻̰̱̳̅͂̎̇̽̃e̷̴̶̛̬̦̮̜̾̂̃͂̐̌̈́̄̾̈́̄̀̚̕ h͍̘̙̠̯̜̫̙̙̜̥͉̝̋͌̌́͋̽͋̉̂̊̄i̶̡̢̧̧̨̛̯̬̤̭͇͂́̏͂̐̋̈́̎̍̋̀̐̕v̸̡̢̛̤̫͇̹̱̗̮̻͈̳̄͆̓̄̾̀̋̀́̕ȩ͍̹͂-m̴̶̳̖̼̟̅̓ĭ̴̠̙̦̗͍̙̀̒͂͌ņ̵̵̨̼͇̖̥̉͂̓̌̀ḓ̛̛̗̠̰̞̫̗̘̗̖̖̎̈́̐́̈́̑ͅ ṟ̯̟̟̣͍͈̰̫͌̓̆̽̈́̆̀̊e͎̜̭̣̝̪͂̒̔̽̕p̸̧̡̨̛̛̤̦̹̩͉͎͈̬͍͈̞̈́̀̉̿̈̄̒̊̇̽̚ͅȓ̶̵̴̳̘̟͈̓e̬̟̝̎̍s̶̷̷̡̛̪̞͇̼̤̱̘̼̘̘͈̮̃̾̑̆̑̆̏̈ͅe̢̬̳͈͉̙̖̖̱̭͈̣̪̲̱͎̔̓̅̎͋̃͋̾̂ͅņ̸̷̶̷̸̻̱̻̹̻̥̹̟̭̘̟̟̣̟͊̔̏̔̀̐͆̋̚ͅt̶̵̢͍͈̳̱̬̫̯̣̾̂̆̓i̷̸̧̛̛̹̹̯̬̜̪̼͇̮̤̯̖̾̀̄̃͌̃̄̓̔̋̏n̴̛̩̗̦̟̖̣̒̓̈̒̓̏̇̈́̓̽̉͊̑͌́͋̚ͅͅg̛̬͉̳̗̈́ ċ̵̶̨̠̘̮̤̺̟̹̱̠̙̅̑̽̽̃̐́̀̅̃̾ḩ̤̖̮̖͈̣̘̺̱̍̎͋ȧ̸̴̴̡̨̢̧̘̩̥͉̣̰̝̘̪̠̖͉̐̋̇̏̊̚̕ͅö̵̩̼̰̣̟̱̳̞̖̪̗͎́̃́́̆̍̓͌̀̽̃̊̿s̸̼̱͇̿̍͊͊

[].concat(...[...document.all].map(e => [...e.childNodes])).filter(n => n.nodeType === Node.TEXT_NODE).map(n => n.textContent = n.textContent.replace(/([a-zA-Z])/g, (_, c) => c + [...Array(Math.floor(Math.random()*30))].map(() => String.fromCharCode(0x300 + Math.floor(Math.random()*79))).join('')))

Ç̵̶̶̡̛̱̘̤͉̘̹͈̳̝̝̽̆́̀̈́̾̍̅̎̑̌̿̚ͅȯ̷̳p̶͍̲͇̳̔̅̍̚y̴̸̵̢̡̭̖̩̫̘̼̦̬̓̿̇͋̉͊̓́́́̑̍ a̴̵̶̢̛̟̬̘͍̰̝̘͌̍̈́̉̔̂͋̊̑̍̽̚̕n̸̵̢̢̧̛̛̪̬̯̠̣̮̤̮̻͈͈̘͌͋́̓̏̀́̋d͇͎̝̜͈͇͂̋ p̄a̴̸̴̛͉̰̯̗̯̯͉̰̲͈̤̞̽͂̃̔̔̅̒͂̑́s̢̝̮̳̳̮̪̞̟̃̾̑̅̒́͊t̷̨̨̫̣͇̮̮͍̺̭̓̈̎̇̔̈́̆̒̌̕̕ĕ̢̢̡̤̗̟̫̄̀̚ t̶̸̢̥̘̫̮̹̤̉̑̀̀̽̔̑h̸̝̝̀͊̅e̵͇̖̞̹̅͊̄̋̄̐̑̑ c̼̞̠̯̜̹̺̱̖͈̙͎̔̈́̽̓̔́̄̾̋̾̓͊̅̾̔̚̚o̵̢̥̘͍̱̗͈͈̭̟͇̠̰̪̮̩̿̂̅͌̀̀͌̀̑̆̆d̡̡̳̣̪̦̩̟͉̝͇̬̼̺̖̫̏̈́̅̇̍́̓̎̋ͅͅe͉̦͆͂̉̔ a̛̺̥̜̤͈͍̠̠͍̣̳͌̍̊̉̎̑͌̇̊̾̽́̒̒̾̏b̸̶̭̙̥̥̱̫̮̜̌͌̋̿̍̓ò̵̸̻̟̰̗̯̥̭̈́̾͌͌̃̾̊̽̽́̑̉́v̳̗͊̄͊̓̔̅́ḙ t̴̶̵̡̧̮̯͍̟̝̭̲̮̰̰͇̺̪͊͋͋̓̽͆̽́̂́̂o̧̜̖̟̼̥͎̭̩̟̳͍̅̓̾̏̎̀̅̍̐͆̈͊͆ t̷͉̣̺̗̰̱̏͊̎̂̇̆ḩ̨̜͎̳̺̥̬͊́̇̒̾̐̏e̛͉̝̙̓̀̓̾̑̚ ȃ̵̡̢͎̖͈̬̾̓̃̓̋̊̏͆͆̆̋̿ḑ̡̩̦̬̬̻͎̏̑̍͋͆̊̽̊́̾̐̏̈̀̽̎̚d̸̨̼̭̥̮͉̯̥̬͈̦̦̠̯̺̮͆̏̄̄͊̽́̏̽̓̏̂̕r̙̤͊̔̀̾e̷̡̹̜̫͍̻̥̋͂̓́͋̍̆s̸̷̨̡͈̲̰̮͇̦̪̟̭͈̲̟̀͌̋͂̔͊̍̓̏̿̕s̆ b̴͍̰̖̹̉à̲̱̬ŕ̤̙̫͎̻̞̥̼̮̑͂ a̳͉̲̲̗̮̰̜̾̏̅̄͌̿̂̕n̸̸̛̦̹̥̺͈͈͂̂̎̌̈̒̀̔̽̏͂̆̍ͅd̗̀̉ ṗ̶̭̲̠̞͌̄r̸̷̨̡̨̛̺̫͎̞̤̣̭̠̞̣̼͊̀̅̓̈́̔̈́̚e̷̴̢̨̻̱̳̼̘̘̍̄́̓̽̒̔̽̃̍̓̄͌̒̏̆̀̚̚p̶̨̧̯̟̪̙͍̖̪̌̓̇̈́̐͋̅̕e̷̸̢̧̝̘̜̭̠̘̰̗̋̀̀̏͆̐̈́̌͆̌͆̏̕ͅņ̶̡̻̼̩̼̙̖̰̯̤͈͇̦̬̈́̂̒̀́͋̆̿͂͆̚d͆̉ͅ "j̺̙àv̴̖͍̀̿̽̏͆a̭͉̞͇͎̓͌̔͋s̸̢̢̡͎̲̯̙͈̳̱̟̹̱̤͎̏͂̅̄̒́̈̔̆̀ͅc̴̡̪̳͎̤̭̺̗̟͂̀̎́̏͆̒̈́ȓ̸̢̨̭͎̠̪̜̣̈͆̒͌͂͌̎͆͋ĩ̲̞̰̤́̄p͇̀̓͆́ţ̴̷̺̯̫̯̻̯̹̺̠̲͈͉̤̍̔̔̌͂̀̓́̂́͊́̕:", ẗ̷̢̯̮͇̗͈̦̫̮̼͆̔́̾h̖̰̲ȩ̛̝̥̘̯̠͉͂̊̓̚n̟̼̩͊̒̈ ṕr̴̨̦̭̦̪̺̟͊̃̂̑̾́̂́̆̀é̇s̷̨̪̤̮̟̗̿͂̐͌̈́̓̅s̵̛̭̤̩͎̦̳̠̘͈͍̜̒̏̽͂̃́̏̏̀ͅ Ě̸̦̱̙̭̠̯̬̂́́́̋̏̐̆̕ṅ̠̼̳̮̌̌͌̊̽̓ţ̷̶̡̨̛̩̰̜̪͇̫̘̯̱͈̙̯̜́̾͆̌̒̏̓̚ȩ̼̻͈͊̍̑̎ṟ̡̜̘̩͉͂̔̀̀̈́̐ k̵̡̲̮͉̣̲̜̰̺͎̺̲̒̅̓̓̿̐͂̊̂̌̋̉̀ͅe̸̵̯̣̥̣̝̒y̭̜̞̠̳̺͆̑̆͌.

注意

実行には数秒くらいの時間が掛かります。
Googleの検索結果ページ等だと、何故かページのスタイルが崩壊してしまいます。
GitHubとかのページでやると良いでしょう。
(追記: スタイル等が崩壊するのは<style><script>の中身が変わるためのようです。こいつらもTextNodeなのか)

解説

ZalgoするJavaScript(ES6)ワンライナーです。
JavaScriptの闇がいくつか詰まっているので1つずつ説明しようと思います。

まずprettifyするとこんな感じ

[].concat(...[...document.all].map(e => [...e.childNodes]))
  .filter(n => n.nodeType === Node.TEXT_NODE)
  .map(n =>
    n.textContent = n.textContent.replace(/([a-zA-Z])/g, (_, c) =>
      c + [...Array(Math.floor(Math.random()*30))].map(() =>
            String.fromCharCode(0x300 + Math.floor(Math.random()*79))
          ).join('')
    )
  )

[].concat(...arrayOfArrays)

(編集しました。元は Array.prototype.concat.apply([], arrayOfArrays) としていましたが、ほぼ同じ意味です)

Array.flatMap をしたい時はこうするしかありません。 ふざけんな
配列の配列(arrayOfArrays)を全て結合して1つの配列にします。

(追記: いつの間にか Array.prototype.flatMap が標準に入ってました)

今回は全てのelementに対してそれぞれのchildNodeの配列を取得するので、Nodeの配列の配列が出来ます。これを単なるNodeの配列にするわけです。

[...iterableObject]

document.all とか element.childNodes とかはただのIterableであってArrayではないため、 map が出来ません。
そのため、上記のような spread operator (...) を配列リテラルに使うことで無理やりArrayにします。

ページ内の全てのTextNodeを取得する

まとめると、以下でページ内の全てのTextNodeを取得することが出来ることになります。

[].concat(...[...document.all].map(e => [...e.childNodes]))
  .filter(n => n.nodeType === Node.TEXT_NODE)

[...Array(n)]

例えば、 Array(10).forEach(() => console.log('foo')) としても何も出力されません(forEachmapに変えても同じ)。
Array.prototype.forEachArray.prototype.map も、値がまだ代入されていないインデックスに対してはcallbackは呼び出されないのです。

一方で、[...Array(10)].forEach(() => console.log('foo')) とすると "foo" が10回出力されます。
これは、 Array.apply10個のundefined が引数として渡された結果 length10のものがargumentsとして渡された結果、0から9までのindexに undefined が代入されたことになるからです。

(ここの解釈はちょっと合ってるか怪しい...)

Combining character

http://www.unicode.org/charts/PDF/U0300.pdf

Unicodeには実にいろんな文字があります。
上記の U0300-U036F の範囲の文字は Combining character といって、直前の文字の上や下や真ん中にくっついてしまいます。
2文字以上の combining character が続くと、全ての combining character が前の文字にくっついて、上や下にズラーッと並んでしまいます。

スペースや日本語等の文字にはくっつかず、横に続いてしまうため、今回のスクリプトではアルファベットだけにくっつけるようにしています。
また、私の環境だと□になってしまったりしたので上記の文字のうち一部のみを使用しています。

おまけ

特定の文字列だけ変換したいことってありますよね。この記事を書くときとか。

'Any string here'.replace(/([a-zA-Z])/g, (_, c) => c + [...Array(Math.floor(Math.random()*30))].map(() => String.fromCharCode(0x300 + Math.floor(Math.random()*79))).join(''))

H̸̘̖̲̙̊̅̉̓̓̈́̏͋̕ȩ̨̡͈̰̟̹̝̒́̈̔̏̓̑̾ ẃ̶̷̨̢̢͎̟̦̺̗̥̗̘̓̓h̾ơ͈̯̭̝̞̊̃̎̉͊̾̾͆̂͂̚ W̸̶̷̢̟̲̙̮̫̭̫̾̇̆͌̆a̵̢̛̻̩̩̦̟͎̜͈̭͎̙̼͂̐̃̏̐̈́̇̇̚ī̤̫̘̈̑ṭ̸̢̛̟̰̖̝̬͎̥̝̀̏̅̎̇͋̀̈́̐̈́̓̎̑̂̓̚s̶̵̱̘̦̍͊ B̧̫̦̫̮̤̻̖̌̓e̷̛̳̮̺̤̳͎̮̳̲̐̎̔̋ͅh̶̹͍i̿̎̔̀ͅǹ̷͍̦̭̮̜̖̱̈̂̓̒͂̂ḑ̸̺̪̞̪̜̗̰̜̻̗̓̒̒̈́̍͊̏̄̉̒̍̾̽̌́̕ T̵̡̛̪̩̙̜́̌̅̃͂̏̾ḩ̸̞͈̞̯̥̣̹̩̫̤͂̇̀̀̾̇̆̔̽̎͊͆̄̾̂̚e̵̩̬͈̙̍̆͌̐ W̵̡̠̣̩̳̪͉̰̮̪̭̘̣̐́̈́̇̌͌̎́̐̂̎ͅa̡̢̩̯̘͎̻̺̹̞̔͊̽͋̏̐l̷̷̢̢̧̢̛̙̖̤̗̲̠̫̠̹̋̇̇́̚ĺ̴̵̴̸̻̗̬̪̙̠̥̘̙̙̆̃̋̉̑͌͌̾̄͆̚ͅ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away