重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

ノートの様な表示画面があります。
ページ部分をダブルクリックすると、テキストエリアが新しく作成される。
既にあるテキストエリアはドラッグで移動できる。

教えて頂きたいのは既にあるテキストエリアと同じ様に、新しく作成した要素にCSSのプロパティとドラッグイベントが反映されないという事です。

jqueryではなく、javascriptでの方法を教えて頂ければ幸いです。
宜しくお願い致します。


<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script
src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/turn.js/3 …
<script src="https://cdn.jsdelivr.net/npm/jquery-autosize@1.1 …
<title>メモ帳アプリ</title>
</head>
<body>
<style>

* {
margin: 0;
padding: 0;
}

html, body {
position: relative;
width: 100%;
height: 100%;
}


#test {
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%) translateX(-50%);
background-color: sandybrown;
width: 70%;
height: 80%;
margin: 0 auto;

}

#book-design {
margin: 0 auto;
background-color: salmon;
width: 85%;
height: 100%;
}

#canvas-parent {
width: 40%;
height: 100%;
background-color:rgb(247, 245, 232);
background-image:
linear-gradient(transparent 97%, rgb(230, 206, 71) 0%);
background-repeat: repeat;
background-size: 10px 30px;
position: relative;
}

textarea {
position: absolute;
width: 100%;
height: 2%;
}

ul {
list-style: none;
display: flex;
justify-content: flex-end;
}

以下略-------
</style>
<div id="test">
<div id="book-design">
<div id="canvas-parent">
<textarea name="" id="child" cols="30" rows="10"></textarea>
</div>
<div id="canvas-parent">
</div>
<div id="canvas-parent">
</div>
</div>
<ul>
<li id="reset">リセット</li>
<li id="prevpage">前のページ</li>
<li id="nextpage">次のページ</li>
</ul>
<p id="announce">※ページ外側の端部分をクリックでもめくれます。</p>
</div>
<script>
// ページをめくる動作
$(function(){
$('#book-design').turn (
{
elevation: 50,
duration: 1000,
gradients: true,
autoCenter: false,
direction: 'ltr',
}
);

$('#prevpage').click(function() {
$('#book-design').turn('previous');
});

$('#nextpage').click(function() {
$('#book-design').turn('next');
});

$('textarea').autosize();

$('#reset').click(function() {
$('#canvas-parent').children().remove();
});
});

var target = document.getElementById('canvas-parent');

// クリックした場所に要素を作成
target.addEventListener('dblclick', (event) => {
var clickX = event.pageX;
var clickY = event.pageY;

var clientRect = target.getBoundingClientRect();
var positionX = clientRect.left + window.pageXOffset;
var positionY = clientRect.top + window.pageYOffset;

var x = clickX - positionX;
var y = clickY - positionY;

var create = document.createElement('textarea');
target.appendChild(create);

create.style.left = x + "px";
create.style.top = y + "px";

console.log(clickX);
console.log(clientRect);
console.log(x);

});

// 要素の位置を移動する
var child = document.getElementById('child');

child.onmousedown = function(event) {
document.addEventListener('mousemove', onMouseMove);
}

var onMouseMove = function(event) {
var clickX = event.pageX;
var clickY = event.pageY;

var clientRect = target.getBoundingClientRect();
var positionX = clientRect.left + window.pageXOffset;
var positionY = clientRect.top + window.pageYOffset;

var x = clickX - positionX;
var y = clickY - positionY;
child.style.left = x + "px";
child.style.top = y + "px";
}

child.onmouseup = () => {
document.removeEventListener("mousemove",onMouseMove);
}

</script>
</body>
</html>

