代码之家  ›  专栏  ›  技术社区  ›  Bing

javascript:复制到剪贴板会导致跳转到页面顶部(不涉及锚标记!)

  •  0
  • Bing  · 技术社区  · 7 年前

    我见过很多类似的问题,但是这个问题没有锚标签,没有锚标签我找不到答案!

    问题

    单击要复制到剪贴板的元素(下面提供的代码)会导致页面滚动到顶部,这是不需要的。

    问题

    我看到它在 focus 改变,但永远不会改变。有没有办法防止页面跳转?

    代码

    JS Fiddle: https://jsfiddle.net/myingling/r135zL90/2/

    一 嵌入的

    <style>
    div {
      min-height: 500px;
    }
    .item {
      cursor: pointer;
      background-color: blue;
      color: white;
      padding: 3px;
    }
    </style>
    <div>
      <span class='item'>AAA</span>
    </div>
    <div>
      <span class='item'>BBB</span>
    </div>
    <div>
       <span class='item'>CCC</span>
    </div>
    
    <script>
        jQuery(".item").click(function () {
            var success = copyToClipboard(jQuery(this).html());
            if (success) jQuery(this).fadeOut(100).fadeIn(100);
        });
    
    function copyToClipboard(elem) {
        // create hidden text element, if it doesn't already exist
        var targetId = "_hiddenCopyText_";
        var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
        var origSelectionStart, origSelectionEnd;
        if (isInput) {
            // can just use the original source element for the selection and copy
            target = elem;
            origSelectionStart = elem.selectionStart;
            origSelectionEnd = elem.selectionEnd;
        } else {
            // must use a temporary form element for the selection and copy
            target = document.getElementById(targetId);
            if (!target) {
                var target = document.createElement("textarea");
                target.style.position = "absolute";
                target.style.left = "-9999px";
                target.style.top = "0";
                target.id = targetId;
                document.body.appendChild(target);
            }
            if(typeof elem == "string") target.textContent = elem;
            else target.textContent = elem.text();
        }
        // select the content
        var currentFocus = document.activeElement;
        target.focus();
        target.setSelectionRange(0, target.value.length);
    
        // copy the selection
        var succeed;
        try {
            succeed = document.execCommand("copy");
        } catch(e) {
            succeed = false;
        }
        // restore original focus
        if (currentFocus && typeof currentFocus.focus === "function") {
            currentFocus.focus();
        }
    
        if (isInput) {
            // restore prior selection
            elem.setSelectionRange(origSelectionStart, origSelectionEnd);
        } else {
            // clear temporary content
            target.textContent = "";
        }
        return succeed;
    }
    </script>
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Will    7 年前

    这里有几个问题: 1-向函数提交HTML内容,而它需要一个DOM元素。 2-您将该文本区域添加到页面顶部,这样浏览器将向上滚动以获得焦点。

    解决方案: 1 -删除 .html() copyToClipboard() 在函数的开头创建一个变量 2-将该文本区域添加到单击的元素中,这样浏览器就不会滚动离开它。

    记住,一旦使用了隐藏字段,就要将其删除。

    下面的javascript代码

        jQuery(".item").click(function () {
            var success = copyToClipboard(jQuery(this));
            if (success) jQuery(this).fadeOut(100).fadeIn(100);
        });
    
    function copyToClipboard(elem) {
        // create hidden text element, if it doesn't already exist
        var copyText = elem.html();
        var targetId = "_hiddenCopyText_";
        var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
        var origSelectionStart, origSelectionEnd;
        if (isInput) {
            // can just use the original source element for the selection and copy
            target = elem;
            origSelectionStart = elem.selectionStart;
            origSelectionEnd = elem.selectionEnd;
        } else {
            // must use a temporary form element for the selection and copy
            target = document.getElementById(targetId);
            if (!target) {
                var target = document.createElement("textarea");
                /*target.style.position = "absolute";
                target.style.left = "-9999px";
                target.style.top = "0";
                target.id = targetId;
                document.body.appendChild(target);*/
                target.style.opacity = 0;
                elem.append(target);
            }
            if(typeof elem == "string") target.textContent = elem;
            else target.textContent = elem.text();
        }
        // select the content
        var currentFocus = document.activeElement;
        target.focus();
        target.setSelectionRange(0, target.value.length);
    
        // copy the selection
        var succeed;
        try {
            succeed = document.execCommand("copy");
        } catch(e) {
            succeed = false;
        }
        // restore original focus
        if (currentFocus && typeof currentFocus.focus === "function") {
            currentFocus.focus();
        }
    
        if (isInput) {
            // restore prior selection
            elem.setSelectionRange(origSelectionStart, origSelectionEnd);
        } else {
            // clear temporary content
            target.textContent = "";
        }
        target.remove();
        return succeed;
    }
    

    看看这是不是你想要的: https://jsfiddle.net/yjvstazu

    边注 :这在iOS上不起作用。您需要使输入/文本区域内容可编辑。在代码中添加如下内容:

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