Минимальный пример: ожидаемое поведение определяется тестами Жасмин:
$(document).ready(function() {
function thereIsImportantContent(id) {
return $(id).find("strong").filter(function() {
var index = $(id).text().indexOf($(this).text());
return 0 <= index && index <= 20;
}).length > 0;
}
// specs code
describe("thereIsImportantContent", function() {
it("accept strong near head", function() {
expect(thereIsImportantContent($("#test_case_1")[0])).toBeTruthy();
});
it("accept strong near head with children", function() {
expect(thereIsImportantContent($("#test_case_2")[0])).toBeTruthy();
});
it("accept wrapped strong near head", function() {
expect(thereIsImportantContent($("#test_case_3")[0])).toBeTruthy();
});
it("reject strong further down", function() {
expect(thereIsImportantContent($("#test_case_4")[0])).toBeFalsy();
});
it("reject strong further down with copies near head", function() {
expect(thereIsImportantContent($("#test_case_5")[0])).toBeFalsy();
});
});
// load jasmine htmlReporter
(function() {
var env = jasmine.getEnv();
env.addReporter(new jasmine.HtmlReporter());
env.execute();
}());
});
container {
display: none;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css">
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<container id="test_case_1">
<!-- strong content at the beginning -> accept -->
<p>Some <strong>content</strong></p>
...
<p>other text</p>
...
<p>Hey look: <strong>content</strong>!</p>
</container>
<container id="test_case_2">
<!-- handle strong with children correctly -->
<strong>Hey look: <span> content!</span></strong>
</container>
<container id="test_case_3">
<p>Test</p>
<p>Hey <strong>content!</strong></p>
</container>
<container id="test_case_4">
<p>Something</p>
...
<p>other text</p>
...
<!-- strong content but located further down -> reject -->
<p>Hey look: <strong>content</strong>!</p>
</container>
<container id="test_case_5">
<!-- same text as in strong below triggering false accept -->
<p>Some content</p>
...
<p>other text</p>
...
<!-- strong content but located further down -> should eject -->
<p>Hey look: <strong>content</strong>!</p>
</container>
Мой пример использования: как часть пользовательского сценария, который пытается найти потенциальные заголовки сайта:
Предполагая, что у меня есть веб-сайт, который выглядит следующим образом:
<container>
<p>Some <strong>content</strong></p>
...
<p>other text</p>
...
<p>Hey look: <strong>content</strong>!</p>
</container>
Я ищу способ найти важные элементы, такие как (например, h1, h2, strong, ...), которые визуально находятся рядом сначало видимого текста.
Выше код выглядит для пользователя примерно так:
Некоторый контент
...
другой текст
...
Эй, смотри: content !
Мой нынешний подход - оценить container.text().indexOf(elementOfIntrest.text())
и использовать только их с низким индексом ...
container.find("strong").slice(0,10).filter(function () {
var index = container.text().indexOf($(this).text());
console.log("Testing: " + $(this).text(), " index: " + index);
return 0 <= index && index <= 50
});
Но я понял, что это работает только в том случае, если важный контент отсутствует в обычном тексте на более раннем этапе.
Например:
<container>
<p>Some content</p> <---position where the text "content" was found and
^ wrongly accepted
... |Potentially important
<p>really long text</p> |Element with text "content"
... |should be ignored as its far away
|from the start of the text
<p>Hey look: <strong>content</strong>!</p>
</container>
indexOf
находит «контент» из сильного элемента во второй строке и принимает его.
В: как эффективно фильтровать элементы HTML по их расстоянию доначало заданного элемента-предка, считается в символах?