はじめに
初Qiita投稿です。エンジニア歴半年でJavaScriptに苦手意識があり避けてきたのですが
社内用のエディターが必要になって、勉強しながら自作エディターを作ることに。
Qiitaの投稿画面のような連動スクロール(左の箱に書いた文字を右の箱で反映して、左の箱をスクロールすると右の箱内も自動スクロールされる)の実装でつんだので、
同じ境遇に人の参考&他にもっといい書き方などアドバイスいただけると嬉しいです。
実装方法
html側
左側は入力するのでtextarea、
右側にtextarea内を反映するdivを作る。
<!-- 同時反映させたいので、キーボードを押した時に反映する関数を仕込む -->
<textarea id="before" onKeyDown="reflectNow()"></textarea>
<div id="after" ></div>
css側
(よしなに…)
#before, #after {
border: solid 1px #333;
width: 50%;
min-height: 100vh;
display: inline-block;
vertical-align: top;
font-size : 22px;
padding: 20px;
box-sizing: border-box;
height: 100vh;
overflow: auto;
}
#before {
background : #333;
color: #fff;
font-size: 18px;
}
JavaScript側
/* 左側に書いた文字を右側に反映 */
function reflectNow() {
after.innerHTML = before.value;
}
/* 連動スクロールの処理 */
window.onload = function (){
// beforeをスクロールした時に発火させる
before.addEventListener('scroll', function(){
setTimeout( scr(), 500);
}, false);
// カソールの位置が変わって書き始めてもスクロールするように
before.addEventListener('onkeydown', scr(), false);
/* スクロール */
function scr(){
// before(左)とafter(右)を変数に入れる
var before = document.getElementById('before');
var after = document.getElementById('after');
// beforeとafterそれぞれの高さの現在値を取得
var beforeScr = before.scrollTop;
var afterScr = after.scrollTop;
// afterの高さを取得
var afterHeight = after.scrollHeight;
// 全体の高さから現在値の高さをひいて、高さの割合をだす
var beforeHeight = before.scrollHeight - beforeScr;
var scrPercent = beforeScr / beforeHeight;
// beforeのスクロールの割合をafterにかけて、その分だけafterをスクロールさせる
after.scrollTo(0, afterHeight * scrPercent);
}
}
文字を打った時にbeforeからafterに反映するのは同期させて、
スクロール自体は同時にする必要がないので、setTimeoutを使って処理の負荷を減らしました。
最後に
計算が苦手で、割合の出し方をまちがてスクロールするとカクカクするっていう事象にハマっていたのですが、
consoleで割合を見てみたらスクロールの途中から100%超えてて、あれ…ってなりました。
バグってたら1つずつconsoleを入れてみるのが大事だなと思いました。
つまった時、アドバイスしてくださったみなさまありがとうございました!!