#javascript
#javascript
Вопрос:
это моя строка
<img class="img" src="a.png"><img class="img" src="a.png"><img class="img" src="a.png">
я хочу проверить, содержит ли строка только html-теги
dwd<img class="img" src="a.png">dwd<img class="img" src="a.png"><img class="img" src="a.png"> dwd
если содержит какую-либо строку, подобную приведенному выше примеру, я хочу вернуть false
здесь у меня есть некоторый код для проверки этого
function isHTML(str) {
var a = document.createElement('div');
a.innerHTML = str;
for (var c = a.childNodes, i = c.length; i--; ) {
if (c[i].nodeType == 1) return true;
}
return false;
}
isHTML('<a>this is a string</a>') // true
isHTML('this is a string') // false
isHTML('this is a <b>string</b>') // true
как мы можем видеть в третьем примере, он возвращает true, и есть некоторая строка с html-тегами, так как я могу отредактировать это и заставить его возвращать true, если только есть html-теги none text
другой метод здесь, но тот же, что и выше
var isHTML = RegExp.prototype.test.bind(/(<([^>] )>)/i);
isHTML('Testing'); // false
isHTML('<p>Testing</p>'); // true
isHTML('<img src="hello.jpg">'); // true
isHTML('My <p>Testing</p> string'); // true (caution!!!)
isHTML('<>'); // false
это хороший метод, но isHTML('My <p>Testing</p> string'); // true (caution!!!)
здесь я хочу вернуть false, потому что есть некоторая строка с html-тегами
Комментарии:
1. Ваша логика вроде как обратная. Вы должны
return false;
, как только увидите дочерний узел, который не является типом 1, а затемreturn true
в конце.2. @Pointy спасибо, вы можете ответить на это, чтобы другие люди могли видеть ваш ответ
function isHTMLONLY(str) { var a = document.createElement('div'); a.innerHTML = str; for (var c = a.childNodes, i = c.length; i--; ) { if (c[i].nodeType != 1) return false; } return true; }
3. @dailytube нет …
childNodes
включает текстовые узлы… тип равен 3, html-комментарии равны 9, если они вас интересуют4. Не так просто проверить, является ли ввод только HTML (не XML). github.com/sindresorhus/is-html
Ответ №1:
Вариант 1: с помощью регулярного выражения и замены строки:
const isHTML = (str) => !(str || '')
// replace html tag with content
.replace(/<([^>] ?)([^>]*?)>(.*?)</1>/ig, '')
// remove remaining self closing tags
.replace(/(<([^>] )>)/ig, '')
// remove extra space at start and end
.trim();
console.log(isHTML('Testing')); // false
console.log(isHTML('<p>Testing</p>')); // true
console.log(isHTML('<img src="hello.jpg">')); // true
console.log(isHTML('My <p>Testing</p> string')); // false
console.log(isHTML('<p>Testing</p> <p>Testing</p>')); // true
console.log(isHTML('<>')); // false
console.log(isHTML('<br>')); // true
Вариант 2: с помощью DOM API
const isHTML = (str) => {
const fragment = document.createRange().createContextualFragment(str);
// remove all non text nodes from fragment
fragment.querySelectorAll('*').forEach(el => el.parentNode.removeChild(el));
// if there is textContent, then not a pure HTML
return !(fragment.textContent || '').trim();
}
console.log(isHTML('Testing')); // false
console.log(isHTML('<p>Testing</p>')); // true
console.log(isHTML('<img src="hello.jpg">')); // true
console.log(isHTML('My <p>Testing</p> string')); // false
console.log(isHTML('<p>Testing</p> <p>Testing</p>')); // true
console.log(isHTML('<>')); // false
console.log(isHTML('<br>')); // true
Комментарии:
1. Первый не работает для некоторой сложной строки, такой как:
<p>Hey there <strong>sir</strong></p><p>How's it <em>going</em>?</p><p>Is everything <u>well and good?</u></p><p><u>Call me </u><s>in the next one.</s></p><blockquote>Comprende?</blockquote><pre class="ql-syntax __qlSyntax--23mc5" spellcheck="false"><code class="hljs language-stylus"><span class="hljs-function"><span class="hljs-title">print</span><span class="hljs-params">(<span class="hljs-string">'see you on the other side'</span>)</span></span> </code></pre>
, 2-й работает безупречно!
Ответ №2:
это хороший метод, но isHTML('My <p>Testing</p> string'); // true (caution!!!)
Это хороший метод, просто используйте ^
и $
в начале и конце регулярного выражения, и код будет работать.
var isHTML = RegExp.prototype.test.bind(/^(<([^>] )>)$/i);
console.log(isHTML('Testing')); // false
console.log(isHTML('<p>Testing</p>')); // true
console.log(isHTML('<img src="hello.jpg">')); // true
console.log(isHTML('My <p>Testing</p> string')); // true (caution!!!)
console.log(isHTML('<>')); // false
Ответ №3:
Все хорошо. И мое решение
const element = document.querySelector('.test_element');
const setHtml = elem =>{
let getElemContent = elem.innerHTML;
// Clean Up whitespace in the element
// If you don't want to remove whitespace, then you can skip this line
let newHtml = getElemContent.replace(/[nt ] /g, " ");
//RegEX to check HTML
let checkHtml = /<([A-Za-z][A-Za-z0-9]*)b[^>]*>(.*?)</1>/.test(getElemContent);
//Check it is html or not
if (checkHtml){
console.log('This is an HTML');
console.log(newHtml.trim());
}
else{
console.log('This is a TEXT');
console.log(elem.innerText.trim());
}
}
setHtml(element);
Ответ №4:
Вот быстрый и хитрый способ.
Что он делает, так это использует встроенный синтаксический анализ xml вашего браузера для обработки всего вложенного материала (что обычно непросто с регулярным выражением js). Затем он проникает в элемент и его дочерние элементы в поисках любых текстовых узлов.
function isOnlyHTML(testMe) {
const testMeEl = document.createElement("div");
testMeEl.innerHTML = testMe; // browser does the parsing
return hasNoTextChildren(testMeEl);
}
// recursively check for text elements
function hasNoTextChildren(element) {
for (let i = 0; i < element.childNodes.length; i ) {
const child = element.childNodes[i];
if (child instanceof Text) {
return false;
} else if(hasNoTextChildren(child) === false) {
return false;
}
}
return true;
}
РЕДАКТИРОВАТЬ: из ваших тестов видно, что вы просто пытаетесь найти, является ли строка отдельным элементом html, без текста до или после (но, возможно, внутри). Если это так, другого ответа о добавлении ^
и $
к вашему регулярному выражению, возможно, сначала выполнить обрезку, будет достаточно.