3

Given this HTML on the target page:

<dd class="ddTit">
<a href="http://abc.xxx.com/54781.html" target="_blank">special text words</a>
</dd>

How can I get the url based on the "special text words", and do the click in a Greasemonkey script?

I tried this:

var textlink = document.querySelector ("dd.ddTit a[textContent*='special']");
var clickEvent      = document.createEvent ('MouseEvents');
clickEvent.initEvent ('click', true, true);
textlink.dispatchEvent (clickEvent);

with no luck.

How do I select based on the textContent, such as textContent contains the word special?

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
user1663601
  • 65
  • 1
  • 6

3 Answers3

3

Alas, you cannot do it with querySelector() because CSS selectors do not (yet) offer a content/text selector.

Here's 3 approaches:

  1. Loop through a targeted selection of nodes:

    var ddTitLinks  = document.querySelectorAll ("dd.ddTit a");
    
    for (var J = ddTitLinks.length - 1;  J >= 0;  --J) {
        var ddTitLink   = ddTitLinks[J];
        //--- Case-insensitive search.
        if (/special text words/i.test (ddTitLink.textContent) ) {
            var clickEvent      = document.createEvent ('MouseEvents');
            clickEvent.initEvent ('click', true, true);
            ddTitLink.dispatchEvent (clickEvent);
            break;
        }
    }
    


  2. Use jQuery (a powerful library that will save you a ton of grief):

    // ==UserScript==
    // @name     _Click Special link(s)
    // @include  http://YOUR_SERVER.COM/YOUR_PATH/*
    // @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
    // ==/UserScript==
    
    //--- Note that contains() is CASE SENSITIVE.
    var specLink    = $("dd.ddTit a:contains('special text words')");
    if (specLink.length) {
        var clickEvent  = document.createEvent ('MouseEvents');
        clickEvent.initEvent ('click', true, true);
        specLink[0].dispatchEvent (clickEvent);
    }
    


  3. Use XPath:

    //--- Note that contains() is CASE SENSITIVE.
    var specLinks   = document.evaluate (
        "//dd[contains(@class, 'ddTit')]/a[contains(text(), 'special text words')]",
        document,
        null,
        XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
        null
    );
    
    if (specLinks.snapshotLength) {
        var specLink    = specLinks.snapshotItem (0);
        var clickEvent  = document.createEvent ('MouseEvents');
        clickEvent.initEvent ('click', true, true);
        specLink.dispatchEvent (clickEvent);
    }
    
Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • Thank you so much, i tested the three methods, all works well. But for the first method, **/special text words/** if the special text words contains the symbol of **/**, it will meet some problem. from my test, the JQurey method is more faster and stronger, is that true? i like it. And sometimes links contain the **special text words** in the page have more than one, and how to make them all work, i mean open all the links contain the **special text words**? Thanks. – user1663601 Sep 12 '12 at 06:56
  • That's over and beyond what you asked in this question. This question is answered as asked. **Mark it so and ask a new question with the additional requirements.** Like how do you invision opening all the links? As soon as you open one, the new page replaces the current one. Do you want to open a bunch of links in new tabs? State all of that in the new question. – Brock Adams Sep 12 '12 at 07:17
  • Sorry @BrockAdams, when i test the scripts, i chose the last part on a page, and i found the opened tab was not the link i expected. so i checked and found on that page there were more than one link meet the condition of that **special text words**. sorry about that, and thanks again. i learned a lot from that. i will ask a new question about that situation. – user1663601 Sep 12 '12 at 08:47
  • [link](http://stackoverflow.com/questions/6466856/greasemonkey-jquery-script-to-click-links) has the answer of how to open the all link meet the condition. – user1663601 Sep 12 '12 at 11:36
  • Okay, good. That's why I asked what you meant. Contrast: (A) Clicking links, no new page loads, (B) Opening link, new page loads, (C) Opening multiple links to multiple tabs or windows, (D) Opening multiple links (new pages load) but sequentially, with usually a delay between each new page. – Brock Adams Sep 12 '12 at 12:06
1

Here it is a greasemonkey script using jquery that performs what you want:

// ==UserScript==
// @name       your script
// @namespace  http://foobarfoobar.com/
// @version    0.1
// @description  Trigger click with jquery
// @require    http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// @match      http://*/*
// ==/UserScript==

(function () {
    $(document).ready(function(){
        $('dd.ddTit').find("a:contains('special text words')").bind('click', function() {
            window.location.href = this.href;
            return false;
        }).trigger('click');

    });
})();

if you copy some of this code to your script make sure to include the line:

// @require    http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js

so the jquery code works well, also adjust the @match rule to the specific site you want to apply the script.

Nelson
  • 49,283
  • 8
  • 68
  • 81
  • No problem, I've just removed it. – Nelson Sep 12 '12 at 07:25
  • @Brock, Nelson: A copyright notice seems perfectly fine to me. You _do_ retain copyright to your posts here, you just have to agree to license them under CC-By-SA (which allows others to copy, redistribute and modify them, as long as they attribute you and release their modifications under the same license). In fact, one could argue that such a notice is actually helpful, in that it makes complying with the attribution requirement easier. – Ilmari Karonen Sep 12 '12 at 14:42
0

If you really have nothing but the content to identify the link, you may have to loop over all links to find the one you want:

var links = document.getElementsByTagName( 'a' );

for ( var i = 0; i < links.length; i++ ) {
    var link = links[i];
    if ( /special/.test( link.textContent ) ) {
        // do something with link
    }
}
Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153