質問者からの補足コメント

  • 回答ありがとうございます。
    教えて頂いた情報を元に下記作成しましたが、今一度教えて頂きたく。

    今回は作成した要素にもイベントが付加されましたが、挙動が少しおかしいで
    す。
    ドラッグイベントは、mousedown→mousemoveでマウスのドラッグイベントを作成しました。

    mousedown→mouemove
    要素の上でマウスボタンを押しっぱなしにして、カーソルを移動するとそれに合わせて要素も移動しました。

    おかしい挙動
    クリックする(例えばノート内の座標:(x:30,y:30)をクリック)
    その後に少し離れた場所の要素に触れると(mousemove)、クリックした場所の座標に瞬間的に移動する。

    宜しくお願い致します。

      補足日時:2021/02/12 09:02
  • コードは書ききれなかったので、お礼に記載しています。

      補足日時:2021/02/12 09:03
  • うーん・・・

    回答ありがとうございます。
    自身が欲しかった内容がすべて入ってます。
    本当にありがとうございます。

    質問になりますが、elmってなんでしょうか?
    obj.elm.clientWidth

    console.logで値を調べてみると,textarea.movableとなっております。
    これを使用して、要素を取得してるのは何となくわかります。

    ・ですが最初は変数や定数としてオブジェクトを作成してると思いましたが、宣言もされておらず、

    ・objの後ろに書かれているのでオブジェクトのプロパティとも考えられます。

    ・また、elmはelmentオブジェクトの省略なのかと予想もしたりします。
    でもその場合、objオブジェクトの後にオブジェクトがくる書き方があるのか疑問です。

    実際にelmはどの様なものなのか教えて頂きたいです。

      補足日時:2021/02/17 14:35
  • うーん・・・

    また、下記のコードについて教えてください。
    x: Math.min(Math.max(p.x, 0), cPRect().width - obj.elm.clientWidth),となっていますが、
    p.xの部分を教えて頂きたいです。

    自分の解釈としては、
    pはpLimの引数(p)のことで
    xはx: Math.min(Math.max(p.x, 0), cPRect().width - obj.elm.clientWidth)のプロパティ,X:を示しているという認識で宜しいでしょうか?

    その場合、
    働きとしてpで要素を取得し、xのプロパティの値にMath.min(Math.max(p.x, 0), cPRect().width - obj.elm.clientWidth)の計算結果の値が入る、そしてその値が0以上ならばその値が取得され、以下ならば0の値が取得される。

    No.2の回答に寄せられた補足コメントです。 補足日時:2021/02/17 16:27
  • 連続の質問、失礼します。

    cPRect = () => cParent.getBoundingClientRect()
    上記コードですが、なぜ関数じゃないと動作しないのでしょうか?
    定数にそのまま入れる様にすればいいのではと思い試してみましたが、動作しませんでした。
    cPRect = CParent.getBoundingClientRect;

    pos = (a, b={x:0, y:0}) => ({
    x: a.clientX - cPRect.left - b.x,
    y: a.clientY - cPRect.top - b.y
    }
    以下略

    何度も申し訳ございません。
    宜しくお願い致します。

    No.3の回答に寄せられた補足コメントです。 補足日時:2021/02/20 12:06

A 回答 (6件)

No5です。



>イベントを行う事で関数内の処理はどの様に行われているのか。
>そこがまだわかっていません。
関数と引数の意味がおわかりでないように思います。
No5の例の意味を理解して下さい。

関数を含んだ処理がわからなければ、関数を外して関数の内容を直接入れ込む形に展開してみれば宜しいでしょう。
行数が増加しますが、関数を使わずに記述した場合はそのようになります。
(内容によっては、多少、無駄な記述が含まれるようになると思いますが、その部分は取り除けば宜しいでしょう)

No5を例にするならば、

const f3 = n=>{
let f1 = n + 1;
let f2 = n + 2;
return f1 * f2;
};
alert( f3(2) ); // 12

といった感じです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

下のSetPosを分解するとして下記の様なやり方で宜しいのでしょうか?
理解するために単語も一つ一つ解説。

____________________________________________________
仮に座標値をいれた場合、

const obj = {};
obj.setPos = (e, o={x:0, y:0}) => {
const A1 = n => let p = pLim( pos(e, o) );
const A2 = n => obj.elm.style.left = p.x + 'px';
const A3 = n => obj.elm.style.top = p.y + 'px';
}

obj.elm.style.left = 作成した要素のクリックした座標
obj.elm.style.right = 同上


pLim = (p) => ({
x: Math.min(Math.max(p.x, 0), cPRect().width - obj.elm.clientWidth),
y: Math.min(Math.max(p.y, 0), cPRect().height - obj.elm.clientHeight)
});

p.x = 0(デフォルト引数が0なので)
CPRect.w~ = 200
obj.elm~ = 25(作成したtextarea.movableの幅)
Math.max(0,0) =0
Math.min= (0, 200-25=175) = 0

p.y = 0(デフォルト引数が0なので)
CPRect.h~ = 100
obj.elm~ = 30(作成したtextarea.movableの高さ)
Math.max(0,0) =0
Math.min= (0, 100-30=75) = 0


let p = pos(e);
obj.x = p.x - obj.elm.offsetLeft;
obj.y = p.y - obj.elm.offsetTop;
};

