0

I'm currently trying to write a JS function to provide a "copy link on button click". It works fine on Android and PC but when I try it on my iPad or iPhone I'm getting an error:

TypeError: Argument 1 ('refNode') to Range.selectNodeContents must be an instance of Node

I've build in a way to copy it on IOS devices too, because the normal copy command don't works:

function copyUrl(e) {
    var tmp = jQuery("<input>");
    jQuery("body").append(tmp.val(e));

    if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
        var editable = tmp.contentEditable;
        var readOnly = tmp.readOnly;
        tmp.contentEditable = true;
        tmp.readOnly = false;
        var range = document.createRange();
        range.selectNodeContents(tmp);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        tmp.setSelectionRange(0, 999999);
        tmp.contentEditable = editable;
        tmp.readOnly = readOnly;
    } else {
        tmp.select();
    }

    document.execCommand("copy");
    tmp.remove();
    alert("Link copied successfully!")
}
div {
  padding: 30px;
}

a {
  border: 1px solid;
  padding: 12px 10px;
  cursor: pointer;
}

a:hover {
  border-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <a class="btn-floating" onclick="copyUrl('google.de')">Share</a>
</div>

What have I missed?

Mr. Jo
  • 4,946
  • 6
  • 41
  • 100

3 Answers3

2

If you pass the JQuery element as an argument element, it will give the TypeError you are getting because it does not interface the Node.

The TypeError message is related to you not doing one of the following.

// copy(document.getElementByClass("")[0];
copy(document.getElementById("")); // Pure JS
copy($("#")[0]); // JQuery

Example, as asked for a link passing a variable string: It creates an element then removes it after selecting it and copying the variable's value we inserted in it.

I suggest looking into the library Cliboard.js

function copy(href) {
    var dummy = document.createElement("input");
    document.body.appendChild(dummy);
    dummy.setAttribute('value', href);
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}
<a href="#" onclick="copy('https://wehavehaxedthecliboard.com')">Copy</a>

FROM IOS Copy to clipboard using Javascript in iOS

var copy = function(href) {
    var input = document.createElement("input");
    document.body.appendChild(input);
    input.setAttribute('value', href);

    var isiOSDevice = navigator.userAgent.match(/ipad|iphone/i);

    if (isiOSDevice) {

        var editable = input.contentEditable;
        var readOnly = input.readOnly;

        input.contentEditable = true;
        input.readOnly = false;

        var range = document.createRange();
        range.selectNodeContents(input);

        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);

        input.setSelectionRange(0, 999999);
        input.contentEditable = editable;
        input.readOnly = readOnly;

        document.body.removeChild(input);
    } else {
        input.select();
    }

    document.execCommand('copy');
    document.body.removeChild(input);
}
I think this works on ios
<a href="#" onclick="copy('http://google.com')">Copy text</a>
ABC
  • 2,068
  • 1
  • 10
  • 21
  • I'll try it out and let you know if it works! Thanks! – Mr. Jo Mar 15 '19 at 21:32
  • 1
    I just redid it. Sorry I had to get to a computer, wasn't able to code before because I was on a Ipad. – ABC Mar 15 '19 at 21:40
  • Hm strange, I don't have an element "el"? – Mr. Jo Mar 15 '19 at 21:46
  • 1
    @Mr.Jo this is just a working example on passing the element, if you want me to fix your code give me a second. – ABC Mar 15 '19 at 21:47
  • Whats with the IE < 9 ? Do we need this? – Mr. Jo Mar 15 '19 at 22:43
  • @Mr.Jo no you do not, I removed it for you. It was just to make sure when I wrote it, that the document functions were available. Some browsers do not support certain functions. – ABC Mar 15 '19 at 22:50
  • Seems to be not working on my iPad anymore. Cache is cleared. I'm wondering because normally the execCommand("copy") don't works within IOS. – Mr. Jo Mar 15 '19 at 23:01
  • Seems to be good, but the prevent scrolling on iPad don't works. It runs down to the end of the page which is a bit wired :0. – Mr. Jo Mar 15 '19 at 23:38
  • Still working but still getting a scrolling on my iPad :/ sorry mate – Mr. Jo Mar 16 '19 at 00:19
  • Im still looking into it, kind of difficult it seems. – ABC Mar 16 '19 at 18:12
  • Oh hey again, this would be nice! I've also tried some unsuccessful things. – Mr. Jo Mar 16 '19 at 18:41
  • Have you found a hack? – Mr. Jo Mar 16 '19 at 20:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/190173/discussion-between-raymond-and-mr-jo). – ABC Mar 16 '19 at 20:36
  • Still not found a solution. Maybe I need to accept this. It works fine everywhere but on my old iPad 2 within Safari is still the scroll to the bottom. – Mr. Jo Mar 18 '19 at 11:23
  • Hey Raymond, I'll love to check your answer. But maybe you can get a last view onto the iPad issue? – Mr. Jo Mar 23 '19 at 17:47
  • Note: I covered the scenario where the user denies permission to the clipboard. Additionally, the message "link copied" will be displayed even if the user copies manually. – Renga Aug 06 '19 at 12:42
-1

Try something like this:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script type="text/javascript">
$(function() {
 $('.copy-to-clipboard input').click(function() {
 $(this).focus();
 $(this).select();
 document.execCommand('copy');
 alert('Copy to Clipboard!');
    });
});
</script>


<span class="copy-to-clipboard">
 <input id="copy-test" readonly type="text" value="google.de">
</span>
Sérgio Martins
  • 112
  • 1
  • 7
  • This does not take a variable as a string for the URL, as he asked for it to in his example. And all my example's do cover this. As he stated this does not work in iOS. – ABC Mar 15 '19 at 23:15
-1

Try this one

/*
    Copy text from any appropriate field to the clipboard
  By Craig Buckler, @craigbuckler
  use it, abuse it, do whatever you like with it!
*/
(function() {

    'use strict';
  
  // click events
  document.body.addEventListener('click', copy, true);

    // event handler
    function copy(e) {

    // find target element
    var 
      t = e.target,
      c = t.dataset.copytarget,
      inp = (c ? document.querySelector(c) : null);
      
    // is element selectable?
    if (inp && inp.select) {
      
      // select text
      inp.select();

      try {
        // copy text
        document.execCommand('copy');
        inp.blur();
        
        // copied animation
        t.classList.add('copied');
        setTimeout(function() { t.classList.remove('copied'); }, 1500);
      }
      catch (err) {
        alert('please press Ctrl/Cmd+C to copy');
      }
      
    }
    
    }

})();
div {
  padding: 30px;
}

a {
  border: 1px solid;
  padding: 12px 10px;
  cursor: pointer;
}

a:hover {
  border-color: blue;
}
<div>
<input style="position: absolute;
  height: 100px;
  width: 100px;
  right: -150px;
  top: -150px;overflow:hidden;" type="text" id="website" value="http://hpecas.com/teste" />

<a class="btn-floating" href="#" data-copytarget="#website">Share</a>
</div>
Sérgio Martins
  • 112
  • 1
  • 7