按钮 ID 作为 getElementById

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

我可以在“getElementById”中获取触发该功能的按钮ID值吗?

我正在尝试编写一个通用函数,其中 getElementById 应该与按钮 ID 相同,因此使用具有不同按钮 ID 的按钮触发函数会导致不同的 getElementById...

HTML:

<button id="10" onclick="f001()">C</button> 
<textarea id="11" rows="1" cols="25">Test123 </textarea> 

<button id="15" onclick="f001()">C</button> 
<textarea id="16" rows="1" cols="25">Test456 </textarea>

JS:

    function f001() {
    var copyText = document.getElementById("triggering button id + 1");
    copyText.select();
    document.execCommand("copy");
}

所以我只能有 1 个通用函数,我可以用它从各种文本区域复制......

javascript getelementbyid
4个回答
1
投票

基于您共享的代码,解决方案的一种方法如下:

// defining the function along with an argument that represents
// the element that was clicked:
function f001(_elem) {

  // here we use the HTMLElement.id property to retrieve the
  // value of the 'id' attribute/property of the clicked
  // element and use parseInt() - along with the radix of 10 -
  // to convert that id into a number:
  var integer = parseInt(_elem.id, 10),
      // here we use document.getElementById() to find the
      // element with an id equal to the integer after it's
      // been incremented by 1:
      copyText = document.getElementById(++integer);

  // we select the entered value from that identified
  // element:
  copyText.select();

  // and execute the 'copy' action to assign the content
  // to the clipboard:
  document.execCommand("copy");
}
<div>
  <!-- here we add the 'this' keyword to the function-call,
       this will be accessed in the function in order to
       retrieve the necessary properties of the element. We
       could pass 'this.id' to get direct access to the
       element's id, but that approach may limit us in future.  -->
  <button id="10" onclick="f001(this)">C</button>
  <textarea id="11" rows="1" cols="25">Test123 </textarea>

  <button id="15" onclick="f001(this)">C</button>
  <textarea id="16" rows="1" cols="25">Test456 </textarea>
</div>

<!-- a generic <textarea> into which the clipboard content
     may be pasted in order to demonstrate the success of
     the earlier function: -->
<div>
  <textarea placeholder="paste copied content here to check."></textarea>
</div>

现在,我们不应该使用上述方法的原因:

  1. 它要求我们在更新函数的需求时可靠地找到HTML中的所有函数调用,这会导致
  2. 将来维护的复杂性会增加(您可能是必须维护该功能/页面的人,不要让您的生活变得更困难)。

我们可以做的是:

  1. 依赖
    EventTarget.addEventListener()
    ,它使用 JavaScript 来绑定事件处理,
  2. 为函数使用有意义的名称,以便更容易记住函数的作用以及它存在的原因,
  3. 如果我们知道 DOM 将保持这种方式,那么我们就可以利用这一点,特别是如果要复制的
    <textarea>
    始终是
    nextElementSibling
    <button>

通过这些改进——尽管不可否认,它们可能是基于意见和个人偏好的——我们可以使用以下内容:

// defining the function along with a meaningful name, also takes an
// argument passed automatically from the later use of
// EventTarget.addEventListener():
const copyText = function(evt) {

    // from the Event Object passed in from EventTarget.addEventListener()
    // we retrieve the Event.currentTarget element, which is the element
    // to which the function is bound as the event-handler (Event.target
    // could be used instead, currently, unless other HTML elements were
    // placed within the <button> for styling purposes):
    var activated = evt.currentTarget,
    
        // we know that the <textarea> is the nextElementSibling, so here
        // we access that property of the HTMLElement:
        textarea = activated.nextElementSibling;

    // we select the entered-value:
    textarea.select();
    // we copy the entered-value to the clipboard:
    document.execCommand("copy");
  },
  
  // we find the <button> elements in the document:
  buttons = document.querySelectorAll('button');