p.x = 0
obj.elm~ = 300(textarea~の左上座標)
0-300 = -300

p.y = 0
obj.elm~ =200(textarea~左上座標)
0-200 = -200

お礼日時:2021/02/23 11:10

No4です



>気になるのはなぜイベントオブジェクトを行っただけで、~
意味不明です。

関数の引数は単なる変数ですし、javascriptの場合は、変数には値だけでなくオブジェクト等も代入可能です。
ですので、(前にも述べましたので、繰り返しになりますが)単に与えられた引数をそのまま呼び出す関数に引き渡しているだけです。

 const f1 = n => n + 1;
 const f2 = n => n + 2;
 const f3 = n => f1(n) * f2(n);

 alert( f3(2) ); // 12 = (2+1) * (2+2)

前にも述べましたが、不明点は自分で調べられるようになりましょう。
https://developer.mozilla.org/ja/docs/Learn/Gett …
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
前回、引数として受け取ったe(=イベントオブジェクト)をそのまま、pos関数に引き渡しています。
となりますが、イベント処理を行う事で引数に値が引き渡されるという認識です。

わからないのは関数の中身がどう処理されているかわかりません。
例えば、下記のダブルクリックイベントを行う事で関数内の処理はどの様に行われているのか。
そこがまだわかっていません。

下記はわかる限りの認識。
イベント(ダブルクリック)→関数内の処理→結果

//イベント処理
ダブルクリックする事で要素が作成
関数内の処理は位置(座標)が作成される ←イメージわかない
const
doubleClick = e =>{

obj.elm = template.cloneNode();
obj.setPos(e);

},  

//関数
上記コードの中にある関数が処理される
関数の処理の順番: obj.setPos→pLim→Pos
const obj = {};
obj.setPos = (e, o={x:0, y:0}) =>{
let p = pLim( pos(e, o) );
obj.elm.style.left = p.x + 'px'; 作成した要素の位置決定
obj.elm.style.top = p.y + 'px'; 同上
};

e→イベントオブジェクト
o→oはデフォルト値を入れる為のもの,下記posのx.yプロパティ値を0にする

pos(e,o)(コールバック)
e→同上
o→同上

pLim = (p) => ({
x: Math.min(Math.max(p.x, 0), cPRect().width - obj.elm.clientWidth),
y: Math.min(Math.max(p.y, 0), cPRect().height - obj.elm.clientHeight)
});

p→pos(e,o)、x.yのオブジェクト(p.x,p.y)

let p = pos(e);
obj.x = p.x - obj.elm.offsetLeft;
obj.y = p.y - obj.elm.offsetTop;
};

e→同上
p.x→上記と違い、let pのp.xとp.yになる
p.y→同上

宜しくお願い致します。

お礼日時:2021/02/22 11:40

No3です



