如何将 Clipboard.js 2.0 与 Bootstrap 5.2 工具提示结合使用?

问题描述 投票:0回答:2

我正在尝试构建一个带有各种按钮的页面,这些按钮将文本复制到剪贴板,然后向用户反馈值已被复制。值不是来自用户输入,每个按钮的值都是静态的。

这是我找到的最接近我想要的示例(工具提示+通过 Clipboard.js 单击突出显示动画),但我使用的是最新版本的 Bootstrap,并且我发现如果更改 Bootstrap CSS 的版本或 JS,或剪贴板,然后示例停止工作。

我的 Javascript 知识非常有限,所以如果有人能指出为什么它不适用于最新版本,那就太好了。

javascript twitter-bootstrap twitter-bootstrap-tooltip clipboard.js
2个回答
0
投票

我不是 javascript/bootstrap 专家,但我会尝试分享我的一点经验。我认为问题可能在于 Bootstrap 3 和 4 的 jQuery 依赖关系,因为与工具提示相关的参考页面上的脚本是用 jQuery 和 Bootstrap 编写的5 及以上版本现在使用 Vanilla Javascript,除非将 jQuery 依赖项添加到主项目中,否则脚本不会运行,您可以看到我的项目的一个片段,其中 jQuery、ClipboardJS 和 Bootstrap 5.2 都可以正常工作+我添加了一些 CSS 和动画也是如此,我还没有发现任何冲突,希望这能有所帮助。也请检查这里Bootstrap 5.2 with jQuery

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous"><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous">
    </script>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Amaranth:ital,wght@0,400;0,700;1,700&display=swap"
    rel="stylesheet">
  <title>Bootstrap 5.2 and tooltips jQuery</title>
  <link rel="icon" type="image/x-icon" href="/images/favicon.ico">

  <link rel="canonical" href="https://www.google.com">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
  <style>
    body {
      font-family: 'Amaranth', sans-serif;
      background: url(https://images.pexels.com/photos/531602/pexels-photo-531602.jpeg) no-repeat center center fixed;
      -webkit-background-size: cover;
      background-size: cover;
      overflow: auto;
      opacity: 99%;
      overflow-x: hidden;
      background-repeat: no-repeat;
      background-position: center;
      position: relative;

    }




    button {
      margin: 20px;
    }

  

   
    .btn-5 {
      width: 47px;
      height: 40px;
      line-height: 42px;
      padding: 0;
      border: none;
      background: rgb(255, 27, 0);
      background: linear-gradient(0deg, rgba(255, 27, 0, 1) 0%, rgba(251, 75, 2, 1) 100%);
    }

    .btn-5:hover {
      color: #f0094a;
      background: transparent;
      box-shadow: none;
    }

    .btn-5:before,
    .btn-5:after {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      height: 2px;
      width: 0;
      background: #f0094a;
      box-shadow:
        -1px -1px 5px 0px #fff,
        7px 7px 20px 0px #0003,
        4px 4px 5px 0px #0002;
      transition: 400ms ease all;
    }

    .btn-5:after {
      right: inherit;
      top: inherit;
      left: 0;
      bottom: 0;
    }

    .btn-5:hover:before,
    .btn-5:hover:after {
      width: 100%;
      transition: 800ms ease all;
    }    
    
    .btn-11 {
      width: 47px;
      height: 40px;
      line-height: 42px;
      padding: 0;
      border: none;
      background: rgb(232, 120, 9);
      background: linear-gradient(0deg, rgb(233, 106, 15) 0%, rgb(193, 130, 35) 100%);
    }

    .btn-11:hover {
      color: #ff8000;
      background: transparent;
      box-shadow: none;
    }

    .btn-11:before,
    .btn-11:after {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      height: 2px;
      width: 0;
      background: #ff8000;
      box-shadow:
        -1px -1px 5px 0px #fff,
        7px 7px 20px 0px #0003,
        4px 4px 5px 0px #0002;
      transition: 400ms ease all;
    }

    .btn-11:after {
      right: inherit;
      top: inherit;
      left: 0;
      bottom: 0;
    }

    .btn-11:hover:before,
    .btn-11:hover:after {
      width: 100%;
      transition: 800ms ease all;
    }

    .btn-14 {
      background: rgb(255, 151, 0);
      border: none;
      z-index: 1;
    }

    .btn-14:after {
      position: absolute;
      content: "";
      width: 100%;
      height: 0;
      top: 0;
      left: 0;
      z-index: -2;
      border-radius: 5px;
      background-color: #eaf818;
      background-image: linear-gradient(315deg, #e0f00c 0%, #07f5e5 25%, #0f7fc9 74%, #e10cf0 81%);
      box-shadow: inset 2px 2px 2px 0px rgba(255, 255, 255, .5),
        7px 7px 20px 0px rgba(0, 0, 0, .1),
        4px 4px 5px 0px rgba(0, 0, 0, .1);
      transition: all 0.3s ease;
    }

    .btn-14:hover {
      color: #000;
    }

    .btn-14:hover:after {
      top: auto;
      bottom: 0;
      height: 100%;
    }

    .btn-14:active {
      top: 2px;
    }

    /* 15 */
    .btn-15 {
      background: #b621fe;
      border: none;
      z-index: 1;
    }

    .btn-15:after {
      position: absolute;
      content: "";
      width: 0;
      height: 100%;
      top: 0;
      right: 0;
      z-index: -1;
      background-color: #663dff;
      border-radius: 5px;
      box-shadow: inset 2px 2px 2px 0px rgba(255, 255, 255, .5),
        7px 7px 20px 0px rgba(0, 0, 0, .1),
        4px 4px 5px 0px rgba(0, 0, 0, .1);
      transition: all 0.3s ease;
    }

    .btn-15:hover {
      color: #fff;
    }

    .btn-15:hover:after {
      left: 0;
      width: 100%;
    }

    .btn-15:active {
      top: 2px;
    }  

    .alfredo {
      background-color: #eaf818;
      background-image: linear-gradient(315deg, #e0f00c 0%, #07f5e5 25%, #0f7fc9 74%, #e10cf0 81%);
    }

    .alfredo2 {
      background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
      background-size: 400% 400%;
      animation: gradient 15s ease infinite;
      height: 100vh;
    }

    @keyframes gradient {
      0% {
        background-position: 0% 50%;
      }

      50% {
        background-position: 100% 50%;
      }

      100% {
        background-position: 0% 50%;
      }
    }

    .css-selector {
      background: linear-gradient(90deg, #33f8a8, #33a3f8, #da1ebd, #21bae3, #7023a7);
      background-size: 1000% 1000%;

      -webkit-animation: Alfredo 2s ease infinite;
      animation: Alfredo 2s ease infinite;
    }

    @-webkit-keyframes Alfredo {
      0% {
        background-position: 0% 51%
      }

      50% {
        background-position: 100% 50%
      }

      100% {
        background-position: 0% 51%
      }
    }

    @keyframes Alfredo {
      0% {
        background-position: 0% 51%
      }

      50% {
        background-position: 100% 50%
      }

      100% {
        background-position: 0% 51%
      }
    }
    

    .urgent {
      color: #ff8000;
    }

    .urgent2 {
      background-color: #ff8000
    }

    .purple {
      color: #7F00FF;
    }

    .pink {
      color: #BF40BF;
    }
    .card {
      border: none;
      height: auto;
    }

    .copy-button {
      height: 25px;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative
    }

    .tip {
      background-color: #ff8000;
      padding: auto;
      line-height: 25px;
      position: absolute;
      border-radius: 4px;
      z-index: 100;
      color: #fff;
      font-size: 14px;
      animation-name: tip;
      animation-duration: .6s;
      animation-fill-mode: both
    }

    .tip:before {
      content: "";
      background-color: #ff8000;
      height: 10px;
      width: 10px;
      display: block;
      position: absolute;
      transform: rotate(45deg);
      top: -4px;
      left: 17px
    }

    #copied_tip {
      animation-name: come_and_leave;
      animation-duration: 1s;
      animation-fill-mode: both;
      bottom: -35px;
      left: 2px
    }  
    .copy {
      display: flex;
      align-items: center;
      justify-content: start;
    }
    .copied {
      visibility: hidden;
      margin-top: var(--button-content-spacing-px);
    }  

  </style>
</head>

<body>
  <main class="container-fluid">  
     <div class="container-fluid" id="section1">
      <p style="padding-top: 4em;">
      <div class="p-4 p-md-5 mb-4 beta rounded-3 z bg-gradient pt-5">
        <div class="col px-0">     
        <nav class="navbar text-bg-dark">           
        <div class="d-flex justify-content-between align-items-center mb-3 text-bg-dark "> <span
                    class="text-line ms-3 text-bg-dark">This button will copy red fruits name on the clipboard</span> <button
                    onclick="copy('Apple,apple,apple and strawberries!','#copy_button_1')"
                    id="copy_button_1" class="btn btn-sm  btn-15 copy-button">Copy</button> </div>
                <div class="d-flex justify-content-between align-items-center mb-3 text-bg-dark"> <span
                    class="text-line ms-3 text-bg-dark">This button copies some yellow fruits on the clipboard</span>
                  <button
                    onclick="copy('Banana banana and pineapple.','#copy_button_2')"
                    id="copy_button_2" class="btn btn-sm btn-5 copy-button"><svg xmlns="http://www.w3.org/2000/svg"
                      class="icon icon-tabler icon-tabler-copy" width="48" height="48" viewBox="0 0 24 24"
                      stroke-width="2" stroke="#ff8000" fill="none" stroke-linecap="round" stroke-linejoin="round">
                      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                      <rect x="8" y="8" width="12" height="12" rx="2" />
                      <path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2" />
                    </svg>Copy</button>
                </div>
                <div class="d-flex justify-content-between align-items-center mb-3 text-bg-dark"> <span
                    class="text-line ms-3">This button will copy a lorem  name on the clipboard</span> <button
                    onclick="copy('Duis aute irure dolor in reprehenderit in voluptate velit','#copy_button_3')"
                    id="copy_button_3" class="btn btn-sm css-selector copy-button"><svg
                      xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                      class="bi bi-file-earmark-arrow-down" viewBox="0 0 16 16">
                      <path
                        d="M8.5 6.5a.5.5 0 0 0-1 0v3.793L6.354 9.146a.5.5 0 1 0-.708.708l2 2a.5.5 0 0 0 .708 0l2-2a.5.5 0 0 0-.708-.708L8.5 10.293V6.5z" />
                      <path
                        d="M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2zM9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5v2z" />
                    </svg>Copy</button> </div>
                <div class="d-flex justify-content-between align-items-center mb-3 text-bg-dark"> <span
                    class="text-line ms-3 ">This button will copy a lorem name on the clipboard </span> <button
                    onclick="copy('I am a cloudy button ','#copy_button_4')" id="copy_button_4"
                    class="btn btn-sm btn-11 alfredo2 copy-button"><svg xmlns="http://www.w3.org/2000/svg" width="16"
                      height="16" fill="currentColor" class="bi bi-cloud-download" viewBox="0 0 16 16">
                      <path
                        d="M4.406 1.342A5.53 5.53 0 0 1 8 0c2.69 0 4.923 2 5.166 4.579C14.758 4.804 16 6.137 16 7.773 16 9.569 14.502 11 12.687 11H10a.5.5 0 0 1 0-1h2.688C13.979 10 15 8.988 15 7.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 2.825 10.328 1 8 1a4.53 4.53 0 0 0-2.941 1.1c-.757.652-1.153 1.438-1.153 2.055v.448l-.445.049C2.064 4.805 1 5.952 1 7.318 1 8.785 2.23 10 3.781 10H6a.5.5 0 0 1 0 1H3.781C1.708 11 0 9.366 0 7.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383z" />
                      <path
                        d="M7.646 15.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 14.293V5.5a.5.5 0 0 0-1 0v8.793l-2.146-2.147a.5.5 0 0 0-.708.708l3 3z" />
                    </svg> Copy</button> </div>
                <div class="d-flex justify-content-between align-items-center mb-3 text-bg-dark"> <span
                    class="text-line ms-3">This button will copy a lorem name on the clipboard</span>
                  <button
                    onclick="copy('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod','#copy_button_5')"
                    id="copy_button_5" class="btn btn-sm btn-14 copy-button"><svg xmlns="http://www.w3.org/2000/svg"
                      width="16" height="16" fill="currentColor" class="bi bi-clipboard-check" viewBox="0 0 16 16">
                      <path fill-rule="evenodd"
                        d="M10.854 7.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7.5 9.793l2.646-2.647a.5.5 0 0 1 .708 0z" />
                      <path
                        d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z" />
                      <path
                        d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z" />
                    </svg>Copy</button>
                </div>

              </div>

          </div>
        </div>
      </div>
      </nav>
      <br>

  </main>
  
  <script>
    document.querySelectorAll('[data-bs-toggle="tooltip"]')
      .forEach(tooltip => {
        new bootstrap.Tooltip(tooltip)
      })
  </script>
  <script>
    function copy(text, target) {
      setTimeout(function () {
        $('#copied_tip').remove();
      }, 800);
      $(target).append("<div class='tip' id='copied_tip'>Copied!</div>");
      var input = document.createElement('input');
      input.setAttribute('value', text);
      document.body.appendChild(input);
      input.select();
      var result = document.execCommand('copy');
      document.body.removeChild(input)
      return result;

    }
  </script>
 
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/clipboard.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
  integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
  crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>

</html>


0
投票

这是我使用 jQuery、Bootstrap 和 Clipboard.js 的解决方案。

  function setTooltip(message, elem) {
    const tooltip = bootstrap.Tooltip.getOrCreateInstance(elem);
    tooltip.enable();
    tooltip.setContent({
      '.tooltip-inner': 'Copied!'
    })
    tooltip.show();
  }

  function hideTooltip(elem) {
    setTimeout(() => {
      const tooltip = bootstrap.Tooltip.getOrCreateInstance(elem);
      tooltip.hide();
      tooltip.disable();
    }, 1000);
  }


  $(document).ready(function() {

    $('[data-toggle="tooltip"]').tooltip();
    const elem = document.getElementById("copy-button");
    const tooltip = bootstrap.Tooltip.getOrCreateInstance(elem);
    tooltip.disable();

    // Initialization of the ClipboardJS
    const clipboard = new ClipboardJS('#copy-button');

    //On clipboard success
    clipboard.on('success', function(e) {
      const copyBtn = $("#copy-button");

      setTooltip('Copied', copyBtn);
      hideTooltip(copyBtn);
    });

    clipboard.on('error', function(e) {
      const copyBtn = $("#copy-button");
      setTooltip('Error while copying', copyBtn);
      hideTooltip(copyBtn);
    });

  });
© www.soinside.com 2019 - 2024. All rights reserved.