I'm trying to write a Tampermonkey script to extend a commercial web application I use. In a very basic sense, some URL appears on the page and I need to extract a number from the URL and then use that number to build a new link and append it to the parent element.
So far I have this but it doesn't work when I click on the element (pagination is just UL) or when the document loads. I know the function works as if I set it to run when I click anywhere in the document it works. When JS reports that a page has loaded, it's almost like the page hasn't fully loaded yet.
(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 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, when I set it to run when I click anywhere on the document, the function works as expected. What confuses me even more is that it doesn't work when using document.onload. It's like the page only starts loading data after I start interacting with it. The reason I'm trying to run the function when pagination is clicked is because the page seems to get all the data and store it somewhere (that I can't see) and then just flick the page when pagination is clicked. So I do need to run the function on the generated link on the new page once pagination is clicked.
It seems like I need to delay running document.onload or some other way to understand after the document data is loaded and figure out why it doesn't run when the UL pagination element is clicked?
Instead of waiting for the page to render and then looping through all elements to append anchor tags. Just use a MutationObserver to handle any elements that are rendered after running your logic.
JS