>定数posについてわからないことがあります。
posはクリック位置からtestareaの位置を計算する関数です。
移動の際には、マウス位置とtextareaの位置差を考慮に入れているので、その分が引数bにあたります。
bが不要な場合(textareaを生成する場合)もあるので、呼び出し側で引数を省略した場合には、b={x:0, y:0}として計算します。(←デフォルト引数)
以下と同等と思います。
 let pos = (a, b)=>{
  if(b == undefined) b = { x:0, y:0 };
あるいは、呼び出し側で
 pos(a, { x:0, y:0 });
のように記述すればよいのですが、不要な引数をわざわざ記述するよりも、受け取り側で処理しようという考え方です。

※ javascriptに関しては、MDNのサイトに大量の情報がありますので、不明なことはこちらで調べれば、大抵のことは解決すると思います。
https://developer.mozilla.org/ja/docs/Web/JavaSc …

>そうだとしてもイベント処理をなぜ起こすような動作なのかわかりません。
イベント処理の中で、「元のイベントオブジェクト」をそのまま引き継いでいるだけです。(新しいイベントが発生しているわけではありません)
 >obj.setOffset = e=>{
 >let p = pos(e);
引数として受け取ったe(=イベントオブジェクト)をそのまま、pos関数に引き渡しています。

>pos自体に引数を入れる動作がコードの中に見当たりません
直接pos関数を呼び出しているのは、
 obj.setPos
 obj.setOffset
のメソッドです。
実際のイベント処理の関数からは、上記のメソッドを利用することで、間接的にpos関数を利用していることになります。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
デフォルト引数引数は理解できました。
ですが、イベントオブジェクトについてですが、なぜイベントオブジェクトを起すだけで各関数の引数に値ができるのでしょうか。

例えば、マウスダウンのイベントがあったとします。
mouseDown = e =>{
let t = e.target;
obj.elm = null;
if(t.nodeName != 'TEXTAREA' || !t.classList.contains('movable')) return;
obj.elm = event.target;
obj.setOffset(e);
t.classList.add('active');
},

途中にある.setOffset(e)がイベントオブジェクトです。
イベントオブジェクトの中身は、

//obj.setOffset = e=>{
let p = pos(e);
//obj.x = p.x - obj.elm.offsetLeft;
//obj.y = p.y - obj.elm.offsetTop;
};
さらにsetOffsetの中にlet p = pos(e)があります。

pos = (a, b={x:0, y:0}) => ({
//x: a.clientX - cPRect().left - b.x,
//y: a.clientY - cPRect().top - b.y
}),

気になるのはなぜイベントオブジェクトを行っただけで、各関数(settOffset,pos)に値が作成されてるのかがわかりません。

普通関数の場合は、
func(a,b) {
return a *b*;}
という関数があり、
func(3.2);という呼び出し方になります。
関数の引数に値を入れることで結果が返るのに、
イベントオブジェクトを行った事でいつ引数に値が入ったことになるのでしょうか?

宜しくお願い致します。

お礼日時:2021/02/21 10:01

No2です



>質問になりますが、elmってなんでしょうか?
objオブジェクトは、(値等を記録しておくために)勝手に定義したオブジェクトです。
ですので、そのプロパティやメソッドは作者が自由に設定できます。
ちなみに、obj.elmは「移動中の要素」を一時記憶しておくために利用しています。

>elmはelmentオブジェクトの省略なのかと予想もしたりします。
上述の通り、「勝手に決めている」プロパティなので、elmでもelementでも構いません。
他の記述部分で、統一して使ってさえいればよいことになります。

>x: Math.min(Math.max(p.x, 0), cPRect().width -
>obj.elm.clientWidth),となっていますが、
関数pLimの内容のことと思いますが、この関数はtextareaが親要素をはみ出さないように換算した左上の座標位置を返すものです。
クリックやドラッグによってカーソルの位置を取得しますが、その位置にそのまま表示してしまうと親要素をはみ出す可能性があるので、MAX、MINをとることではみ出さないように換算しています。
この関数内で用いられている p は、引数として与えられている位置を示すオブジェクトで、その位置を上記のような範囲に換算した値にして返しています。

>pはpLimの引数(p)のことで
その通りです。

>xはx: Math.min(Math.max(p.x, 0), cPRect().width - obj.elm.clientWidth)の
>プロパティ,X:を示しているという認識で宜しいでしょうか?
「p.x」のxの意味のことなら、プロパティではありますが、違います。
変数pが座標を示すオブジェクトで、x、yのプロパティを持っています。
それをもとに、範囲に収まるように再計算を行っています。

>働きとしてpで要素を取得し
p は要素ではありません。座標位置を示す{x:x, y:y}形式のオブジェクトです。


※ No2でもお断りしましたが、書きっぱなしのスクリプトなので、熟考した上のものではありません。
ですので、細部の定義や構造などの整合がとれているとは限らないことをご承知おきください。
動作の確認はしてありますが、あくまでも、複数要素に対して同じ関数で処理を行うような場合の参考例としてご覧くださるようお願いいたします。
この回答への補足あり
    • good
    • 0
この回答へのお礼

>書きっぱなしのスクリプトなので~
とんでもない。とても勉強になります。

度々質問になりますが、
定数posについてわからないことがあります。
pos = (a, b={x:0, y:0}) => ({
x: a.clientX - cPRect().left - b.x,
y: a.clientY - cPRect().top - b.y
}),

obj.setOffset = e=>{
let p = pos(e);
obj.x = p.x - obj.elm.offsetLeft;
obj.y = p.y - obj.elm.offsetTop;
};


・定数SetOffsetの中にpos(e)がありますが、これは元のposの引数(a,b={x: 0, y: 0})と引数の数に違いがありますが、これは何故なのでしょうか。
posという定数になぜ違った数の引数が入るのかがよくわかりません。
eはイベントの引数というのは何となくわかりますが、そうだとしてもイベント処理をなぜ起こすような動作なのかわかりません。
本来なら、下記の様になるのではないでしょうか?
obj.setOffset = e=>{
let p = pos(a, b={x:0, y:0}); ←引数が2つ
obj.x = p.x - obj.elm.offsetLeft;
obj.y = p.y - obj.elm.offsetTop;
};

・また、定数pos(a, b={x:0, y:0}) => ~ですが、引数a,bは座標値を求める数値かと思われますが、どのタイミングや状態で引数に数値が入るのでしょうか?(bのx,yのプロパティも同様)
Pos自体に引数を入れる動作がコードの中に見当たりません。

ご教示頂きたくお願い致します。

お礼日時:2021/02/20 11:09

No1です



>クリックした場所の座標に瞬間的に移動する。
No1にも書きましたけれど、
>同じ処理を複数要素で使いたいなら、それに対応できるような
>記述法にしておくほうがよろしそうです。
というあたりに配慮する必要がありそうに思います。
また、mousemoveのイベント処理を設定したり外したりしているようですが、必ずしもそのような必要はなさそうに思います。

実際に、どのようなUIになさりたいのかよくわからないので、以下テキトーですが・・・
「ダブルクリックで追加、ドラッグで移動」だけの部分にして、ページングやテキストエリアのサイズ変更は外してあります。

>jqueryではなく、javascriptでの方法を教えて頂ければ幸いです
とのことなので、素のスクリプトで試してみました。
以下の例は、書きっぱなしのものを動くようにしただけですので、読みにくいとは思いますが、多少のご参考にでもなれば。(Chromeで検証)
移動中のテキストアリアには、activeクラスを付与し、色が変わるようにしてあります。
また、テキストアリアは(基本的に)親要素をはみ出さないように制御をしています。
(画面リサイズの際の制御までは行っていないので、リサイズするとはみだしますが…)

<!DOCTYPE HTML>
<html lang="ja">
<head><title>Sample</title>
<style>
* { margin: 0; padding: 0; }

#canvas-parent {
position: relative;
margin: 10vh 10vw;
width: 80vw; height: 80vh;
background-color:rgb(247, 245, 232);
background-image: linear-gradient(transparent 97%, rgb(230, 206, 71) 0%);
background-repeat: repeat;
background-size: 10px 2em;
}

