Кодировать html-объекты в javascript
Я работаю в CMS, который позволяет пользователям вводить контент. Проблема в том, что при добавлении символов ®
он может не отображаться хорошо во всех браузерах. Я хотел бы настроить список символов, которые нужно искать, а затем преобразовать в соответствующий объект html. Например
® = > ®
& Амп; = > &
© = > ©
™ = > ™
После преобразования его нужно обернуть в тег <sup>
, в результате получится следующее:
®
= > <sup>®</sup>
Поскольку необходим конкретный размер шрифта и стиль заполнения:
sup { font-size: 0.6em; padding-top: 0.2em; }
Будет ли JavaScript похожим на это?
var regs = document.querySelectorAll('®');
for ( var i = 0, l = imgs.length; i < l; ++i ) {
var [?] = regs[i];
var [?] = document.createElement('sup');
img.parentNode.insertBefore([?]);
div.appendChild([?]);
}
Где "[?]" означает, что есть что-то, о чем я не уверен.
Дополнительные сведения:
- Я хотел бы сделать это с использованием чистого JavaScript, а не того, что
спасибо библиотеке, как jQuery, спасибо.
- Backend - Ruby
- Использование RefineryCMS, построенного с помощью Ruby on Rails
Ответы
Ответ 1
Вы можете использовать регулярное выражение для замены любого символа в данном юникодном диапазоне с его эквивалентом сущности html. Код будет выглядеть примерно так:
var encodedStr = rawStr.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#'+i.charCodeAt(0)+';';
});
Этот код заменит все символы в данном диапазоне (unicode 00A0 - 9999, а также амперсанд, больше и меньше) с их эквивалентами сущностей html, который просто &#nnn;
, где nnn
- это значение unicode, которое мы получить от charCodeAt
.
Смотрите здесь: http://jsfiddle.net/E3EqX/13/ (в этом примере используется jQuery для селекторов элементов, используемых в примере., не использует jQuery)
Выполнение этих преобразований не решает всех проблем - убедитесь, что вы используете кодировку символов UTF8, убедитесь, что ваша база данных хранит строки в UTF8. Вы еще можете видеть экземпляры, в которых символы отображаются неправильно, в зависимости от конфигурации системного шрифта и других проблем из-под вашего контроля.
Documentation
Ответ 2
В настоящее время принятый ответ имеет несколько проблем. Этот пост объясняет их и предлагает более надежное решение. Решение, предложенное в этом ответе:
var encodedStr = rawStr.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#' + i.charCodeAt(0) + ';';
});
Флаг i
является избыточным, поскольку ни один символ Unicode в диапазоне от U + 00A0 до U + 9999 не имеет варианта в верхнем/нижнем регистре, который находится за пределами того же диапазона.
Флаг m
является избыточным, потому что ^
или $
не используются в регулярном выражении.
Почему диапазон от U + 00A0 до U + 9999? Это кажется произвольным.
В любом случае, для решения, которое правильно кодирует все, кроме безопасных и печатаемых символов ASCII на входе (включая астральные символы!), И реализует все именованные ссылки на символы (не только в HTML4), используйте библиотеку he (отказ от ответственности: эта библиотека моя). Из его README:
он (для "сущностей HTML") - надежный кодер/декодер сущностей HTML, написанный на JavaScript. Он поддерживает все стандартизированные именованные ссылки на символы в соответствии с HTML, обрабатывает неоднозначные амперсанды и другие крайние случаи так же, как это делает браузер, имеет обширный набор тестов и - в отличие от многих других решений JavaScript - он прекрасно обрабатывает астральные символы Юникода. Онлайн демо доступно.
Также см. Этот соответствующий ответ.
Ответ 3
У меня была такая же проблема, и я создал 2 функции для создания сущностей и перевода их обратно к нормальным символам.
Следующие методы переводят любую строку в объекты HTML и обратно на прототипе String
/**
* Convert a string to HTML entities
*/
String.prototype.toHtmlEntities = function() {
return this.replace(/./gm, function(s) {
return "&#" + s.charCodeAt(0) + ";";
});
};
/**
* Create string from HTML entities
*/
String.fromHtmlEntities = function(string) {
return (string+"").replace(/&#\d+;/gm,function(s) {
return String.fromCharCode(s.match(/\d+/gm)[0]);
})
};
Затем вы можете использовать его следующим образом:
var str = "Test´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en tést".toHtmlEntities();
console.log("Entities:", str);
console.log("String:", String.fromHtmlEntities(str));
Вывод в консоли:
Entities: Dit is e´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en t£eést
String: Dit is e´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en t£eést
Ответ 4
Без какой-либо библиотеки, если вам не нужно поддерживать IE < 9, вы можете создать элемент html и установить его содержимое Node.textContent:
var str = "<this is not a tag>";
var p = document.createElement("p");
p.textContent = str;
var converted = p.innerHTML;
Вот пример: https://jsfiddle.net/1erdhehv/
Ответ 5
Вы можете использовать это.
var escapeChars = {
'¢' : 'cent',
'£' : 'pound',
'¥' : 'yen',
'€': 'euro',
'©' :'copy',
'®' : 'reg',
'<' : 'lt',
'>' : 'gt',
'"' : 'quot',
'&' : 'amp',
'\'' : '#39'
};
var regexString = '[';
for(var key in escapeChars) {
regexString += key;
}
regexString += ']';
var regex = new RegExp( regexString, 'g');
function escapeHTML(str) {
return str.replace(regex, function(m) {
return '&' + escapeChars[m] + ';';
});
};
https://github.com/epeli/underscore.string/blob/master/escapeHTML.js
var htmlEntities = {
nbsp: ' ',
cent: '¢',
pound: '£',
yen: '¥',
euro: '€',
copy: '©',
reg: '®',
lt: '<',
gt: '>',
quot: '"',
amp: '&',
apos: '\''
};
function unescapeHTML(str) {
return str.replace(/\&([^;]+);/g, function (entity, entityCode) {
var match;
if (entityCode in htmlEntities) {
return htmlEntities[entityCode];
/*eslint no-cond-assign: 0*/
} else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
return String.fromCharCode(parseInt(match[1], 16));
/*eslint no-cond-assign: 0*/
} else if (match = entityCode.match(/^#(\d+)$/)) {
return String.fromCharCode(~~match[1]);
} else {
return entity;
}
});
};
Ответ 6
Если вы хотите избежать кодирования HTML-сущностей более одного раза
function encodeHTML(str){
return str.replace(/[\u00A0-\u9999<>&](?!#)/gim, function(i) {
return '&#' + i.charCodeAt(0) + ';';
});
}
function decodeHTML(str){
return str.replace(/&#([0-9]{1,3});/gi, function(match, num) {
return String.fromCharCode(parseInt(num));
});
}
пример
var text = "<a>Content</a>";
text = encodeHTML(text);
console.log("Encode 1 times: " + text);
// <a>Content</a>
text = encodeHTML(text);
console.log("Encode 2 times: " + text);
// <a>Content</a>
text = decodeHTML(text);
console.log("Decoded: " + text);
// <a>Content</a>
Ответ 7
Если вы уже используете jQuery, попробуйте html()
.
$('<div>').text('<script>alert("gotcha!")</script>').html()
// "<script>alert("gotcha!")</script>"
Создается текст в памяти node, и на него вызывается html()
.
Это некрасиво, он отнимает немного памяти, и я понятия не имею, насколько он настолько тщателен, как что-то вроде библиотеки he
, но если вы уже используете jQuery, возможно, это вариант для вас.
Взято из сообщения в блоге Кодировать объекты HTML с jQuery от Felix Geisendörfer.
Ответ 8
Специальные символы HTML и ESCAPE CODES
Зарезервированные символы должны быть экранированы HTML: мы можем использовать escape-символ символа для обозначения любого символа Юникода [Ex: и - U + 00026] в HTML, XHTML или XML, используя только символы ASCII. Числовые символьные ссылки [Пример: ampersand (& ) - &
] и Именованные символьные ссылки [Ex: &
] являются типами character escape used in markup
.
Original Character XML entity replacement XML numeric replacement
< < <
> > >
" " "
& & &
' ' '
Чтобы отображать HTML-теги как обычную форму на веб-странице, мы используем теги <pre>
, <code>
или можем их избежать. Экранирование строки путем замены любым вхождением символа "&"
на строку "&"
и любые вхождения символа ">"
по строке ">"
. Пример: stackoverflow post
function escapeCharEntities() {
var map = {
"&": "&",
"<": "<",
">": ">",
"\"": """,
"'": "'"
};
return map;
}
var mapkeys = '', mapvalues = '';
var html = {
encodeRex : function () {
return new RegExp(mapkeys, 'gm');
},
decodeRex : function () {
return new RegExp(mapvalues, 'gm');
},
encodeMap : JSON.parse( JSON.stringify( escapeCharEntities () ) ),
decodeMap : JSON.parse( JSON.stringify( swapJsonKeyValues( escapeCharEntities () ) ) ),
encode : function ( str ) {
return str.replace(html.encodeRex(), function(m) { return html.encodeMap[m]; });
},
decode : function ( str ) {
return str.replace(html.decodeRex(), function(m) { return html.decodeMap[m]; });
}
};
function swapJsonKeyValues ( json ) {
var count = Object.keys( json ).length;
var obj = {};
var keys = '[', val = '(', keysCount = 1;
for(var key in json) {
if ( json.hasOwnProperty( key ) ) {
obj[ json[ key ] ] = key;
keys += key;
if( keysCount < count ) {
val += json[ key ]+'|';
} else {
val += json[ key ];
}
keysCount++;
}
}
keys += ']'; val += ')';
console.log( keys, ' == ', val);
mapkeys = keys;
mapvalues = val;
return obj;
}
console.log('Encode: ', html.encode('<input type="password" name="password" value=""/>') );
console.log('Decode: ', html.decode(html.encode('<input type="password" name="password" value=""/>')) );
O/P:
Encode: <input type="password" name="password" value=""/>
Decode: <input type="password" name="password" value=""/>
Ответ 9
Иногда вы просто хотите кодировать каждый символ... Эта функция заменяет "все, кроме ничего" в regxp.
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
function encode(w) {
return w.replace(/[^]/g, function(w) {
return "&#" + w.charCodeAt(0) + ";";
});
}
test.value=encode(document.body.innerHTML.trim());
<textarea id=test rows=11 cols=55>www.WHAK.com</textarea>
Ответ 10
var htmlEntities = [
{regex:/&/g,entity:'&'},
{regex:/>/g,entity:'>'},
{regex:/</g,entity:'<'},
{regex:/"/g,entity:'"'},
{regex:/á/g,entity:'á'},
{regex:/é/g,entity:'é'},
{regex:/í/g,entity:'í'},
{regex:/ó/g,entity:'ó'},
{regex:/ú/g,entity:'ú'}
];
total = <some string value>
for(v in htmlEntities){
total = total.replace(htmlEntities[v].regex, htmlEntities[v].entity);
}
Массивное решение
Ответ 11
replaceHtmlEntities(text) {
var tagsToReplace = {
'&': '&',
'<': '<',
'>': '>',
};
var newtext = text;
for (var tag in tagsToReplace) {
if (Reflect.apply({}.hasOwnProperty, this, [tagsToReplace, tag])) {
var regex = new RegExp(tag, 'g');
newtext = newtext.replace(regex, tagsToReplace[tag]);
}
}
return newtext;
}
Ответ 12
function encodeHTML(str) {
return document.createElement("a").appendChild(
document.createTextNode(str)).parentNode.innerHTML;
};
function decodeHTML(str) {
var element = document.createElement("a");
element.innerHTML = str;
return element.textContent;
};
var str = "<"
var enc = encodeHTML(str);
var dec = decodeHTML(enc);
console.log("str: " + str, "\nenc: " + enc, "\ndec: " + dec);
Ответ 13
Вы можете использовать метод charCodeAt()
, чтобы проверить, имеет ли указанный символ значение выше 127 и преобразует его в цифровую ссылку с помощью toString(16)
.