innerHTML:如何避免 [英] innerHTML: How To Avoid
问题描述
我正在编写一个插件,将表情符号转换为特定站点的文本块中的图像。简单的答案是使用正则表达式来检测innerHTML上的触发器文本并插入img标签,然后将该字符串返回到 innerHTML 部分中的dom元素。 DOM元素块可能已经具有锚点< a>
和/或文本格式
例如
var textBlock = pItems [i] .innerHTML;
var kissSource ='https://mail.google.com/mail/e/35D';
textBlock = textBlock.replace(/(^ | [^& lt;] | [^& gt;]):\ * / g,< img class ='emoticon'src =' + kissSource +'/>);
- > pItems [i] .innerHTML = textBlock; //< - 我可以避免这样做符合Mozilla插件的要求
关于如何将DOM(或HTML字符串)转换为XML(我知道:HTML!= XLM
https ://developer.mozilla.org/en-US/docs/XUL/School_tutorial/DOM_Building_and_HTML_Insertion?redirectlocale = en-US& redirectslug = XUL_School%2FDOM_Building_and_HTML_Insertion#JSON_Templating
我不知道jQuery,所以如果使用javascript的话可能会很理想。
我应该如何解决这个问题,而不是运行正则表达式对innerHTML,从而避免了这个问题?
非常感谢JennaS
$ b
根据您最近对@Giuseppe的评论,以及您格式不正确的样式您从我的帖子中借用的唯一的解决方案是避免递归或遍历文本字符串寻找您的regEx匹配元素。
- 正如您所建议的,将正则表达式应用于您的字符串。 使用HTMLify字符串解析器完成从该字符串中构建DOM
- 将节点替换为由字符串构建的新DOM节点。 li>
注意:这在拉取AJAX HTML页面时也很有用,您需要在临时DOM对象中解析HTML结果,只想将内容转储到新创建的元素的innerHTML中。另外请注意,使用createDocumentFragment将不适合,因为您不能像DOM树那样浏览片段。
这些步骤听起来很辛苦,但是在Stackoverflow上有几个很棒的帖子,它很容易!
在为你做研究并运行到一个现在已经过时的解决方案和 dom解析器不会为你工作 a>我遇到了@ rob-w的解决方案: dom解析器
您的代码将包含来自@ rob-w链接的DOM解析器以及:
/ *
* DOMParser HTML扩展
* 2012-02-02
*
*通过Eli Gray,http://eligrey.com
*公有领域。
*不作任何明示或暗示的保证。使用您自己的风险。
* /
/ *! //source https://gist.github.com/1129031 * /
/ *全局文档,DOMParser * /
(函数(DOMParser){
use strict;
var DOMParser_proto = DOMParser.prototype;
var real_parseFromString = DOMParser_proto.parseFromString;
// Firefox / Opera / IE在不支持的类型上抛出错误
try {
// WebKit在不支持的类型
上返回null if((new DOMParser).parseFromString(,text / html)){
//原生支持text / html解析
return;
}
} catch(ex){}
DOMParser_proto.parseFromString = function(markup,type){
if(/ ^ \s * text \ / ($:$ | $)/ $。 b $ b var first_elt;
doc_elt.innerHTML =标记;
first_elt = doc_elt.firstElementChild; (doc_elt.childElementCount === 1&&& first_elt.localName.toLowerCase()===html){
doc.replaceChild(first_elt,doc_elt);
if
}
return doc;
} else {
return real_parseFromString.apply(this,arguments);
}
};
}(DOMParser));
autostyle = function(str){
var boldPattern = /(?![^<] *< \ / a>)(^ |<。> | [ ?\s\W _])\ *(\S * \S)\ *($ |< \ /.& GT; | [\s\W _])/克;
var italicsPattern = /(?![^<]*<\/a>)(^|<.>|[\s\W])_(\S.* ?\S)_($ |< \ /.& GT; | [\s\W])/克;
var strikethroughPattern = /(?![^<]*<\/a>)(^|<.>|[\s\W_])-(\S.* ?\S) - ($ |< \ /.& GT; | [\s\W _])/ GI;
var underlinePattern = /(?![^<]*<\/a>)(^|<.>|[\s\W_])!(\S.* ?\S)($ |<!\ /.& GT; | [\s\W _])/ GI;
str = str.replace(strikethroughPattern,'$ 1< s> $ 2< / s> $ 3');
str = str.replace(italicsPattern,'$ 1 $ 2 / $ 3'); $ b $ str = str.replace(boldPattern,'$ 1< b> $ 2< / b> $ 3');
str = str.replace(underlinePattern,'$ 1 u $ 2 $ 3');
return str;
};
emoticonRegexFunction = function(str){
//做某事
return str;
RegexWithoutInnerHTML = function(){
pItems = document.getElementsByTagName('p'); (var k = 0; k< pItems.length; k ++){
var str = pItems [k] .textContent;
str = autostyle(str);
str = emoticonRegexFunction(str);
var doc = new DOMParser()。parseFromString('< p> + str +'< / p>','text / html');
pItems [k] .parentNode.replaceChild(doc.getElementsByTagName('p')[0],pItems [k]);
// pItems [k] .innerHTML = str; //< - 现在不需要innerHTML
}
};
完整的jsbin示例: http://jsbin.com/itiwek/12/edit
享受。
I'm writing a plugin which will convert emoticons to images in a text block for a particular site. The easy answer is to use regular expressions to detect the trigger text on the innerHTML and insert the img tag, then pipe the string back to the dom element in the innerHTML part. The DOM element block may already have anchor <a>
and/or text formatting <b>,<i>,<u>
in the innerHTML part.
For example
var textBlock = pItems[i].innerHTML;
var kissSource = 'https://mail.google.com/mail/e/35D';
textBlock = textBlock.replace(/(^|[^<]|[^>]):\*/g, "<img class='emoticon' src='" + kissSource + "' />");
--> pItems[i].innerHTML = textBlock; //<-can I avoid this to be in compliance with Mozilla addons reqmnts
I searched for quite a few hours on how I might convert a DOM (or HTML string) to XML (I know: HTML!=XLM How to read HTML as XML? but perhaps a portion of a div?) which in turn could be converted to JSON who in turn .. could be converted back into a DOM following: https://developer.mozilla.org/en-US/docs/XUL/School_tutorial/DOM_Building_and_HTML_Insertion?redirectlocale=en-US&redirectslug=XUL_School%2FDOM_Building_and_HTML_Insertion#JSON_Templating
I do not know jQuery, so please if it is possible with javascript that would be ideal.
Should I be solving this problem without running the regular expression against the innerHTML thus avoiding the problme?
Thanks so much, JennaS
Working Solution
Based on your recent comment to @Giuseppe, and your malformed styling that you borrowed from my post the only solution would be to avoid recursion or iterating through the text strings looking for matching elements for your regEx.
- Apply the regex to your string as you are proposing.
- Once finished build a DOM from that string using a HTMLify string parser
- Replace the node with the new DOM node built from the string.
NB: This is also useful when pulling in AJAX HTML page and you need to parse the HTML results in a temporary DOM object but don't want to merely dump the contents into a the innerHTML of a newly created element. Also note that using createDocumentFragment will not be suitable as you cannot navigate a fragment like a DOM tree.
The steps sound hard but there are a few great posts on Stackoverflow which make it easy!
After doing research for you and running into a now obsolete solution and dom parsers which won't work for you I came across a solution from @rob-w: a dom parser
Your code would include the DOM parser from @rob-w link plus:
/*
* DOMParser HTML extension
* 2012-02-02
*
* By Eli Grey, http://eligrey.com
* Public domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
/*! @source https://gist.github.com/1129031 */
/*global document, DOMParser*/
(function (DOMParser) {
"use strict";
var DOMParser_proto = DOMParser.prototype;
var real_parseFromString = DOMParser_proto.parseFromString;
// Firefox/Opera/IE throw errors on unsupported types
try {
// WebKit returns null on unsupported types
if ((new DOMParser).parseFromString("", "text/html")) {
// text/html parsing is natively supported
return;
}
} catch (ex) {}
DOMParser_proto.parseFromString = function (markup, type) {
if (/^\s*text\/html\s*(?:;|$)/i.test(type)) {
var doc = document.implementation.createHTMLDocument("");
var doc_elt = doc.documentElement;
var first_elt;
doc_elt.innerHTML = markup;
first_elt = doc_elt.firstElementChild;
if (doc_elt.childElementCount === 1 && first_elt.localName.toLowerCase() === "html") {
doc.replaceChild(first_elt, doc_elt);
}
return doc;
} else {
return real_parseFromString.apply(this, arguments);
}
};
}(DOMParser));
autostyle = function (str) {
var boldPattern = /(?![^<]*<\/a>)(^|<.>|[\s\W_])\*(\S.*?\S)\*($|<\/.>|[\s\W_])/g;
var italicsPattern = /(?![^<]*<\/a>)(^|<.>|[\s\W])_(\S.*?\S)_($|<\/.>|[\s\W])/g;
var strikethroughPattern = /(?![^<]*<\/a>)(^|<.>|[\s\W_])-(\S.*?\S)-($|<\/.>|[\s\W_])/gi;
var underlinePattern = /(?![^<]*<\/a>)(^|<.>|[\s\W_])!(\S.*?\S)!($|<\/.>|[\s\W_])/gi;
str = str.replace(strikethroughPattern, '$1<s>$2</s>$3');
str = str.replace(italicsPattern, '$1<i>$2</i>$3');
str = str.replace(boldPattern, '$1<b>$2</b>$3');
str = str.replace(underlinePattern, '$1<u>$2</u>$3');
return str;
};
emoticonRegexFunction = function(str) {
//do something
return str;
}
RegexWithoutInnerHTML = function () {
pItems = document.getElementsByTagName('p');
for (var k = 0; k < pItems.length; k++) {
var str = pItems[k].textContent;
str = autostyle(str);
str = emoticonRegexFunction(str);
var doc = new DOMParser().parseFromString('<p>' + str + '</p>', 'text/html');
pItems[k].parentNode.replaceChild(doc.getElementsByTagName('p')[0], pItems[k]);
// pItems[k].innerHTML = str; //<-now do not need innerHTML
}
};
Full working example on jsbin at: http://jsbin.com/itiwek/12/edit
Enjoy.
这篇关于innerHTML:如何避免的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!