我可以在“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 个通用函数,我可以用它从各种文本区域复制......
基于您共享的代码,解决方案的一种方法如下:
// 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>
现在,我们不应该使用上述方法的原因:
我们可以做的是:
EventTarget.addEventListener()
,它使用 JavaScript 来绑定事件处理,<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>
参考资料:
<!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>
在现代浏览器中(除了 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>
"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>