我正在尝试隔离(然后操纵)以常见新闻阅读器和电子邮件客户端方式格式化的报价块。
HTML:
<p>
Hello there!
<br />
I'm great, how are you?
<br />
<br />
Someone wrote:
<br />
> Greetings,
<br />
> How are you?
</p>
我需要定位所有以&gt;开头的行,并将它们隐藏为可折叠块。在上面的例子中,“Someone写道:”之后的所有内容都将被隐藏,保存为变量,JS生成的最终结果将是:
<p>
Hello there!
<br />
I'm great, how are you?
<br />
<br />
Someone wrote:
<br />
<a href="#">Click to expand</a>
</p>
Gmail做同样的事情,但是服务器端将报价块包装在<div>
中,由于我的项目的特定性质,完整的过程必须由JS单独完成。
我正在使用jQuery框架。
提前致谢!
答案 0 :(得分:2)
我不相信jquery会像这样分析文本。您必须自己解析以'&gt;'开头的行并根据需要编辑字符串。然后,您可以使用jquery对您添加的元素进行操作。
答案 1 :(得分:1)
我在this pastebin为你准备了一个例子。这是添加了注释的代码。
HTML
<p>
Hello there!
<br />
I'm great, how are you?
<br />
<br />
Someone wrote:
<br />
> Greetings,
<br />
> How are you?
<br />
<br />
Someone else wrote:
<br />
> I like turtles
<br />
<br />
> Someone odd person wrote:
<br />
> > You smell like cheese
<br />
> > and now I'm hungry
<br />
<br />
and that's the end,
<br />
of all of this.
</p>
脚本
$(document).ready(function(){
// link text to inform users to click to expand
var lnk = '[+]';
// variable to look for stating it's a new reply
var newrply = 'wrote:';
// reply indicator (HTML escape code for ' > ' to exclude any HTML that might be found
var isrply = '> ';
// collect html and split it into an array
var txt = $('p').html().split('<br>');
// flag showing that the text is within a reply block
var rply = false;
// cycle through each portion of text
$.each(txt, function(i){
// look for a new reply
if (this.match(newrply)){
// if within a reply and it finds a new reply, close previous
var tmp = (rply) ? '</div>' : '';
// add link
txt[i] = tmp + txt[i] + ' <a href="#" class="replylink">' + lnk + '</a>';
// go to next variable in array and add wrapper, this makes sure the <br> is outside the reply (formatting purposes)
txt[i+1] = '<div class="reply">' + txt[i+1];
// look for reply indicator or text that is <5 characters in length
// (in the HTML above, the array value will have carriage return plus two spaces for each <br>)
} else if (this.match(isrply) || txt[i].length < 5) {
rply = true;
} else {
rply = false;
// close the reply, add the close to the previous array element (most likely a <br>)
txt[i-1] = txt[i-1] + '</div>';
}
// close the reply at the end of the array
if(i == txt.length) {
txt[i-1] = txt[i-1] + '</div>';
}
})
// join the array and add it back
$('p').html( txt.join('<br>') );
// hide the replies
$('.reply').hide();
// add toggle view
$('.replylink').click(function(){
$(this).next().next('.reply').toggle();
return false;
})
})
我将链接更改为'[+]'以切换视图,但在回复打开时我没有费心将其更改为'[ - ]'。我认为代码变得足够长,就像这个例子一样。
使用您发布的新代码,我不得不做一些更改。
<a name="" style="color: gray;"/>
留在了代码中,但格式不正确的HTML ...您无法以这种方式关闭<a>
代码。新更新:
<BR>
而不是<br>
,因此拆分无效。尽管it isn't recommended,我最终还是使用了$.browser.msie
。此外,原始脚本未打开</div>
,这也是它在IE中崩溃的原因。rply
变量没有在每个函数的迭代之间进行更新,因此我将其值移动到隐藏的输入标记中。我试图让它成为全球性的,但它只是不合作。这可能不是理想的做法,所以根据需要进行修复/调整。必填HTML
<input id="replyflag" type="hidden" value="false"/>
更新了IE&amp; amp;的代码新pastbin posting:
$(document).ready(function(){
$('div.post').each(function(){
// link text to inform users to click to expand
var lnk = '[+]';
// variable to look for stating it's a new reply
var newrply = 'wrote:';
// reply indicator (HTML escape code for ' > ' to exclude any HTML that might be found
var isrply = '>';
// IE capitalizes the <BR>, collect html and split it into an array
var splt = ($.browser.msie) ? '<BR>' : '<br>';
var txt = $(this).find('p:eq(0)').html().split(splt);
// index of each reply in a post
var indx = 0;
// start <div> tag around contents, as the script automatically closes the tag, even without replies
txt[0] = '<div>' + txt[0];
// cycle through each portion of text
$.each(txt, function(i){
// look for a new reply
if (this.match(newrply)){
// if within a reply and it finds a new reply, close previous
var tmp = ($('#replyflag').val()) ? '</div>' : '';
// set the "within a reply flag" to true
$('#replyflag').val(true);
// increment index
indx++;
// add link, the rel attrib contains the index of the reply
txt[i] = tmp + txt[i] + ' <a href="#" class="replylink" rel="' + indx + '">' + lnk + '</a>';
// go to next variable in array and add wrapper, this makes sure the <br> is outside the reply (formatting purposes)
txt[i+1] = '<div class="reply" rel="' + indx + '">' + txt[i+1];
// look for reply indicator at the beginning of a line or text that is > 3 characters in length, if not there, turn off reply flag.
} else if (this.substring(0,4)!=isrply | this.length > 3) {
$('#replyflag').val(false);
}
// close the reply at the end of the array
if (i >= txt.length-1) {
txt[i] = txt[i] + '</div>';
}
})
// join the array and add it back
$(this).find('p:eq(0)').html( txt.join('<br>') );
// hide the replies
$('.reply').hide();
// add toggle view (using live because sometimes the click event is called twice and the toggle appears to not work)
$('.replylink').live('click',function(){
$(this).parent().find('.reply[rel=' + $(this).attr('rel') + ']').toggle();
return false;
})
})
})