3
<div>Some reallllly
realllyyy long text</div>

will render as Some reallllly realllyyy long text because HTML removes the line breaks.

But I can't find the div using the :contains() CSS selector because of the line break:

// Returns an empty array
$(':contains("Some reallllly realllyyy long text")');

Is there a way to select the div and ignore the line-break?

Note: I don't want to add the line break in the selector, I want to be able to select the div without knowing there is a line break (because I use the text that the user can see, and he can't see the line break)

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
  • 2
    Why don't you use some unique identifiers for your divs? What you are doing right now is basically the ugliest thing I've seen. `
    Some reallllly realllyyy long text
    ` would be much simpler to handle.
    – slash197 Jul 11 '13 at 09:25
  • var str = "Some reallllly realllyyy long text"; str = str.replace(/(\r\n|\n|\r)/gm,""); $(':contains('+str+')');, Hey, can you try this – RONE Jul 11 '13 at 09:27
  • @slash197 In general, I agree with you, but this is not for front end javascript. This is to write functional tests (Selenium). So it's better to say "I click on button 'Validate'" rather than "I click on button '#superId'" because the first one has a functional meaning. – Matthieu Napoli Jul 11 '13 at 09:33
  • 2
    @MMM I'm looking for a solution. That's what stackoverflow is about you know... – Matthieu Napoli Jul 11 '13 at 09:34
  • @MatthieuNapoli: And I've given you one. – MMM Jul 11 '13 at 09:35
  • @MatthieuNapoli does my answer fits your needs ? – Brewal Jul 11 '13 at 09:50
  • Also, `:contains()` is not a CSS selector (or at least, not anymore). – BoltClock Jul 11 '13 at 09:59

2 Answers2

5

What you could do is overriding the :contains selector :

$.expr[":"].contains = $.expr.createPseudo(function(arg) {
    return function( elem ) {
        return $(elem).text().replace(/(\n)+/g, " ").indexOf(arg) >= 0;
    };
});

See this Fiddle

With such a solution, you don't have to change anything in your code but only add this piece of code. But this is not a good practice.
Of course you could name this selector other way. In this case, you could use both of the behaviours :

$.expr[":"].mycontains

See this other Fiddle

Brewal
  • 8,067
  • 2
  • 24
  • 37
  • This won't work if there is more than one newline character in a row. – MMM Jul 11 '13 at 09:51
  • 1
    You should call "contains" something else, it's not a good idea to overwrite the default "contains" selector with one that does something subtly different. – thirtydot Jul 11 '13 at 09:54
  • 1
    Well, thanks. Now it does. But this is just for the idea. You can do anything you want with this. – Brewal Jul 11 '13 at 09:54
  • 1
    @thirtydot: [An excellent use case for a prefix](http://stackoverflow.com/questions/11748141/can-i-force-jquery-to-use-sizzle-to-evaluate-a-selector-without-using-non-standa/11748913#11748913) – BoltClock Jul 11 '13 at 10:00
0

The concept is very innefficient and so is my answer:

$("div").each(function () {
    if ($(this).text()replace(/(\n)+/g, " ") == "Some reallllly realllyyy long text") {
        // Do something
        $(this).css({color: 'red'});
    }
});

Remember that the browser just happens to render a collection of whitespace characters as a single space. Please rethink your approach.

MMM
  • 7,221
  • 2
  • 24
  • 42
  • 1
    Yeah not really efficient, but it does the job :). About the approach, see in the comments this is for functional validation so I need to select elements by their functional meaning (their label). – Matthieu Napoli Jul 11 '13 at 09:39
  • Actually, `.replace(/\n/g," ")` is better - your answer will only work with one newline, this one will replace all occourencies. – Kamil T Jul 11 '13 at 09:44
  • 1
    Thanks Kamil, however will that not generate more spaces than neccessary? Shouldn't it be like `.replace(/(\n)+/g, " ")`? – MMM Jul 11 '13 at 09:50