英文:
Run JS function on document load and when a certain element is clicked [Tampermonkey]
问题
I'm here to assist with your translation request. Here's the translated part of your code:
我正在尝试编写一个Tampermonkey脚本来扩展我使用的业务Web应用程序。在非常基本的意义上,页面上会出现某些URL,我需要从URL中提取一个数字,然后使用该数字构建一个新链接并追加到父元素上。
到目前为止,我有以下代码,但当我单击元素(分页仅为UL)或文档加载时它不起作用。我知道该函数可以工作,因为当我将其设置为在文档的任何位置单击时运行时,它可以工作。就好像页面在JS报告加载完全之前并没有完全加载一样。
(function() {
'use strict';
// 获取分页元素
var element = document.getElementsByClassName('pagination-sm');
element.onclick = createLinks;
document.onload = createLinks;
function createLinks() {
var links = document.querySelectorAll("a[href*='/Field/POPendingCreate/']");
for (var J = links.length-1; J >= 0; --J) {
var thisLink = links[J];
console.log(thisLink.href);
var ppon = thisLink.href.match(/\d+/)[0];
console.log(ppon);
var a = document.createElement('a');
var linkText = document.createTextNode("Preview Order");
a.appendChild(linkText);
a.title = "Preview Order";
a.href = "https://website.com/Field/DownloadPendingPO?POPPKeyID=" + ppon + "&co=1&po=" + ppon;
a.target = "_blank";
var parentNode = thisLink.parentNode;
console.log(parentNode);
parentNode.appendChild(a);
}
}
})();
UL元素看起来像这样:
```
如我上面所说,当我将其设置为在文档的任何位置单击时运行时,该函数按预期工作。对我更令人困惑的是,当使用document.onload时它不起作用。就好像页面只有在我开始与其交互后才开始加载数据。我尝试让函数在单击分页时运行的原因是因为页面似乎会获取所有数据并将其存储在某个地方(我无法看到),然后只是在分页时切换页面。因此,一旦单击分页,我确实需要在新页面上生成的链接上运行该函数。
似乎我需要延迟运行document.onload或其他一种方式来知道文档数据何时加载完全,以及为什么它不会在单击UL分页元素时运行?
I've provided the translation for your code as requested. If you need any further assistance, please let me know.
<details>
<summary>英文:</summary>
I'm trying to write a Tampermonkey script to extend a business web app I use. In a very basic sense, certain URL's appear on the page, I need to extract a number from the URL then use than number to build a new link and append to the parent element.
So far I have this but it's not working when I click on the element (pagination just an UL) or on document load. I know the function works as when I set it to run on clicking anywhere in the document it works. It's almost like the page isn't fully loaded when JS reports it is loaded.
(function() {
'use strict';
//get the pagination element
var element = document.getElementsByClassName('pagination-sm');
element.onclick = createLinks;
document.onload = createLinks;
function createLinks() {
var links = document.querySelectorAll ("a[href*='/Field/POPendingCreate/']");
for (var J = links.length-1; J >= 0; --J) {
var thisLink = links[J];
console.log(thisLink.href);
var ppon = thisLink.href.match(/\d+/)[0];
console.log(ppon);
var a = document.createElement('a');
var linkText = document.createTextNode("Preview Order");
a.appendChild(linkText);
a.title = "Preview Order";
a.href = "https://website.com/Field/DownloadPendingPO?POPPKeyID=" + ppon + "&co=1&po=" + ppon;
a.target = "_blank";
var parentNode = thisLink.parentNode;
console.log(parentNode);
parentNode.appendChild(a);
}
}
})();
The UL element just looks like this:
<ul uib-pagination="" items-per-page="formData.itemPerPage" class="pagination-sm ng-pristine ng-untouched ng-valid ng-scope ng-isolate-scope pagination ng-not-empty" data-total-items="pendingList.length" data-ng-model="formData.currentPage" data-max-size="10" data-ng-if="!attachmentView && filteredDocuments.length > 0" role="menu"><!-- ngIf: ::boundaryLinks -->
<!-- ngIf: ::directionLinks --><li role="menuitem" ng-if="::directionLinks" ng-class="{disabled: noPrevious()||ngDisabled}" class="pagination-prev ng-scope disabled"><a href="" ng-click="selectPage(page - 1, $event)" ng-disabled="noPrevious()||ngDisabled" uib-tabindex-toggle="" class="ng-binding" disabled="disabled" tabindex="-1">Previous</a></li><!-- end ngIf: ::directionLinks -->
<!-- ngRepeat: page in pages track by $index --><li role="menuitem" ng-repeat="page in pages track by $index" ng-class="{active: page.active,disabled: ngDisabled&&!page.active}" class="pagination-page ng-scope active"><a href="" ng-click="selectPage(page.number, $event)" ng-disabled="ngDisabled&&!page.active" uib-tabindex-toggle="" class="ng-binding">1</a></li><!-- end ngRepeat: page in pages track by $index -->
<!-- ngIf: ::directionLinks --><li role="menuitem" ng-if="::directionLinks" ng-class="{disabled: noNext()||ngDisabled}" class="pagination-next ng-scope disabled"><a href="" ng-click="selectPage(page + 1, $event)" ng-disabled="noNext()||ngDisabled" uib-tabindex-toggle="" class="ng-binding" disabled="disabled" tabindex="-1">Next</a></li><!-- end ngIf: ::directionLinks -->
<!-- ngIf: ::boundaryLinks -->
</ul>
As I said above the function works as expected when I set it to run on clicking anywhere on the document. More puzzling to me is that it doesn't work when using document.onload. It's like the page only starts loading data in once I start interacting with it. The reason why I'm trying to have the function run when clicking on the pagination is because the page appears to get all the data and store it somewhere (I can't see) then just flicks through the pages when paginating. So once the pagination is clicked I really need to run the function on the links that are generated on the new page.
Seems like I need to delay running document.onload or some other way of knowing once the document data has loaded and also work out why it won't run when clicking on the UL pagination element?
</details>
# 答案1
**得分**: 2
以下是您要翻译的内容:
"Instead of waiting for the page to render and then looping through all the elements to attach an anchor tag. Just use a MutationObserver to handle any elements that get rendered after you have run your logic.
**JS**
```js
(function() {
'use strict';
const createLinks = function ( nodeElement ){
const queryElem = nodeElement.parentElement || nodeElement;
const links = queryElem.querySelectorAll("a[href*='/Field/POPendingCreate/']");
for ( const link of links || [] ){
// Skip link if Preview has been attached
if ( link.createLinkReady ) continue;
// Get numbers from link href
const [ ppon ] = link.href.match(/\d+/);
// Create an anchor tag
const a = document.createElement('a');
a.innerHTML = 'Preview Order';
a.setAttribute( 'title', 'Preview Order' );
a.setAttribute( 'href', `https://website.com/Field/DownloadPendingPO?POPPKeyID=${ppon}&co=1&po=${ppon}` );
a.setAttribute( 'target', '_blank' );
a.setAttribute( 'rel', 'nofollow' );
// Append anchor tag to parent element
link.parentElement.appendChild( a );
link.createLinkReady = true;
}
}
// Create DOM MutationObserver
const Observer = new MutationObserver( function( mutationsList ) {
// Loop through mutations
for ( const mutation of mutationsList || [] ) {
// Loop through added nodes
for ( const node of mutation.addedNodes || [] ){
// Run createLinks on node
createLinks( node );
}
}
});
// Observe DOM for new elements starting from document.body
Observer.observe( document.body, { childList:true, subtree:true } );
// Process links that have been rendered
createLinks( document.body );
})();
请注意,我已将代码中的HTML实体编码(如"
和'
)还原为正常的引号和双引号。
英文:
Instead of waiting for the page to render and then looping through all the elements to attach an anchor tag. Just use a MutationObserver to handle any elements that get rendered after you have run your logic.
JS
(function() {
'use strict';
const createLinks = function ( nodeElement ){
const queryElem = nodeElement.parentElement || nodeElement;
const links = queryElem.querySelectorAll("a[href*='/Field/POPendingCreate/']");
for ( const link of links || [] ){
// Skip link if Preview has been attached
if ( link.createLinkReady ) continue;
// Get numbers from link href
const [ ppon ] = link.href.match(/\d+/);
// Create an anchor tag
const a = document.createElement('a');
a.innerHTML = 'Preview Order';
a.setAttribute( 'title', 'Preview Order' );
a.setAttribute( 'href', `https://website.com/Field/DownloadPendingPO?POPPKeyID=${ppon}&co=1&po=${ppon}` );
a.setAttribute( 'target', '_blank' );
a.setAttribute( 'rel', 'nofollow' );
// Append anchor tag to parent element
link.parentElement.appendChild( a );
link.createLinkReady = true;
}
}
// Create DOM MutationObserver
const Observer = new MutationObserver( function( mutationsList ) {
// Loop through mutations
for ( const mutation of mutationsList || [] ) {
// Loop through added nodes
for ( const node of mutation.addedNodes || [] ){
// Run createLinks on node
createLinks( node );
}
}
});
// Observe DOM for new elements starting from document.body
Observer.observe( document.body, { childList:true, subtree:true } );
// Process links that have been rendered
createLinks( document.body );
})();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论