#javascript #jquery
#javascript #jquery
Вопрос:
Я пишу JavaScript, который просматривает HTML-документ и находит все экземпляры ключевого слова, которые НЕ являются ссылками — не внутри <a>
тега. Например, давайте возьмем следующий HTML, и я ищу ключевое слово «ноутбуки».
<p>I love laptops so much and these are <a href="mylink">some of my <i>favorite laptops</i></a>. Don't you love laptops also?</p>
Итак, мне нужен способ вернуть экземпляры 1 и 3 здесь, но не номер 2, потому что он находится внутри ссылки. Я не уверен, что правильный способ сделать это — использовать регулярное выражение (я не могу подобрать подходящее для этого) или выполнить итерацию через DOM или что-то в этом роде. Я могу использовать либо jQuery, либо прямой JS.
Комментарии:
1. вы уже пробовали что-нибудь? Если да, пожалуйста, покажите это, возможно, мы сможем исправить это для вас
2. Что именно вы хотите? Я полагаю, что такой массив, как
['laptop', 'laptop']
, был бы не слишком полезен.3.
instances 1 and 3 here,
Какие экземпляры вы вызываете, потому что, как показывает DOM, у вас естьp
элемент, который содержитa
элемент, который содержитi
элемент. IOW: вашp
элемент содержит все 3 ноутбука, так что мы должны вернуть?.4. Поскольку вы тестируете иерархию DOM, я бы избегал разбора строк, потому что это будет чрезвычайно сложно и хрупко. Может подойти настоящий синтаксический анализатор HTML. Возможно, анализатор DOM?
5. «проблема» тривиальна. но отсутствие каких-либо усилий с вашей стороны действительно мешает людям помогать вам.
Ответ №1:
Предполагая, что вам нужен список элементов, содержащих ‘laptop’, это может помочь вам начать:
let elements = [...document.querySelectorAll('*')]
.filter(e =>
!e.closest('A') amp;amp;
[...e.childNodes].some(c =>
c.nodeType === 3 amp;amp; c.textContent.match(/blaptops?b/i)));
elements.forEach(e => e.style.border = '1px solid black');
* {padding: 5px;}
<div>child text is not considered so this div will not be returned.
<div>laptop, this div will be returned.</div>
<div>this div will not.</div>
<a>laptop in anchor tags are ignored. <span> nested laptop inside anchor tags are also not returned.</span></a>
</div>
<div>plural and capital LapTops will also work, this div will be returned.
<div>this laptop div will also be returned.</div>
<div>but parent text is not considered so this div won't be returned.</div>
</div>
Комментарии:
1. @canon, нет, это не сработает. На самом деле мой фрагмент содержит такой пример, взгляните на 1-й div «дочерний текст не учитывается, поэтому этот div не будет возвращен»
2. Я понимаю, что вы имеете в виду. Неясно, какое ожидаемое поведение для вашего описанного сценария, и я предпочитаю предполагать, что требуется самое простое решение. Спасибо за объяснение.
3. Вы снова правы. 🙂 Я прибегну к аргументу «это тривиально для обхода
.parentElement
и проверки на этот случай, и OP выиграет от выполнения этого самостоятельно».4. Обновлено, даже не знал, что этот метод существует, спасибо!
5. Большое спасибо за это. Это отлично работает, но есть одно предостережение. Если в элементе имеется более одного экземпляра ключевого слова, это не указывает на смещение для каждого или на то, что существует более одного. И если в элементе есть несколько экземпляров, и один связан, а другой нет, я не знаю, как определить, какой из них какой.