动态函数和动态参数/参数

时间:2017-01-30 13:43:32

标签: javascript jquery dynamic parameters arguments

我有一个名为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

2 个答案:

答案 0 :(得分:1)

一种解决方案包括两个步骤。

首先获取<p>中的所有#links个节点,然后过滤掉那些没有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);
});

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

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)

答案 1 :(得分:0)

感谢@lookforangular能够更新我的代码。 首先在foreach循环中选择div#链接中的所有p个节点。通过这种方式,一般可以对点击事件进行处理,而不是选择单个p节点。

通过将id设置为data-p,click事件可以使用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);
   });

   });
 }