// we use NodeList.prototype.forEach() to iterate over the
// NodeList, using an Arrow function inside:
buttons.forEach(
  // here 'btn' is a reference to the current Node of the
  // NodeList over which we're iterating, and we use the
  // EventTarget.addEventListener() method to bind the
  // named - copyText() function, but note the deliberate
  // lack of parentheses - as the 'click' event-handler:
  (btn) => btn.addEventListener('click', copyText)
)
<div>
  <button>C</button>
  <textarea>Test123 </textarea>

  <button>C</button>
  <textarea>Test456 </textarea>
</div>

<!-- a generic <textarea> into which the clipboard content
     may be pasted in order to demonstrate the success of
     the earlier function: -->
<div>
  <textarea placeholder="paste copied content here to check."></textarea>
</div>

我们还可以使用自定义

data-*
属性从
<button>
元素中检索属性,通过该属性我们可以检索相关的
<textarea>
:

// defining the function along with a meaningful name, also takes an
// argument passed automatically from the later use of
// EventTarget.addEventListener():
const copyText = function(evt) {

    // from the Event Object passed in from EventTarget.addEventListener()
    // we retrieve the Event.currentTarget element, which is the element
    // to which the function is bound as the event-handler:
    var activated = evt.currentTarget,
    
        // we then use the Element.dataset API to retrieve the attribute-value
        // of the data-copyfrom attribute:
        identifierString = activated.dataset.copyfrom,
        
        // we use a CSS attribute-selector, along with a Template Literal
        // (a String delimited using back-ticks) in which JavaScript can
        // be directly interpolated when wrapped with `${...JavaScript}`:
        textarea = document.querySelector( `[data-identifier=${identifierString}]` );

    // we select the entered-value:
    textarea.select();
    // we copy the entered-value to the clipboard:
    document.execCommand("copy");
  },
  
  // we find the <button> elements in the document with a custom data-copyfrom
  // attribute:
  buttons = document.querySelectorAll('button[data-copyfrom]');

