Скопіюйте вихідні дані змінної JavaScript у буфер обміну


80

Я не знаю JavaScript, але мені вдалося зібрати цей код, використовуючи біти та болти з різних відповідей Stack Overflow. Це працює нормально, і виводить масив усіх вибраних прапорців у документі через поле сповіщення.

function getSelectedCheckboxes(chkboxName) {
  var checkbx = [];
  var chkboxes = document.getElementsByName(chkboxName);
  var nr_chkboxes = chkboxes.length;
  for(var i=0; i<nr_chkboxes; i++) {
    if(chkboxes[i].type == 'checkbox' && chkboxes[i].checked == true) checkbx.push(chkboxes[i].value);
  }
  return checkbx;
}

І щоб назвати це, я використовую:

<button id="btn_test" type="button" >Check</button>
<script>
    document.getElementById('btn_test').onclick = function() {
        var checkedBoxes = getSelectedCheckboxes("my_id");
        alert(checkedBoxes);
    }
</script>

Тепер я хотів би змінити його, так що коли я натискаю btn_testкнопку, вихідний масив checkbxкопіюється в буфер обміну. Я спробував додати:

checkbx = document.execCommand("copy");

або

checkbx.execCommand("copy");

в кінці функції, а потім викликає її як:

<button id="btn_test" type="button" onclick="getSelectedCheckboxes('my_id')">Check</button>

Але це не працює. Дані не копіюються в буфер обміну.


Я сумніваюся, що ви можете скопіювати необроблений об'єкт JS у буфер обміну. .execCommand('copy')копіює виділення на сторінці (якщо це дозволено в налаштуваннях користувача). Ви можете спробувати розшифрувати масив, потім заповнити ним текстове поле, вибрати все з текстового поля, а потім скопіювати за допомогою execCommand. Під час вставлення захопіть подію та проаналізуйте вміст назад у масив.
Teemu

Добре .. Дякую, що вказали мені напрямок. Я думав, що це, мабуть, неможливо, оскільки, здається, не повертає жодних прямих результатів пошуку. Тож, мабуть, я спробую зробити те, що ви запропонували.
harman

Це, можливо, дурне запитання, але куди / як би ви вставили необроблений об'єкт JS?
Teemu

Ну, в основному це для wordpress thingy .. Я просто збираю всі елементи, чий ID = деякий ідентифікатор, щоб потім вставити ідентифікатори, розділені комами, в умовні теги wordpress. Надія, що має сенс ..
Харман

Виправлення заради розумності ... Я збираю всі елементи, які були позначені, а НЕ чий ідентифікатор = якийсь ідентифікатор ... ;-)
harman

Відповіді:


110
function copyToClipboard(text) {
    var dummy = document.createElement("textarea");
    // to avoid breaking orgain page when copying more words
    // cant copy when adding below this code
    // dummy.style.display = 'none'
    document.body.appendChild(dummy);
    //Be careful if you use texarea. setAttribute('value', value), which works with "input" does not work with "textarea". – Eduard
    dummy.value = text;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}
copyToClipboard('hello world')
copyToClipboard('hello\nworld')

1
Будьте обережні, якщо використовуєте тексарею. setAttribute ('value', value) не працює з ним.
Едуард

@how t скопіювати рядок за допомогою \n?
qg_java_17137

2
Це працює в Chrome для когось? Я перебуваю у v70 +, і він не видає помилок, але не копіює. Працює в IE.
ScottLenart

З якихось причин мені довелося використовувати .textContentзамість .value.
mythofechelon

Працює у Firefox 79.0, Chrome 84.0, IE 11, Edge 44 (у Windows 10).
NoJoshua

40

Гаразд, я знайшов трохи часу і слідував пропозиціям Теему, і я зміг отримати саме те, що хотів.

Отже, ось остаточний код для всіх, кого це може зацікавити. Для уточнення цей код отримує всі позначені прапорці певного ідентифікатора, виводить їх у масив, названий тут checkbx, а потім копіює їх унікальне ім'я в буфер обміну.

Функція JavaScript:

function getSelectedCheckboxes(chkboxName) {
  var checkbx = [];
  var chkboxes = document.getElementsByName(chkboxName);
  var nr_chkboxes = chkboxes.length;
  for(var i=0; i<nr_chkboxes; i++) {
    if(chkboxes[i].type == 'checkbox' && chkboxes[i].checked == true) checkbx.push(chkboxes[i].value);
  }
  checkbx.toString();

  // Create a dummy input to copy the string array inside it
  var dummy = document.createElement("input");

  // Add it to the document
  document.body.appendChild(dummy);

  // Set its ID
  dummy.setAttribute("id", "dummy_id");

  // Output the array into it
  document.getElementById("dummy_id").value=checkbx;

  // Select it
  dummy.select();

  // Copy its contents
  document.execCommand("copy");

  // Remove it as its not needed anymore
  document.body.removeChild(dummy);
}

І його HTML-виклик:

<button id="btn_test" type="button" onclick="getSelectedCheckboxes('ID_of_chkbxs_selected')">Copy</button>

8
Чи можна це зробити без створення елемента HTML? Скажімо, наприклад, я просто хотів скопіювати рядок у буфер обміну користувачами, коли вони натискають кнопку або заздалегідь заданий елемент?
VikingGoat

6
Я б рекомендував використовувати "textarea" замість "input", таким чином, ви також можете скопіювати розриви рядків.
Telmo Trooper

20

Для загальних цілей копіювання будь-якого тексту в буфер обміну я написав таку функцію:

function textToClipboard (text) {
    var dummy = document.createElement("textarea");
    document.body.appendChild(dummy);
    dummy.value = text;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}

