Hatena::Groupjavascript

JavaScriptで遊ぶよ

 | 

2011-02-13

クリック直下の単語を取得

07:29

デモ。クリック直下の単語を選択してアラートする。


元ネタ→ javascript - Creating a collapsed range from a pixel position in FF/Webkit - Stack Overflow

DOM 標準には document.caretRangeFromPoint というメソッドがあり、座標から collapsed range を得ることができる。ただし WebKit しか実装してないらしい。

Firefox はマウスイベントの rangeParent と rangeOffset というガラパゴスプロパティがある。

組み合わせるとこんな感じ。

    document.addEventListener('click', function onclick(e) {
      var r;
      if (document.caretRangeFromPoint) { // standard (WebKit)
        r = document.caretRangeFromPoint(e.pageX, e.pageY);
      } else if (e.rangeParent) { // Mozilla
        r = document.createRange();
        r.setStart(e.rangeParent, e.rangeOffset);
      }

      var t = r.startContainer; // should be a text node
      var s = r.startOffset; // number of chars from the start of text
      var e = s;

      while (s > 0) {
        s -= 1;
        r.setStart(t, s);
        if (/^\s/.test(r.toString())) {
          r.setStart(t, s += 1);
          break;
        }
      }
      var l = t.nodeValue.length;
      while (e < l) {
        e += 1;
        r.setEnd(t, e);
        if (/\s$/.test(r.toString())) {
          r.setEnd(t, e -= 1);
          break;
        }
      }

      window.getSelection().addRange(r);
      alert(r.toString());

    }, false);

IE は textRange.moveToPoint というメソッドがある。

同様のコード。

    document.attachEvent('onclick', function onclick(e) {
      if (!e) e = window.event;
      if (document.selection && document.selection.createRange) {
        var r = document.selection.createRange();
        r.moveToPoint(e.x, e.y);

        r.moveStart('word', -1);
        if (/^\s/.test(r.text)) r.moveStart('character', 1);
        r.moveEnd('word', 1);
        if (/\s$/.test(r.text)) r.moveEnd('character', -1);

        r.select();

        alert(r.text);
      }
    });

[JavaScript] IE8でのTextRange.moveToPoint() - @・ェ・)やるっきゃない とかあったけど↑で動いてるっぽいので放置。


Opera は無理。document.caretRangeFromPoint も無いし、range.getClientRects とかも無いので、座標と range を結びつけることができない。テキストノードを <span> に細切れにしておくぐらいしか方法が無さそう。

トラックバック - http://javascript.g.hatena.ne.jp/edvakf/20110213
 |