// we use NodeList.prototype.forEach() to iterate over the
// NodeList, using an Arrow function inside:
buttons.forEach(
  // here 'btn' is a reference to the current Node of the
  // NodeList over which we're iterating, and we use the
  // EventTarget.addEventListener() method to bind the
  // named - copyText() function, but note the deliberate
  // lack of parentheses - as the 'click' event-handler:
  (btn) => btn.addEventListener('click', copyText)
)
<div>
  <!-- using data-copyfrom to specify a value by which the
       the relevant <textarea> might be retrieved (this
       could identify a class-name, the element's id or any
       other unique custom data-* attribute-value: -->
  <button data-copyfrom="textareaOne">C</button>
  <!-- here we use the data-identifier custom attribute
       as the attribute, the value of which, will identify
       the relevant element: -->
  <textarea data-identifier="textareaOne">Test123 </textarea>

  <button data-copyfrom="textareaTwo">C</button>
  <textarea data-identifier="textareaTwo">Test456 </textarea>
</div>

<!-- a generic <textarea> into which the clipboard content
     may be pasted in order to demonstrate the success of
     the earlier function: -->
<div>
  <textarea placeholder="paste copied content here to check."></textarea>
</div>

参考资料:


0
投票
<!doctype html>
<html>
<head>
<script>
"use strict";
window.addEventListener('load', onLoaded, false);

// called when the window has finished loading
// - attaches a click handler to all buttons.
//   buttons are selected with the css selector 'button'
//   'button.someClass' would select all 'button' elements
//   that had the class 'someClass'
function onLoaded(evt)
{
    let buttons = document.querySelectorAll('button');

// this code just does the same thing as the line below
//  buttons.forEach( 
//          function(btn)
//          { 
//              btn.addEventListener('click', onCopyBtnClick, false); 
//          } 
//      );
        
    buttons.forEach( btn => btn.addEventListener('click', onCopyBtnClick, false) );
}

function onCopyBtnClick(evt)
{
    // get reference to btn that fired the event
    let btn = this;

    // the textarea may not be the element immediately following
    // the button. In the code below, there's actually a 
    // text-node between the two walk through the list of 
    // siblings until we get to the first text-area after the button.
    let tmp = btn.nextSibling;
    while (tmp.nodeName != 'TEXTAREA')
        tmp = tmp.nextSibling;
    let targetTextarea = tmp;

    // select and copy the text
    targetTextarea.select();
    document.execCommand('copy');
}
</script>
</head>
<body>
    <button>COPY</button>
    <textarea rows='1' cols='25'>Test123 </textarea>
    
    <button>COPY</button>
    <textarea rows='1' cols='25'>Test456 </textarea>
</body>
</html>

示例

"use strict";
window.addEventListener('load', onLoaded, false);

// called when the window has finished loading
// - attaches a click handler to all buttons.
//   buttons are selected with the css selector 'button'
//   'button.someClass' would select all 'button' elements
//   that had the class 'someClass'
function onLoaded(evt)
{
    let buttons = document.querySelectorAll('button');

// this code just does the same thing as the line below
//  buttons.forEach( 
//          function(btn)
//          { 
//              btn.addEventListener('click', onCopyBtnClick, false); 
//          } 
//      );
        
    buttons.forEach( btn => btn.addEventListener('click', onCopyBtnClick, false) );
}

function onCopyBtnClick(evt)
{
    // get reference to btn that fired the event
    let btn = this;

    // the textarea may not be the element immediately following
    // the button. In the code below, there's actually a 
    // text-node between the two walk through the list of 
    // siblings until we get to the first text-area after the button.
    let tmp = btn.nextSibling;
    while (tmp.nodeName != 'TEXTAREA')
        tmp = tmp.nextSibling;
    let targetTextarea = tmp;

    // select and copy the text
    targetTextarea.select();
    document.execCommand('copy');
}
    <button>COPY</button>
    <textarea rows='1' cols='25'>Test123 </textarea>
    
    <button>COPY</button>
    <textarea rows='1' cols='25'>Test456 </textarea>


0
投票

在现代浏览器中(除了 IE 之外的任何浏览器)
您可以使用 W3C 标准自定义元素来创建您自己的 HTML 标签:

<my-textarea>Hello World!</my-textarea>
<hr>
<my-textarea>Hello Another World!</my-textarea>

<script>
  customElements.define("my-textarea", class extends HTMLElement {
    connectedCallback() {
      setTimeout(() => { //required because can only READ innerHTML after DOM is ready
        let textarea = document.createElement("textarea");
        let button = document.createElement("button");
        button.innerHTML = "copy me";
        button.id = "foo"; // no id needed, just showing wath duplicate ids do
        button.onclick = (evt) => { // inline event just fine, we're not attaching more
          textarea.select(); // in scope, so no need to search for textarea
          document.execCommand("copy");
          console.log(button.id, window[button.id]); // see difference in FireFox & Chrome
          console.log(document.querySelectorAll("#foo"));
        }
        textarea.innerHTML = this.innerHTML;
        this.innerHTML = "";
        this.append(textarea, button); // learn the difference with appendChild
      })
    }
  })
</script>


0
投票

"use strict";
window.addEventListener('load', onLoaded, false);

// called when the window has finished loading
// - attaches a click handler to all buttons.
//   buttons are selected with the css selector 'button'
//   'button.someClass' would select all 'button' elements
//   that had the class 'someClass'
function onLoaded(evt)
{
    let buttons = document.querySelectorAll('button');

// this code just does the same thing as the line below
//  buttons.forEach( 
//          function(btn)
//          { 
//              btn.addEventListener('click', onCopyBtnClick, false); 
//          } 
//      );
        
    buttons.forEach( btn => btn.addEventListener('click', onCopyBtnClick, false) );
}

function onCopyBtnClick(evt)
{
    // get reference to btn that fired the event
    let btn = this;

    // the textarea may not be the element immediately following
    // the button. In the code below, there's actually a 
    // text-node between the two walk through the list of 
    // siblings until we get to the first text-area after the button.
    let tmp = btn.nextSibling;
    while (tmp.nodeName != 'TEXTAREA')
        tmp = tmp.nextSibling;
    let targetTextarea = tmp;

    // select and copy the text
    targetTextarea.select();
    document.execCommand('copy');
}
    <button>COPY</button>
    <textarea rows='1' cols='25'>Test123 </textarea>
    
    <button>COPY</button>
    <textarea rows='1' cols='25'>Test456 </textarea>

© www.soinside.com 2019 - 2024. All rights reserved.