【问题标题】:Dynamic function and dynamic parameter/argument动态函数和动态参数/参数
【发布时间】:2017-06-15 16:44:31
【问题描述】:

我有这个函数叫copyToClipboard()。这需要一个名为 element 的参数。此函数通过定位元素的 id、选择和复制内容来复制元素的内容。

例如:

JS

/*
*  Copy to clipboard fn
*/
function copyToClipboard(element) {
  var $temp = $("<input>");  
  $("body").append($temp);
  $temp.val($(element).text()).select();
  document.execCommand("copy");
  var $tempval = $temp.val($(element).text());
  $temp.remove();  

  var $notif = $("<p>");
  $notif.attr("class","notif");
  $("body").append($notif);
  $notif.html('Copied content to clipboard!');
  setTimeout(function() {
      $notif.fadeOut();
      $notif.promise().done(function(){
        this.remove();
      });
  }, 400);
}

HTML:

<p id="p1">content of #p1</p>
<p> not me tho </p>
<p id="p2">content of #p2</p>   
<button onclick="copyToClipboard('#p1')">Copy P1</button>
<button onclick="copyToClipboard('#p2')">Copy P2</button>

我正在尝试将其改进为动态生成按钮的功能。

到目前为止,我的方法是将上述函数集成到一个新函数中,迭代由 ID/Class(本例中为 ID)找到的元素,vb 使用 onclick 函数容器生成按钮,将迭代值作为参数/参数.

/*
* generate copy buttons fn
*/
function generateCopyButtons() {

  var links = document.getElementById('links').getElementsByTagName('p');
      for (var i = 0; i < links.length; i++) {
          var $link = links[i];
          var thisId = $($link).attr('id');     
              if( thisId && thisId !== "null" && thisId !== "undefined" ){                  
                  var $button = document.createElement('button'); // btn
                  $button.innerHTML = 'Copy ' + thisId; //btn text
                  var element = '#' + thisId; // # + id 
                // console.log(element); // works like i want, #p1, #p2

                //how do i pass the element into this function??
                $button.onclick = function(element) {
                    var $temp = $("<input>");                    
                    $temp.val($(element).text()).select();
                    document.execCommand("copy");
                    var $tempval = $temp.val($(element).text());
                    $("body").append($temp);
                    $temp.remove();

                var $notif = $("<p>");
                $notif.attr("class","notif");
                $("body").append($notif);
                $notif.html('Copied content to clipboard!');
                setTimeout(function() {
                    $notif.fadeOut();
                    $notif.promise().done(function(){
                      $notif.remove();
                    });
                }, 400);
            };
              $($link).prepend($button);              
              // $($thisHashId).remove();
          }
}

}
$(document).ready(function(){
  generateCopyButtons();
});

现在它不显示错误并且它不起作用。使用前面的按钮效果很好。

jsfiddle demonstrating problem

【问题讨论】:

    标签: javascript jquery dynamic parameters arguments


    【解决方案1】:

    一个解决方案包括 2 个步骤。

    首先获取#links内的所有&lt;p&gt;节点,过滤掉没有id的。

    var pNodes = document.querySelectorAll('#links p[id^="p"]');
    pNodes.forEach(function(element){
        var button = document.createElement('button');
    
        [...] //add button text, etc..
    
        button.setAttribute('data-p',element.getAttribute('id') );
        element.insertAdjacentHtml('afterend', button);
    });
    

    删除不必要代码的好方法是使用委托。 当您点击文档中的任何节点时,默认情况下事件向上传播,这意味着可以从其父节点#links 侦听&lt;button&gt; 元素的点击,这将通过删除 for 循环来减少代码量。

    var node = document.getElementById("links");
    node.addEventListener("click", function(e) {
        if(e.target && e.target.nodeName == "P") {
            //click event target is a <button> node
            //here e.target is the <button> DOM node
            //use e.target.getAttribute('data-p') to retrieve the <p>'s ID
        }
    }
    

    这解决了在每个按钮上附加监听器的需要,按钮生成可以在另一个脚本/函数中处理 我不确定它是否适用于所有浏览器(IE)

    【讨论】:

    • 谢谢我稍后会用这段代码更新我的答案。 IE compat 不是必需的,谢谢。仍在寻找将动态参数传递给 onclick 函数的选项。
    • 我不确定这在哪里可以帮助我生成参数,但它肯定是编写循环的更好方法。
    • 您在寻找什么样的论据?你有没有考虑在生成的 p 元素中插入数据标签?
    • 您可以将所有

      标签存储在一个数组中,过滤那些没有 id 的标签,然后 foreach p 创建一个兄弟按钮,该按钮在 data-p-id 或其他东西中获取 id 参数,然后使用e.target.nodeName == "BUTTON"

    • 我不是在尝试生成 p。我想要的是生成按钮,预先或附加到 p (如果他们有一个 ID),将此 ID ( + # )设置为每个按钮的 onclick 参数 - >例如

      ...

      变成

      ...

    【解决方案2】:

    感谢@lookforangular 能够更新我的代码。 首先在 foreach 循环中选择 div#links 中的所有 p 节点。这样一般可以处理点击事件,而不是选择单个 p 节点。

    通过将 id 设置为 data-p,点击事件可以使用 data-p 值作为动态参数来定位要复制的 div。随意重写、使用或更新此功能。代码下方是演示效果的工作小提琴的链接。 小奖励一条消息通知用户此操作。

     /*
      * generate copy buttons fn
      */
     function generateCopyButtons() {
       var pNodes = document.querySelectorAll('#links p[id^="p"]');
       pNodes.forEach(function(element) {
         var $button = document.createElement('button'); // btn       
         $button.innerHTML = 'Copy ' + element.id; //btn text
      // for this example we will set the value of data-p dynamically with the id so we have something to target. 
         $button.setAttribute('data-p', element.getAttribute('id'));
         element.prepend($button);
    
       $($button).on("click", function() {
         var $datap = '"#' + $($button).attr('data-p') + '"';
         //console.log($datap);
         var $temp = $("<input>");
         $("body").append($temp);
         $temp.val($(element).text()).select();
         document.execCommand("copy");
         $temp.remove();
    
         var $notif = $("<p>");
         $notif.attr("class", "notif");
         $("body").append($notif);
         $notif.html('Copied content to clipboard!');
         setTimeout(function() {
           $notif.fadeOut();
           $notif.promise().done(function() {
             this.remove();
           });
         }, 400);
       });
    
       });
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-08
      • 1970-01-01
      • 2016-12-07
      • 2016-02-20
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多