

オブジェクトがありませんとエラーが出てしまいます。
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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ActiveXobjectが作成できない
-
javascriptで編集可能不可能の...
-
「nullまたはオブジェクトでは...
-
javascriptを使ったページ内の...
-
重複しないくじの作り方がわか...
-
onclickを使わずにイベント処理...
-
innerHTML実行後のイベント
-
onchangeイベントを使ってspan...
-
C#OpenCv V4にのエラーに関する...
-
jspからjavascriptの変数引継ぎ
-
jslintのエラーについて質問
-
同じ型【ハイフンと数字】だけ...
-
JavaScriptで平日のみをカウン...
-
問題の個数を数える。
-
HTTPSのとき":"が"%3A"ではなく...
-
同じIDで定義した要素の配列を...
-
ローカルにあるファイルを検索...
-
四肢麻痺の娘のパソコンの使い方
-
C#テキストボックスの文字を配...
-
極小コードに挑戦!part2 数列...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ActiveXobjectが作成できない
-
<a>タグのテキストを取得
-
onchangeイベントを使ってspan...
-
appendChildがieだとできない??
-
innerHTML実行後のイベント
-
RadioButtonListの表示制御
-
onclickとonkeypressの重複
-
【Tabキー】特定の範囲内だけで...
-
javascript 特定のタグのidの存...
-
javascriptで編集可能不可能の...
-
配列の大括弧と丸括弧はどう違う?
-
画像上のクリックした場所が分...
-
WordPressのコンタクトフォーム...
-
div要素内の全input要素をdisable
-
IE8でdivのcontenteditable=tru...
-
「nullまたはオブジェクトでは...
-
問題はbind の付いたリスナーを...
-
画像の一部を表示
-
日本語入力の禁止
-
javascriptでCSVを呼出しvlookup
おすすめ情報