Joe Berg
Joe Berg

Reputation: 381

Find element by innerHTML to call angular ng-click from injected javascript

I am trying to call ng-click from a specific a-tag on the webpage from an injected script.

How could I find the exact a-tag from my page? I know if I had a class-name that I could write ($('a.classname')), but is there a way to find the tag which contains innerHTML Apple?

If not, would it be possible to call ng-click, as it is the 10th a-tag on the page? As a[10]?

Tag on page:

    <a ng-click="myFunction()">Apple</a>

Injected script:

    angular.element($('a')).scope().$apply(function() {
    angular.element($('a')).scope().myFunction();
    });

Upvotes: 0

Views: 380

Answers (2)

Joe Berg
Joe Berg

Reputation: 381

In regards to my comment about xpath in answer by charlietfl, thought I would also share the example I was referring to.

// by specific anchor tag from full xpath

var nodesSnapshot = document.evaluate("//html/body/div[1]/a[1]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
{
nodesSnapshot.snapshotItem(i).click();
nodesSnapshot.snapshotItem(i).style.background = 'yellow';
console.log('Clicked first <' + nodesSnapshot.snapshotItem(i).tagName + '> tag and marked it yellow')
}

// or by specific anchor tag from xpath by index that contains the text

var nodesSnapshot = document.evaluate("//a[3][text()[contains(., 'Apple')]]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
{
nodesSnapshot.snapshotItem(i).click();
nodesSnapshot.snapshotItem(i).style.background = 'pink';
console.log('Clicked third <' + nodesSnapshot.snapshotItem(i).tagName + '> tag that contains ' + nodesSnapshot.snapshotItem(i).text + ' and marked it pink')
}
<div ng-app="app" ng-controller="MainCtrl">
  <text>1: </text><a ng-click="myFunction()">Apple</a>
  <text>2: </text><a ng-click="myFunction()">Apple</a>
  <text>3: </text><a ng-click="myFunction()">Apple</a>
</div>

Upvotes: 0

charlietfl
charlietfl

Reputation: 171679

If you are trying to do this externally, such as in an extension or from console, you could just trigger click event on the targeted element.

You could use eq() to target the index of <a> or use :contains selector or for more granularity of testing the text use filter()

angular
  .module('app', [])
  .controller('MainCtrl', ($scope) => {
    $scope.myFunc = (val) => {
      console.log('Clicked value = ', val)
    };
  });

// from outside angular app
setTimeout(() => {
  // by index
  $('a').eq(3).click()
  // or by text contains
  $('a:contains(Apple)').click();
  // using filter()
  $('a').filter(function() {
    return this.textContent.trim() === 'Apple';
  }).click();

}, 500)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.js"></script>

<div ng-app="app" ng-controller="MainCtrl">
  <a href ng-click="myFunc(1)">1</a>
  <a href ng-click="myFunc(2)">2</a>
  <a href ng-click="myFunc(3)">3</a>
  <a href ng-click="myFunc(4)">Apple</a>
</div>

Upvotes: 2

Related Questions