Виділіть весь текст DIV одним натисканням миші


136

Як виділити / вибрати вміст тегу DIV, коли користувач натискає на DIV ... ідея полягає в тому, що весь текст виділяється / вибирається, тому користувачеві не потрібно вручну виділяти текст мишею та потенційно пропустіть трохи тексту?

Наприклад, скажімо, що у нас є DIV, як показано нижче:

<div id="selectable">http://example.com/page.htm</div>

... і коли користувач натискає будь-яку з цієї URL-адреси, виділяється весь текст URL-адреси, щоб вони могли легко перетягнути вибраний текст навколо у браузері або скопіювати повну URL-адресу правою кнопкою миші.

Дякую!

Відповіді:


194

function selectText(containerid) {
    if (document.selection) { // IE
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(containerid));
        range.select();
    } else if (window.getSelection) {
        var range = document.createRange();
        range.selectNode(document.getElementById(containerid));
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(range);
    }
}
<div id="selectable" onclick="selectText('selectable')">http://example.com/page.htm</div>

Тепер вам потрібно передавати ідентифікатор як аргумент, який у даному випадку є "вибір", але він більш глобальний, що дозволяє вам використовувати його де завгодно разів без використання, як згадував чіборг, jQuery.


8
До речі, ви можете легко перетворити це в обробник подій JQuery клік замінює document.getElementById('selectable')з this. Тоді ви можете ненав’язливо додати функціональність до декількох елементів, наприклад декількох дівів у контейнері: jQuery('#selectcontainer div').click(selectText);
chiborg

3
Це чудово працює у Chrome, FF, Safari (Mac) та Chrome та IE (Windows 9+, 8 не перевірено). Але це, здається, не працює на Safari на iPad Mini (iOS6) або на iPhone 4, не впевнений в інших iOS або Android.
прототип

1
Згідно з цією статтею, запит if (window.getSelection) {повинен бути першим для Opera ( quirksmode.org/dom/range_intro.html )
прототип

1
Це рішення, здається, не працює в ie11. Будь-яка ідея чому?
Швейцарський містер

5
У Chrome версії 36+ це призведе до помилки "Неперервний вибір не підтримується". Рішення полягає в тому, щоб додати window.getSelection().removeAllRanges();ранішеwindow.getSelection().addRange(range);
nHaskins

122

ОНОВЛЕННЯ 2017:

Щоб вибрати виклик вмісту вузла:

window.getSelection().selectAllChildren(
    document.getElementById(id)
);

Це працює у всіх сучасних браузерах, включаючи IE9 + (у стандартному режимі).

Приклад виконання:

function select(id) {
  window.getSelection()
    .selectAllChildren(
      document.getElementById("target-div") 
    );
}
#outer-div  { padding: 1rem; background-color: #fff0f0; }
#target-div { padding: 1rem; background-color: #f0fff0; }
button      { margin: 1rem; }
<div id="outer-div">
  <div id="target-div">
    Some content for the 
    <br>Target DIV
  </div>
</div>

<button onclick="select(id);">Click to SELECT Contents of #target-div</button>


Оригінальна відповідь, наведена нижче, застаріла, оскільки window.getSelection().addRange(range); застаріла

Оригінальний відповідь:

Усі наведені вище приклади використовують:

    var range = document.createRange();
    range.selectNode( ... );

але проблема в тому, що він вибирає сам Вузол, включаючи тег DIV і т.д.

Щоб вибрати текст Вузла відповідно до питання щодо ОП, вам потрібно зателефонувати:

    range.selectNodeContents( ... )

Отже, повний фрагмент буде таким:

    function selectText( containerid ) {

        var node = document.getElementById( containerid );

        if ( document.selection ) {
            var range = document.body.createTextRange();
            range.moveToElementText( node  );
            range.select();
        } else if ( window.getSelection ) {
            var range = document.createRange();
            range.selectNodeContents( node );
            window.getSelection().removeAllRanges();
            window.getSelection().addRange( range );
        }
    }

Ви також можете використовувати thisзамість того, щоб отримати елемент на основі ідентифікатора, якщо він знаходиться у clickслухачі елемента .
Зак Сосьє,

44

Є чисте рішення CSS4:

.selectable{
    -webkit-touch-callout: all; /* iOS Safari */
    -webkit-user-select: all; /* Safari */
    -khtml-user-select: all; /* Konqueror HTML */
    -moz-user-select: all; /* Firefox */
    -ms-user-select: all; /* Internet Explorer/Edge */
    user-select: all; /* Chrome and Opera */

}

user-select- це специфікація модуля CSS рівня 4, яка наразі є чернеткою та нестандартною властивістю CSS, але браузери її добре підтримують - див. # search = user-select .

Детальніше про користувача виберіть тут на MDN та пограйте з ним тут у w3scools


3
+1 дивовижне дивовижне рішення! Тестований вересень 2017 року, і він працює бездоганно на FireFox та Chrome, АЛЕ НЕ В МІКРОСОФТЕ РЕЖ! Будь-які ідеї, чому б ні, і як це виправити? Дякую!
Сем

13

Відповідь Нейроксика була дуже корисною. У мене були проблеми лише з Chrome, тому що коли я натиснув зовнішній дів, він не працював. Я міг би вирішити це, видаливши старі діапазони, перш ніж додати новий діапазон:

function selectText(containerid) {
    if (document.selection) {
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(containerid));
        range.select();
    } else if (window.getSelection()) {
        var range = document.createRange();
        range.selectNode(document.getElementById(containerid));
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(range);
    }
}
<div id="selectable" onclick="selectText('selectable')">http://example.com/page.htm</div>