textarea.movable {
position: absolute;
width: 25em; height: 2em;
}
textarea.active {
border: 1px solid #D88;
background-color: #FFF8F8;
}

#template { display: none; }
</style>

<script>
window.addEventListener('DOMContentLoaded', () =>{
const
template = document.querySelector('#template textarea'),
cParent = document.getElementById('canvas-parent'),

cPRect = () => cParent.getBoundingClientRect(),
pos = (a, b={x:0, y:0}) => ({
x: a.clientX - cPRect().left - b.x,
y: a.clientY - cPRect().top - b.y
}),
pLim = (p) => ({
x: Math.min(Math.max(p.x, 0), cPRect().width - obj.elm.clientWidth),
y: Math.min(Math.max(p.y, 0), cPRect().height - obj.elm.clientHeight)
});

const obj = {};
obj.setPos = (e, o={x:0, y:0}) =>{
let p = pLim( pos(e, o) );
obj.elm.style.left = p.x + 'px';
obj.elm.style.top = p.y + 'px';
};
obj.setOffset = e=>{
let p = pos(e);
obj.x = p.x - obj.elm.offsetLeft;
obj.y = p.y - obj.elm.offsetTop;
};

const
doubleClick = e =>{
if(e.target != cParent) return;
obj.elm = template.cloneNode();
cParent.appendChild(obj.elm);
obj.setPos(e);
obj.elm = null;
},
mouseDown = e =>{
let t = e.target;
obj.elm = null;
if(t.nodeName != 'TEXTAREA' || !t.classList.contains('movable')) return;
obj.elm = t;
obj.setOffset(e);
t.classList.add('active');
},
mouseUp = e =>{
if(obj.elm) obj.elm.classList.remove('active');
obj.elm = null;
},
mouseMove = e =>{
if(!obj.elm) return;
obj.setPos(e, obj);
obj.setOffset(e);
},
setEvent = (elm, evt, func) =>{
elm.addEventListener(evt, e =>{ func(e); });
};

setEvent( cParent, 'dblclick', doubleClick);
setEvent( cParent, 'mousedown', mouseDown);
setEvent( cParent, 'mousemove', mouseMove);
setEvent( document, 'mouseup', mouseUp);
});
</script>
</head>
<body>
<div id="canvas-parent">
<textarea class="movable"></textarea>
</div>
<div id="template">
<textarea class="movable"></textarea>
</div>
</body>
</html>
この回答への補足あり
    • good
    • 0