Значення параметра вставляється у значення новоствореного <textarea>, яке потім вибирається, його значення копіюється в буфер обміну, а потім видаляється з документа.


1
Будьте обережні, якщо використовуєте тексарею. setAttribute ('value', value), який працює з "input", не працює з "textarea".
Едуард

16

Дуже корисний. Я змінив його, щоб скопіювати значення змінної JavaScript у буфер обміну:

function copyToClipboard(val){
    var dummy = document.createElement("input");
    dummy.style.display = 'none';
    document.body.appendChild(dummy);

    dummy.setAttribute("id", "dummy_id");
    document.getElementById("dummy_id").value=val;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}

5
змінити $ (фіктивний) .css ('display', 'none'); into dummy.style.display = 'немає'; щоб уникнути jQuery
Kardi Teknomo

4
Chrome повинен мати манекен, що відображається. Тож я видалив один рядок коду, і він працює, дякую
shukshin.ivan

1
@ shukshin.ivan дякую за цей внесок! У підсумку я змінив цей рядок на такий: dummy.setAttribute("hidden", true);true може бути чим завгодно, оскільки синтаксис html для прихованого атрибута не має жодного значення.
Джиммі Вестберг,

Я також зробив просту перевірку, чи надіслане "значення" є об'єктом, якщо так стригфік:if (typeof stuffToAddToClipboard === "object") { stuffToAddToClipboard = JSON.stringify(stuffToAddToClipboard); }
Джиммі Вестберг

Привіт, хтось може пояснити голосування проти? Я не бачу чітких резонансів у своїй відповіді ...
lbrutti


5

Мені вдалося скопіювати текст у буфер обміну ( не показуючи жодного текстового поля ), додавши прихований input елемент до body, тобто:

 function copy(txt){
  var cb = document.getElementById("cb");
  cb.value = txt;
  cb.style.display='block';
  cb.select();
  document.execCommand('copy');
  cb.style.display='none';
 }
<button onclick="copy('Hello Clipboard!')"> copy </button>
<input id="cb" type="text" hidden>


1
Це спрацювало для мене, але лише без "прихованого" атрибута для вводу. У Chromium він формує стиль "display: none! Important", який не перезаписується вручну, встановлюючи "display: block" у рядку 4 вашого сценарію.
II СТРІЛКИ

Як не дивно, але це продовжує зазнавати невдач для мене. Натомість, коли я намагаюся вставити, він просто вставляє старий текст у буфер обміну. Це відома проблема?
Destaq

3

На момент написання статті налаштування display:noneелемента для мене не працювало . Встановлення ширини та висоти елемента на 0 також не спрацювало. Отже, елемент повинен мати принаймні 1pxширину, щоб це працювало.

Наступний приклад працював у Chrome та Firefox:

    const str = 'Copy me';
    const el = document.createElement("input");
    // Does not work:
    // dummy.style.display = "none";
    el.style.height = '0px';
    // Does not work:
    // el.style.width = '0px';
    el.style.width = '1px';
    document.body.appendChild(el);
    el.value = str;
    el.select();
    document.execCommand("copy");
    document.body.removeChild(el);

Я хотів би додати, що я бачу, чому браузери намагаються запобігти цьому хакерському підходу. Краще відкрито показувати вміст, який ви збираєтесь скопіювати, у браузер користувача. Але іноді є вимоги до дизайну, ми не можемо змінити.


1

Я просто хочу додати, якщо хтось хоче скопіювати два різні входи в буфер обміну. Я також використовував техніку введення її у змінну, а потім поміщав текст змінної з двох входів у текстову область.

Примітка: наведений нижче код наведено користувачем, який запитує, як скопіювати кілька входів користувача в буфер обміну. Я просто виправив це для коректної роботи Тож очікуйте якогось старого стилю, наприклад використання varзамість letабо const. Я також рекомендую використовувати addEventListenerдля кнопки.

    function doCopy() {

        try{
            var unique = document.querySelectorAll('.unique');
            var msg ="";

            unique.forEach(function (unique) {
                msg+=unique.value;
            });

            var temp =document.createElement("textarea");
            var tempMsg = document.createTextNode(msg);
            temp.appendChild(tempMsg);

            document.body.appendChild(temp);
            temp.select();
            document.execCommand("copy");
            document.body.removeChild(temp);
            console.log("Success!")


        }
        catch(err) {

            console.log("There was an error copying");
        }
    }
<input type="text" class="unique" size="9" value="SESA / D-ID:" readonly/>
<input type="text" class="unique" size="18" value="">
<button id="copybtn" onclick="doCopy()"> Copy to clipboard </button>


0

На сьогоднішній день існує новий (ish) API, який робить це безпосередньо. Він працює лише в сучасних браузерах та на HTTPS (і localhost). Не підтримується IE11.

IE11 має власний API.

І обхідний шлях у прийнятій відповіді може бути використаний для незахищених хостів.

function copyToClipboard (text) {
  if (navigator.clipboard) { // default: modern asynchronous API
    return navigator.clipboard.writeText(text);
  } else if (window.clipboardData && window.clipboardData.setData) {     // for IE11
    window.clipboardData.setData('Text', text);
    return Promise.resolve();
  } else {
    // workaround: create dummy input
    const input = h('input', { type: 'text' });
    input.value = text;
    document.body.append(input);
    input.focus();
    input.select();
    document.execCommand('copy');
    input.remove();
    return Promise.resolve();
  }
}

Примітка: він використовує Hyperscript для створення елемента введення (але повинен бути легким для адаптації)

Немає необхідності робити введення невидимим, оскільки воно додається та видаляється так швидко. Крім того, прихований (навіть за допомогою розумного методу) деякі браузери виявлять його та запобігають копіюванню.

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