69763


contenteditableを指定したdivの中にある文字列を選択状態にして、見出しボタンを押したときに見出しタグで挟んだ文字列を返すという処理をしたいです。

buttonが押されたときにselectionオブジェクトを取得してしまうと、buttonを押した時点の状態が取得されてしまうので、.text_bodyでmouseupされたときだけグローバル変数のselectionにselectionオブジェクトを入れて、buttonが押されたときにselectionを利用する形にすればいけると思ったのですが、ダメでした。

どうすれば.text_bodyで選択した状態のselectionオブジェクトを取得できるでしょうか。よろしくお願いいたします。

[code]

    var selection = null;
    document.querySelector('.text_body').addEventListener('mouseup', function(){
      selection = window.getSelection();
    } )
    document.querySelector('button').addEventListener('click', function(){
      document.querySelector('.result').textContent = selection.rangeCount + ', ' + selection.isCollapsed;
    })
[/code]

[code]

    .text_body {
      width : 300px;
      height : 60px;
      border : 1px solid black;
    }
[/code]

[code]

    <div class="text_body" contenteditable>JavaScrip Ruby PHP</div>
    <button type='button'>見出し</button>
    <div class="result"></div>
[/code]


CC BY-SA 4.0
2020-08-21T07:40:58.543
69756
2020-08-27T00:46:36.813
2020-08-26T22:05:30.510
32180
32180
question
javascript
getselection contenteditable 特定のdiv内でユーザーが選択した範囲を取得する


> どうすれば.text_bodyで選択した状態のselectionオブジェクトを取得できるでしょうか。よろしくお願いいたします。

# IDによる制御

ここでは、ユーザーの選択した文字列を取得するために、[window.getSelection()](https://developer.mozilla.org/en-
US/docs/Web/API/Window/getSelection)を使用しています。[window.getSelection()](https://developer.mozilla.org/en-
US/docs/Web/API/Window/getSelection)をそのまま使うとユーザーが選択した箇所であればどこでも取得できてしまうため、特定の`div`といったように取得箇所を限定したいのであれば、なにかしらの仕組みで特定`div`以外の場合は反応しないようにしなければなりません。

クラスではなくIDになってしまいますが、IDだと下記の方法でできました。  
参考資料: [javascript - How to getSelection() within a specific div? - Stack
Overflow](https://stackoverflow.com/questions/38758713/how-to-getselection-
within-a-specific-div) の [回答](https://stackoverflow.com/a/38758990/1979953)

[code]

    <html>
    <head>
    <script>
    function hoge(){
      if(window.getSelection().baseNode.parentNode.id != "foo") return;
      alert(window.getSelection());
    }
    </script>
    </head>
    <body>
      aaaa
      <div id="foo">JavaScrip Ruby PHP</div>
      <button type='button' onclick="hoge()">見出し</button>
      <div class="result"></div>
    </body>
    </html>
    
[/code]

## ちなみに

ちょっと遭遇していないので、どういう現象かわかってないですが  
[javascript - How to getSelection() within a specific div? - Stack
Overflow](https://stackoverflow.com/questions/38758713/how-to-getselection-
within-a-specific-div) の [回答](https://stackoverflow.com/a/38758990/1979953)  
のコメント部にある

> You may have to recursively check the parentNode until you reach the body as
> the contenteditable will create multiple tags in different hierarchy.

> @z0mBi3 Good point, since this is just a "highlight once" thing it would
> work. I'd advise OP to use jQuery's .closest() function. I'll mention that
> in a edit.

も気にしたほうがいいかもしれません。このコメントを受けて回答にjQueryによる解法が付け加えられています。その`if文`を書き換えた方法は下記のようです。

引用:

[code]

    if($(window.getSelection().baseNode).closest("#foo").attr("id") != "foo") return;
    
[/code]

# テキストエリアの場合

特定のテキストエリア（`selectionStart`と`selectionEnd`が使える要素と言ったほうがいいかもしれない）でよいなら下記の方法もありました。テキストエリアであれば、[window.getSelection()](https://developer.mozilla.org/en-
US/docs/Web/API/Window/getSelection)を使わないですみます。

[javascript - HTML5 how to get selected text out of a textarea - Stack
Overflow](https://stackoverflow.com/questions/23021645/html5-how-to-get-
selected-text-out-of-a-textarea) の
[回答](https://stackoverflow.com/a/23027596/1979953)

念のためにテキストエリア版で重要そうなところを引用しておきます。

[code]

    var textarea = document.getElementById("textArea");  
    var selection = (textarea.value).substring(textarea.selectionStart,textarea.selectionEnd);
    alert (selection);
    
[/code]

## 追記: contenteditableの場合

[contenteditable](https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Editable_content)ですが、質問者さんは、`<div
class="text_body"
contenteditable>`と書かれていますが、`true`もしくは`false`を与える必要があると思います（もしくは私が知らないだけで省略可能？）下記のように
textareaと同様にいけるかと思い試してみたが、クロームで試してみたところ **駄目でした** 。  
[jquery - selectionStart and selectionEnd in contenteditable element - Stack
Overflow](https://stackoverflow.com/questions/19288700/selectionstart-and-
selectionend-in-contenteditable-element) に`contenteditable`
を使った質問がありましたが、`getSelection`の回答しか載っておらず、特別によさそうな方法が **ありませんでした** 。

**駄目だった例** :

[code]

    <html>
    <head>
    <script>
    function hoge(){
      var contenteditableAria = document.getElementById("foo");  
      var selection = (contenteditableAria.value).substring(contenteditableAria.selectionStart,contenteditableAria.selectionEnd);
      alert (selection);
    }
    </script>
    </head>
    <body>
      <div id="foo" contenteditable="true">JavaScrip Ruby PHP</div>
      <button type='button' onclick="hoge()">見出し</button>
      <div class="result"></div>
    </body>
    </html>
    
[/code]


CC BY-SA 4.0
2020-08-21T12:04:02.130
69763
2020-08-27T00:46:36.813
2020-08-27T00:46:36.813
9008
9008
69756
answer