2011-10-07 9 views
5

ルコード: http://jsfiddle.net/frf7w/12/Javascript:htmlタグに基づいてユーザー選択を拡張するにはどうすればよいですか?

だから、今、現在の方法は、選択したとおりに...選択したテキストを取り、それが表示されたときに、ページが爆破しないようにタグを追加します。

しかし、私がしたいこと:これは、ユーザーがページの一部を選択したときに、選択範囲内に一致しないタグがある場合、その選択は前方一致または後方一致(不一致タグ選択に有効なHTMLを選択させるタグに変更します。

私がこれをやりたい理由は、ユーザーがページ上でテキストを選択できるようにし、そのテキストをWYSIWYGエディタで編集できるようにするためです(リンクされたコードでこれを行うことができます)、そして編集したものをページに戻します(私が使用するメソッドはタグを追加するので、現在はこれを行うことはできません)。

+0

私はあなたの選択肢の周りにdivを追加していますが、それが追加されると、このdivの親を取得してからそれを選択できると思いますか?しかし、あなたは奇妙な行動に終わるかもしれません。 – boulaycote

+0

divは、選択したテキストを表示するためのものです。選択されたテキスト自体にdivが追加されていません。 = \ – NullVoxPopuli

+0

したがって、そのdivの親を選択すると、おそらくページ全体が選択されます。 – NullVoxPopuli

答えて

2

を含むスパンであなたの選択の要素を囲むことができます。

var sel = window.getSelection(), 
    range = sel.getRangeAt(0); 

var startEl = sel.anchorNode; 
if (startEl != range.commonAncestorContainer) { 
    while (startEl.parentNode != range.commonAncestorContainer) { 
     startEl = startEl.parentNode; 
    } 
} 
var endEl = sel.focusNode; 
if (endEl != range.commonAncestorContainer) { 
    while (endEl.parentNode != range.commonAncestorContainer) { 
     endEl = endEl.parentNode; 
    } 
} 

range.setStartBefore(startEl); 
range.setEndAfter(endEl); 

sel.addRange(range); 

上記の例をあなたのカバーに拡張された選択を提供します開始ノードと終了ノードの間のツリーの全体です(commonAncestorContainer()のおかげで)。

これはテキストノードをdom要素と等しく扱いますが、これは問題ではありません。

デモ:http://jsfiddle.net/Nq6hr/2/

+0

は、このクロスブラウザーです(IE7 +以降、実際のブラウザーと同様です)。 – NullVoxPopuli

+1

Chrome 14、FF7、IE9でテストしました。私はIEのバージョン9 – Deebster

+0

の 'range'オブジェクトをサポートしていると思います。私の上司に顧客にアップグレードするために提案する別の理由を与えるための言い訳を与えるだろう= D – NullVoxPopuli

0

選択したノードで作業する必要があります。それはextentNodeとanchorNodeは終わりを表し、選択のノードの始まりは両方ともあなたが "完全な"選択を持つのを助けることができるようです。 https://developer.mozilla.org/fr/DOM/Selection

インライン編集では、contentEditable属性を試してください。あなたはadding a rangeによって選択範囲の境界線を変更することができ、この属性にhttps://developer.mozilla.org/en/DOM/element.contentEditable

3

このSOの答えでcoverAll方法は、あなたがUse javascript to extend a DOM Range to cover partially selected nodesたい正確に何があります。何らかの理由でSelectionプロトタイプが私のクロームで私にとってうまくいかないので、コードを抽出してthiswindow.getSelection()に置き換えました。最終的なコードは次のようになります:

function coverAll() { 
    var ranges = []; 
    for(var i=0; i<window.getSelection().rangeCount; i++) { 
     var range = window.getSelection().getRangeAt(i); 
     while(range.startContainer.nodeType == 3 
       || range.startContainer.childNodes.length == 1) 
      range.setStartBefore(range.startContainer); 
     while(range.endContainer.nodeType == 3 
       || range.endContainer.childNodes.length == 1) 
      range.setEndAfter(range.endContainer); 
     ranges.push(range); 
    } 
    window.getSelection().removeAllRanges(); 
    for(var i=0; i<ranges.length; i++) { 
     window.getSelection().addRange(ranges[i]); 
    } 
    return; 
}
関連する問題