9

Для редагування вмісту (не для регулярних входів, вам потрібно використовувати selectNodeContents (а не просто selectNode).

ПРИМІТКА. Усі посилання на "document.selection" і "createTextRange ()" призначені для IE 8 і новіших версій ... Вам, швидше за все, не знадобиться підтримувати цього монстра, якщо ви намагаєтеся зробити такі складні речі.

function selectElemText(elem) {

    //Create a range (a range is a like the selection but invisible)
    var range = document.createRange();

    // Select the entire contents of the element
    range.selectNodeContents(elem);

    // Don't select, just positioning caret:
    // In front 
    // range.collapse();
    // Behind:
    // range.collapse(false);

    // Get the selection object
    var selection = window.getSelection();

    // Remove any current selections
    selection.removeAllRanges();

    // Make the range you have just created the visible selection
    selection.addRange(range);

}

6

Використовуючи поле з текстовим полем, ви можете використовувати це: (Через Google)

<form name="select_all">

    <textarea name="text_area" rows="10" cols="80" 
    onClick="javascript:this.form.text_area.focus();this.form.text_area.select();">

    Text Goes Here 

    </textarea>
</form>

Ось як я бачу, що це робить більшість веб-сайтів. Вони просто стилюють його за допомогою CSS, щоб він не виглядав як текстовий район.


чому не просто this.focus();this.select();?
Taha Paksu

5

Цей фрагмент надає потрібну вам функціональність . Що вам потрібно зробити, це додати подію до цього div, що активує fnSelect у ньому. Швидкий злом, який ви абсолютно не повинні робити і, можливо, може не працювати, виглядатиме так:

document.getElementById("selectable").onclick(function(){
    fnSelect("selectable");
});

Очевидно припускаючи, що зв'язаний фрагмент був включений.


5

Я вважаю корисним перетворити цю функцію на додаток jQuery:

$.fn.selectText = function () {
    return $(this).each(function (index, el) {
        if (document.selection) {
            var range = document.body.createTextRange();
            range.moveToElementText(el);
            range.select();
        } else if (window.getSelection) {
            var range = document.createRange();
            range.selectNode(el);
            window.getSelection().addRange(range);
        }
    });
}

Отже, це стає багаторазовим рішенням. Тоді ви можете зробити це:

<div onclick="$(this).selectText()">http://example.com/page.htm</div>

І буде обраний тест у діві.


1
Не забудьте зателефонувати window.getSelection (). RemoveAllRanges (); як у коді Джосілло. Крім того: я б закликав поставити window.getSelect як перший варіант, оскільки це стандарт HTML5, а document.selection - це стара версія IE для IE8 і раніше.
Ян Агаард

3

Як щодо цього простого рішення? :)

<input style="background-color:white; border:1px white solid;" onclick="this.select();" id="selectable" value="http://example.com/page.htm">

Впевнений, що це не дива-будівництво, як ви згадали, але все-таки воно працює для мене.


1
Коротке рішення, але це не враховує текст у іншому елементі, крім поля введення чи текстової області.
JoePC

3

Ніко Лей: Як щодо цього простого рішення? :)

`<input style="background-color:white; border:1px white solid;" onclick="this.select();" id="selectable" value="http://example.com/page.htm">`

.....

Код до:

<textarea rows="20" class="codearea" style="padding:5px;" readonly="readonly">

Код після:

<textarea rows="20" class="codearea" style="padding:5px;" readonly="readonly" onclick="this.select();" id="selectable">

Просто ця частина onclick = "this.select ();" id = "вибір" у моєму коді справно працював. Виділяє все у моєму кодовому полі одним клацанням миші.

Дякуємо за допомогу Ніко Лай!


0
$.fn.selectText = function () {
    return $(this).each(function (index, el) {
        if (document.selection) {
            var range = document.body.createTextRange();
            range.moveToElementText(el);
            range.select();
        } else if (window.getSelection) {
            var range = document.createRange();
            range.selectNode(el);
            window.getSelection().addRange(range);
        }
    });
}

Вищенаведена відповідь не працює в Chrome, оскільки addRange видаляє попередній доданий діапазон. Я не знайшов жодного рішення для цього, крім підробленого вибору з css.


Для когось цей код може бути корисним, оскільки я перевірив і виявив, що він працює в останній версії Chrome: $ .fn.selectText = function () {return $ (this) .each (function (index, el) {if (документ. вибір) {var range = document.body.createTextRange (); range.moveToElementText (el); range.select ();} else if (window.getSelection) {var range = document.createRange (); range.selectNode (el ); window.getSelection (). removeAllRanges (); window.getSelection (). addRange (range);}}); }
Хайдер Аббас

0

Легко досягається завдяки встановленому користувачем властивості css для всіх. Подобається це:

div.anyClass {
  user-select: all;
}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.