Qiitaの本文で一時的に最下部へ移動するユーザースクリプト


概要動機

最近、本文がスッキリするので、リンク[text]:URLや脚注[^1]:textをまとめて最下部に書いているのですが、文量が長くなると元々の場所に戻るのがしんどくなってきました。
プレビューを見れば見つけやすいのですが、画像などを貼り付けると、だんだんプレビューと本文の場所が一致しなくなり捜索時間が増えます。
なので度々、こんなにも長く、時間がかかってしまった…とげんなりします。


中盤で大体1画面分ずれる

検索するのも面倒なので、ボタンを押したら最下部へ移動し、もう一度押したら最初に押した時の場所へ戻るボタンを作成しました。

動作確認環境

Firefox + Greasemonkey です。
大体スクラッチパッドで作ってからGreasemonkeyに移植しているので、Greasemonkey由来のものは無いと思います。

デモ

コード

Gistに上げるのでrawボタンからインストールできるはず…

Qiita_round_trip_button.user.js

// ==UserScript==
// @name        Qiita round trip button
// @namespace   khsk
// @description 最下部へ移動し、戻るボタンを追加
// @include     http://qiita.com/drafts/*
// @version     1
// @grant       none
// ==/UserScript==

// インターフェース作成
var i = document.createElement('i')
i.className = 'fa fa-arrow-down'

var div = document.createElement('div')
div.appendChild(i)
div.style.float = 'left'
div.style.fontSize = '24px'
// 「書き方」のマウスオーバーを拝借
div.className = 'editorMarkdown_help'

// document.getElementsByClassName('editorMarkdown_toolBar')[0].appendChild(div)
// ↑では、本文のみ表示時に現れるプレビューボタンより右に出てしまうので、左に出す
var tool_bar = document.getElementsByClassName('editorMarkdown_toolBar')[0]
tool_bar.insertBefore(div, tool_bar.lastChild)

// イベント登録
// キャレットはStart,End両方移動しないと選択状態になる

var body = document.getElementById('draft_item_raw_body')
var original_caret = 0
// 戻った時に先頭行になってもいいなら不要
var original_scroll = 0 

// 移動前のキャレットを保存し、最下部へ移動
var down_caret = function(e){
  original_caret = body.selectionStart
  original_scroll = body.scrollTop
  move_caret = body.value.length
  body.selectionStart = move_caret
  body.selectionEnd = move_caret
  i.className = 'fa fa-arrow-up'
  div.removeEventListener('click', down_caret)
  div.addEventListener('click', up_caret)
  body.focus()
}

// 保存したキャレットへ戻る
var up_caret = function(e) {
  body.selectionStart = original_caret
  body.selectionEnd = original_caret
  body.scrollTop = original_scroll
  i.className = 'fa fa-arrow-down'
  div.removeEventListener('click', up_caret)
  div.addEventListener('click', down_caret)
  body.focus()
}

div.addEventListener('click', down_caret)

注意

ありえない使い方ですが、最下部へ移動したあと、元々の位置より上で本文を編集した場合は、戻る位置がずれます。

元々のキャレットが隠れた状態で移動すると、戻った際に画面内の最下行または最上行にスクロールが合わせられます。
これは恐らく、優先度がcaret > scrollTop となっているからだと思われますが、詳細は不明です。

要望

他のアイコンのようにマウスオーバーでツールチップを出したかったのですが、動作がわかりませんでした…