![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_13.png?5a7ff87)
オブジェクトがありませんとエラーが出てしまいます。
operaやNetscapeは動くようなのですがIEは動きません。
document.getElementById(target).style.top = y-offx+"px";
の部分でエラーがでるようなのですが。
出さないためにどうすれば良いかが、分かりません。
よろしくお願いします。
<html>
<head>
<title>ドラッグして移動する</title>
<script type="text/javascript"><!--
if(window.addEventListener)window.addEventListener("load",loadScript,false);
if(window.attachEvent)window.attachEvent("onload",loadScript);
//関数ロード
function loadScript(){
///ドラッグ用ロード
flag=false;
Menu=new Array("menu1","menu2","menu3");
for(i=0;i<Menu.length;i++){
XMenu=window.document.getElementById(Menu[i])
if(XMenu.addEventListener)XMenu.addEventListener("mousedown",dragOn,false);
if(XMenu.attachEvent)XMenu.attachEvent("onmousedown",dragOn);
}
}
//ドラッグ関数
function dragOn(){
flag=true;
target=this.id;
///移動
if(window.document.addEventListener)window.document.addEventListener("mousemove",dragMove,false);
if(window.document.attachEvent)window.document.attachEvent("onmousemove",dragMove);
///終了
if(window.document.addEventListener)window.document.addEventListener("mouseup",dragOff,false);
if(window.document.attachEvent)window.document.attachEvent("onmouseup",dragOff);
}
function dragMove(evt){
if (!flag) return;
if (window.createPopup){
x = event.x + document.body.scrollLeft;
y = event.y + document.body.scrollTop;
}else{
x = evt.pageX;
y = evt.pageY;
}
offx = 60;
offy = 75;
document.getElementById(target).style.top = y-offx+"px";document.getElementById(target).style.left = x-offy+"px";return false;
}
function dragOff(){flag=false;}
// --></script></head>
<body>
<!-- 各メニューで自分自身をドラッグ開始するように,関数を呼ぶ -->
<div id="menu1" style="background-color:red; position:absolute; width:120px;height:150px;" >メニュー1</div>
<div id="menu2" style="background-color:green; position:absolute;top:200px;width:120px;height:150px;" >メニュー2</div>
<div id="menu3" style="background-color:blue; position:absolute;top:400px;width:120px;height:150px;">メニュー3</div>
<div id="menu4" style="background-color:yellow; position:absolute;top:200px; left:200px;width:120px;height:150px;">メニュー4</div>
</body>
</html>
No.5ベストアンサー
- 回答日時:
ふと気づいたので。
<html>
<head>
<title>ドラッグして移動する</title>
<script type="text/javascript"><!--
function addMyEvent(obj,type,func){
if(window.addEventListener){ obj.addEventListener(type, func, false) }
else{ if(window.attachEvent) obj.attachEvent("on"+type, func) }
}
addMyEvent(window,'load',function(){
var T = null, oW, oH;
addMyEvent(document,'mousedown',function(e){
if((o = e.target || e.srcElement).className == 'move')
T=o; oW = o.offsetWidth/2; oH = o.offsetHeight/2;
});
addMyEvent(document,'mouseup', function(){ T = null });
addMyEvent(document,'mousemove',function(e){
if(!T) return;
T.style.top = pos('scrollTop', e.clientY, oH),
T.style.left = pos('scrollLeft', e.clientX, oW);
});
function pos(a,b,c){ return b - c + (document.body[a] || document.documentElement[a]) +"px" }
});
// --></script></head>
<body>
<div id="menu1" class="move" style="background-color:red; position:absolute; width:120px;height:150px;" >メニュー1</div>
<div id="menu2" class="move" style="background-color:green; position:absolute;top:200px;width:120px;height:150px;" >メニュー2</div>
<div id="menu3" class="move" style="background-color:blue; position:absolute;top:400px;width:120px;height:150px;">メニュー3</div>
<div id="menu4" style="background-color:yellow; position:absolute;top:200px; left:200px;width:120px;height:150px;">メニュー4</div>
</body>
</html>
#4で書いた事と、可動メニューにクラス名をつけてマウスダウン監視をdocumnetに変更。
クラス名チェックで一致したら起動。
これでfor文が消せたので見方によってはすこしすっきりですかね?
御丁寧にありがとうございました。
とてつもなく勉強になりました。
質問外の質問にも解説付きで書いていただき、
勉強になります。
すごいです。目からウロコです。
質問して良かったです。
回答していただけたことに、
感謝致します。
ありがとうございました。
No.4
- 回答日時:
いえいえ、いつも何か抜けてるので恥ずかしい限りです^^;
私が普段書く感じだと#3でもう最終です。
1年経ってすっかり忘れてから見直しても楽に流れを追える程度で止めていますから。
これ以上無理も含めてやるとしたら、
■変数X,Yは整理用の不要な変数ですから
target.style.top = e.clientY - oH + (document.body.scrollTop || document.documentElement.scrollTop) + "px";
としてしまう。
■配列がソート処理や順番が関係ないケースなので for文は for(var i in Menu) でもOKです。
■関数名などを簡略化して文字数を減らす
エディタなどを使ってるならaddMyEventの様に意味まで含めた長い名前にしなくても追いやすいですからね。
他にスクリプトやライブラリがあるならグローバル変数・関数は短い名前だと干渉する確率が高くなるので逆に良くないですけど。
documentと言うのも良く出てくるので、ローカルでvar D = documentにして短くしちゃう事もあります。
■document.body.scrollTop || document.documentElement.scrollTop のどちらか理解できる方と言う記述
DOCTYPEをつけない(必ずつけるべき といわれていますけどw)とか、特定のブラウザ専用なら
どちらか片方だけにできるかもしれないので、テストして可能ならそうします。
DOCTYPEがない場合は document.body.scrollTop だけでIE、Firefox、Netscape、Safari、Operaでもきちんと動きます。
DOCTYPEをつけると「NetscapeやSafari」と「IEやFirefox」とで方法が分かれてくるので変更はしない方が良いと思います。Operaは両方理解できます。
また長い記述が気持ち悪い場合は、好みによって
addMyEvent(document,'mousemove',function(e){
if(!target) return;
var t=target.style;
t.top = pos('scrollTop', e.clientY, oH);
t.left = pos('scrollLeft', e.clientX, oW);
});
function pos(a,b,c){ return b - c + (document.body[a] || document.documentElement[a]) +"px" }
とかですかね。
ただ、これらは処理が短くなるとか速くなるとかではなく記述上の好み?みたいなレベルだと思います。これらをやる事で何か得した気分になる時くらいしかやらないです。^^;
最後のposの様に関数化すると返って処理が遅くなる(といっても人が感じるレベルではない)場合があるので、
mousemoveのような連続して処理が発生し続ける場合は関数化しない事も1つの選択方法です。
他の人なら、もっとこうすれば簡単になるってのをすぐ見つけられるかもしれないですよ。
その時々で脳が一方向だけ向いてしまうので時間が経つと「この処理無駄だな」とか出てくる時もありますし。
と、こんな感じです^^;
No.3
- 回答日時:
<html>
<head>
<title>ドラッグして移動する</title>
<script type="text/javascript"><!--
/* add event 共用関数 */
function addMyEvent(obj,type,func){
if(window.addEventListener){ obj.addEventListener(type, func, false) }
else{ if(window.attachEvent) obj.attachEvent("on"+type, func) }
}
/* windowにonloadイベントをaddして、関数は全部その中に */
addMyEvent(window,'load',function(){
var target = null; //操作対象の有無をフラグ代わり
var oW, oH; //可動メニューの幅と高さを入れる変数
var Menu = ["menu1","menu2","menu3"]; //new Array(A,B,C)と同じ※空要素は禁止
for(var i=0; i<Menu.length; i++){
var XMenu = document.getElementById(Menu[i]);
addMyEvent(XMenu,'mousedown',function(o){ return function(){ target=o; oW = o.offsetWidth/2; oH = o.offsetHeight/2; }}(XMenu));
}
addMyEvent(document,'mouseup', function(){ target = null });
addMyEvent(document,'mousemove',function(e){
if(!target) return;
var Y = e.clientY - oH + (document.body.scrollTop || document.documentElement.scrollTop);
var X = e.clientX - oW + (document.body.scrollLeft || document.documentElement.scrollLeft);
target.style.top = Y + "px";
target.style.left = X + "px";
});
});
// --></script></head>
<body>
<div id="menu1" style="background-color:red; position:absolute; width:120px;height:150px;" >メニュー1</div>
<div id="menu2" style="background-color:green; position:absolute;top:200px;width:120px;height:150px;" >メニュー2</div>
<div id="menu3" style="background-color:blue; position:absolute;top:400px;width:120px;height:150px;">メニュー3</div>
<div id="menu4" style="background-color:yellow; position:absolute;top:200px; left:200px;width:120px;height:150px;">メニュー4</div>
</body>
</html>
スクロールがある場合の処理も入れておかねばいけなかったですね。
ある程度まとめても理解しづらくない?と思うのでまた少し丸めました。
インデントつけないと見辛いかも^^;
何回も書き込んでくださり、ありがとうございました。
段階的に書いてくださったおかげで違いがわかりやすかったです。
みごとに動きました。
おかげさまで解決しました。
質問外の質問になるかもしれないのですが、
「ある程度まとめても理解しづらくない」
「もう少し丸め込む事できますが」
とありますが、これ以上まとめることなどできるものなのでしょうか。
No.2
- 回答日時:
さっそく訂正^^;
マウスアップ、マウスムーブのイベント付加はオンロード関数の中に入れるべきですね。
<html>
<head>
<title>ドラッグして移動する</title>
<script type="text/javascript"><!--
/* 何度も使うので関数化 */
function addMyEvent(obj,type,func){
if(window.addEventListener){ obj.addEventListener(type, func, false) }
else{ if(window.attachEvent) obj.attachEvent("on"+type, func); }
}
/* windowにonloadイベント付加 */
addMyEvent(window,'load',loadScript);
/* 呼ばれる関数 */
function loadScript(){
flag=false;
var Menu = new Array("menu1","menu2","menu3");
for(i=0;i<Menu.length;i++){
var XMenu = document.getElementById(Menu[i]);
/* 各menuにマウスダウンイベント付加と、thisにあたるオブジェクト渡し */
addMyEvent(XMenu,'mousedown',function(o){ return function(){ dragOn(o) } }(XMenu) );
}
/*
マウスアップ、マウスムーブは 何度もイベントを作るのは変なので
dragOn関数にいれずにドキュメントへのイベント付加を1度だけ実行
*/
addMyEvent(document,'mouseup',function(){ flag=false; });
addMyEvent(document,'mousemove',dragMove);
}
//ドラッグ関数
function dragOn(el){
flag=true;
target=el;
}
function dragMove(evt){
if (!flag) return;
x = evt.clientX - 60;
y = evt.clientY -75;
target.style.top = y+"px";
target.style.left = x +"px";
}
// --></script></head>
<body>
<!-- 各メニューで自分自身をドラッグ開始するように,関数を呼ぶ -->
<div id="menu1" style="background-color:red; position:absolute; width:120px;height:150px;" >メニュー1</div>
<div id="menu2" style="background-color:green; position:absolute;top:200px;width:120px;height:150px;" >メニュー2</div>
<div id="menu3" style="background-color:blue; position:absolute;top:400px;width:120px;height:150px;">メニュー3</div>
<div id="menu4" style="background-color:yellow; position:absolute;top:200px; left:200px;width:120px;height:150px;">メニュー4</div>
</body>
</html>
No.1
- 回答日時:
前にサンプルで貰った物からイベントの付加をメソッドを使った方法に変えたようですね。
メソッドを使う方法にすると、呼ばれた関数内のでのthis の意味がIEの場合は変ってしまうのでオブジェクト不明になってるんだと思います。
ちょっと重複する指示などもあったので、もう少しスクリプトを丸めておきました。
もう少し丸め込む事できますが、この状態なら理解もしやすいかと。
(ミスもあるかもしれません)
<html>
<head>
<title>ドラッグして移動する</title>
<script type="text/javascript"><!--
/* 何度も使うので関数化 */
function addMyEvent(obj,type,func){
if(window.addEventListener){ obj.addEventListener(type, func, false) }
else{ if(window.attachEvent) obj.attachEvent("on"+type, func); }
}
/* windowにonloadイベント付加 */
addMyEvent(window,'load',loadScript);
/* 呼ばれる関数 */
function loadScript(){
flag=false;
var Menu = new Array("menu1","menu2","menu3");
for(i=0;i<Menu.length;i++){
var XMenu = document.getElementById(Menu[i]);
/* 各menuにマウスダウンイベント付加と、thisにあたるオブジェクト渡し */
addMyEvent(XMenu,'mousedown',function(o){ return function(){ dragOn(o) } }(XMenu) );
}
}
/*
マウスアップ、マウスムーブは 何度もイベントを作るのは変なので
dragOn関数にいれずにドキュメントへのイベント付加を1度だけ実行
*/
addMyEvent(document,'mouseup',function(){ flag=false; });
addMyEvent(document,'mousemove',dragMove);
//ドラッグ関数
function dragOn(el){
flag=true;
target=el;
}
function dragMove(evt){
if (!flag) return;
x = evt.clientX - 60;
y = evt.clientY -75;
target.style.top = y+"px";
target.style.left = x +"px";
}
// --></script></head>
<body>
<!-- 各メニューで自分自身をドラッグ開始するように,関数を呼ぶ -->
<div id="menu1" style="background-color:red; position:absolute; width:120px;height:150px;" >メニュー1</div>
<div id="menu2" style="background-color:green; position:absolute;top:200px;width:120px;height:150px;" >メニュー2</div>
<div id="menu3" style="background-color:blue; position:absolute;top:400px;width:120px;height:150px;">メニュー3</div>
<div id="menu4" style="background-color:yellow; position:absolute;top:200px; left:200px;width:120px;height:150px;">メニュー4</div>
</body>
</html>
これで希望通り動きますか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- JavaScript vertical sliderをautoplayしたい 2 2022/08/25 14:47
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/30 09:10
- JavaScript スマフォではボタンを表示させたくない 2 2023/01/20 14:26
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- HTML・CSS html/cssで要素が出てこなくて困ってます 1 2022/12/31 16:59
- HTML・CSS cssが効かなくて困ってます 1 2023/01/01 23:57
- HTML・CSS 書籍を見つつサイト造りの練習をしているのですが、見た目が一致しません 2 2022/11/28 15:00
- JavaScript コードレビューをお願いします。 1 2022/07/16 05:38
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ActiveXobjectが作成できない
-
「nullまたはオブジェクトでは...
-
javascript 特定のタグのidの存...
-
任意の座標をクリックさせるには
-
<a>タグのテキストを取得
-
配列の大括弧と丸括弧はどう違う?
-
div要素内の全input要素をdisable
-
javascript 作成した要素にCS...
-
javascript画面を自動で切り替...
-
JavaScriptのストップウォッチ...
-
DOMMouseScrollを使って特定のI...
-
JavaScriptによるundefined判定...
-
javascriptでスロットゲームを...
-
javascriptで編集可能不可能の...
-
javascript の 命令文の記述で...
-
google apps scriptの終了のさせ方
-
翌月を取得するGASが分かりません
-
GASでundefinedエラーが出ます
-
functionから別のfunctionを実...
-
関数でy=g(x)のgとは何の略です...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
<a>タグのテキストを取得
-
ActiveXobjectが作成できない
-
innerHTML実行後のイベント
-
任意の座標をクリックさせるには
-
javascript 特定のタグのidの存...
-
onchangeイベントを使ってspan...
-
HTML:Tableタグに対し、JavaScr...
-
モーダルダイアログウィンドウ...
-
日本語入力の禁止
-
javascriptでCSVを呼出しvlookup
-
Click回数を数え、規定された回...
-
画像上のクリックした場所が分...
-
【Tabキー】特定の範囲内だけで...
-
配列の大括弧と丸括弧はどう違う?
-
重複しないくじの作り方がわか...
-
javascriptで、表示されている...
-
div要素内の全input要素をdisable
-
javascriptであるボタンを押す...
-
javascriptで自動計算フォーム...
-
RadioButtonListの表示制御
おすすめ情報