none
IE8、JavaScriptエラーについて(moveToPoint、未定義のエラー) RRS feed

  • 質問

  • IE8でmoveToPointを実行すると、「未定義のエラー」が出てしまいます。

    msdnの以下のサンプルを使っても、同様のエラーが出ました。
    http://msdn.microsoft.com/ja-jp/library/cc428110.aspx

    <SCRIPT FOR=document EVENT=onclick LANGUAGE="JScript">
    var rng = document.body.createTextRange(
    );
    rng.moveToPoint(window.event.x, window.event.y);
    rng.expand("word");
    rng.select();
    </SCRIPT>

    どなたか解決方法をアドバイスいただけないでしょうか。
    よろしくお願いいたします。
    2009年9月20日 16:12

回答

  • 再現しました(`・ω・´)

    こちらが調査したところ、エラーが発生する条件は、
    「直下の子要素にテキストノードが存在しないこと」だと思いました。
    (子孫要素でも許すはずですが、BODYとかでもエラーが発生するのでよく分かりません)

    なので、HRタグやinput type=textが存在する位置に対して、
    moveToPointすると例外(未定義のエラー)が発生するようになっているようです。
    逆に普通のテキスト上でクリックしてもこちらはエラーになりませんでした。
    エラー(例外)が発生するのは当たり前のI/Fのようですので、try cacheでくくってあげるとよいと思います。

    試しにyahooのトップページで以下のスクリプトを動かしたところ、
    約76%の確率(489280/640000)でエラーとなりました。

    var count = 0;
    var rng = document.body.createTextRange();
    for(var i = 0; i < 800; i++){
      for(var j = 0; j< 800; j++){
    	try {
    	rng.moveToPoint(i, j);
    	} catch(e){
    		count++;
    	}
      }
    }
    alert(count)
    • 回答としてマーク 服部清次 2009年10月8日 7:33
    2009年9月22日 9:11

すべての返信

  • 現在、未確認ですが、moveToPointかどうかは忘れましたが、
    IEのrangeオブジェクトのselect()は先頭文字(または要素)、または末尾(または要素)が
    見えない領域(display:none)となっている場合に
    うまく動作しなかったと思います。(少なくともIE7までは)
    ただし、visibility:hiddenや要素サイズの大きさを超えてクリップされた場合であれば動作したと思います。
    display:noneだとしても、開始地点と終了地点に囲まれた中に見えない領域(display:none)が存在するのであれば、エラーにならなかったと思います。

    つまり、expand("word")で単語の範囲に広げたときに、末尾や先頭が見えていなければいけません。
    エラーになる個所のoverflow指定などはどうなっています?
    2009年9月22日 7:47
  • 再現しました(`・ω・´)

    こちらが調査したところ、エラーが発生する条件は、
    「直下の子要素にテキストノードが存在しないこと」だと思いました。
    (子孫要素でも許すはずですが、BODYとかでもエラーが発生するのでよく分かりません)

    なので、HRタグやinput type=textが存在する位置に対して、
    moveToPointすると例外(未定義のエラー)が発生するようになっているようです。
    逆に普通のテキスト上でクリックしてもこちらはエラーになりませんでした。
    エラー(例外)が発生するのは当たり前のI/Fのようですので、try cacheでくくってあげるとよいと思います。

    試しにyahooのトップページで以下のスクリプトを動かしたところ、
    約76%の確率(489280/640000)でエラーとなりました。

    var count = 0;
    var rng = document.body.createTextRange();
    for(var i = 0; i < 800; i++){
      for(var j = 0; j< 800; j++){
    	try {
    	rng.moveToPoint(i, j);
    	} catch(e){
    		count++;
    	}
      }
    }
    alert(count)
    • 回答としてマーク 服部清次 2009年10月8日 7:33
    2009年9月22日 9:11
  • ご回答ありがとうございます。
    大変参考になりました。

    結局、仕様ということですね。。
    moveToPoint以外の方法を模索したいと思います。


    2009年9月24日 3:05
  • すず吉 さん、

    こんにちは!
    フォーラム オペレーターの服部 清次です。

    今回、(´・ω・`) さんの回答が参考になったようですので、私の方で [回答としてマーク] のチェックを付けさせていただきました。
    すず吉 さんと同じ疑問を持たれた他の方々にも、ぜひこちらの情報を参照していただきたいと思いますので。 (^^)

    また何か困ったことがありましたら、ぜひ TechNet フォーラムをご利用ください。
    今後とも、TechNet フォーラムをよろしくお願いします。
    それでは、また! (^_^)/


    __________________________________________________
    マイクロソフト株式会社 フォーラム オペレーター 服部 清次

    2009年10月8日 7:35