こんにちは



いろいろありますけれど・・・
とりあえず、同じid(=canvas-parent)の要素が複数あるのは、文法違反になるので修正しておいたほうが良さそうです。

>新しく作成した要素にCSSのプロパティとドラッグイベントが反映されないという事です。
CSSで設定されている、textareaの内容は、タグ名指定なので反映されています。
例えば、色を付けるなどの設定を追加してみれば、反映されていることを確認できるでしょう。
要素の属性値のこと言っているのなら、生成したときに付加すればよろしいでしょう。
あるいは、既存の要素の複製を作成してしまえば、属性値も同様に付加したまま複製することが可能になります。
https://developer.mozilla.org/ja/docs/Web/API/No …

イベントの設定も、属性値として設定しておくようなスタイルにしておけば、同時に複製されることになります。
一方で、addEventListener()で設定したイベントは複製されませんので、要素生成時に設定するか、あるいは後述の方法によるかになります。
その前に、ご提示のコードではid指定で、個別の要素にイベントを設定していますが、同じ処理を複数要素で使いたいなら、それに対応できるような記述法にしておくほうがよろしそうです。


追加要素に毎回イベントを設定するのも面倒なので、jQueryのイベント設定の
 .on( events [, selector ] [, data ], handler )
形式のselectorの設定を利用することで、最初に上位要素に一回だけイベントを設定しておけば済むようになります。

>jqueryではなく、javascriptでの方法を教えて頂ければ幸いです。
とのことなので、上記のjQueryと同じ内容を記述する場合の一例を以下に示しておきます。
仮に、documentでイベントを取得するものとして、例えばtextareaをクリックした時だけ処理をするようにするとして・・・
document.addEventListener('click', (e)=>{
let t = e.target;
if(t.nodeName == 'TEXTAREA'){ t.value='this area has clicked!'; }
});
のような設定の仕方をしておくことで、後から追加した要素であってもtextareaであれば適用されることがわかると思います。
(上例では、textareaをクリックすると、文字列が先行入力状態になります)
また、上例では要素名で識別していますが、実際には、個別(同じ処理のものは共通)のクラス名などを利用して識別するようにしておいたほうが宜しいかと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
教えて頂いた情報を元に下記作成しましたが、今一度教えて頂きたく。

今回は作成した要素にもイベントが付加されましたが、挙動が少しおかしいで
す。
ドラッグイベントは、mousedown→mousemoveでマウスのドラッグイベントを作成しました。

mousedown→mouemove
要素の上でマウスボタンを押しっぱなしにして、カーソルを移動するとそれに合わせて要素も移動しました。

おかしい挙動
クリックする(例えばノート内の座標:(x:30,y:30)をクリック)
その後に少し離れた場所の要素に触れると(mousemove)、クリックした場所の座標に瞬間的に移動する。

宜しくお願い致します。

document.addEventListener('mousedown', (event) => {
document.addEventListener('mousemove', (e) => {
let t = e.target;
if (t.nodeName == 'TEXTAREA') {
var clickX = event.pageX;
var clickY = event.pageY;

var clientRect = target.getBoundingClientRect();
var positionX = clientRect.left + window.pageXOffset;
var positionY = clientRect.top + window.pageYOffset;

var x = clickX - positionX;
var y = clickY - positionY;

t.style.left = x + "px";
t.style.top = y + "px";
}
});
});

お礼日時:2021/02/11 15:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!