1. 跨子域的iframe高度自适应
2. 完全跨域的iframe高度自适应
同域的我们可以轻松的做到
1. 父页面通过iframe的contentDocument或document属性访问到文档对象,进而可以取得页面的高度,通过此高度值赋值给iframe tag。
2. 子页面可以通过parent访问到父页面里引入的iframe tag,进而设置其高度。
但跨域的情况则不允许对子页面或父页面的文档进行访问(返回undefined),所以我们要做的就是打通或间接打通这个壁垒。
一、跨子域的iframe高度自适应
比如 'a.jd.com/3.html' 嵌入了 'b.jd.com/4.html',这种跨子域的页面
3.html
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
4.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
可以看到与上一篇对比,只要在两个页面里都加上document.domain就可以了
二、完全跨域的iframe高度自适应
分别有以下资源
- 页面 A:http://snandy.github.io/lib/iframe/A.html
- 页面 B:http://snandy.github.io/lib/iframe/B.html
- 页面 C:http://snandy.jd-app.com
- D.js:http://snandy.github.io/lib/iframe/D.js
这四个资源有如下关系
1. A里嵌入C,A和C是不同域的,即跨域iframe
2. C里嵌入B,C和B是不同域的,但A和B是同域的
3. C里嵌入D.js,D.js放在和A同域的项目里
通过一个间接方式实现,即通过一个隐藏的B.html来实现高度自适应。
A.html
嵌入页面C: http://snandy.jd-app.com
1 2 3 4 5 6 7 8 9 10 |
|
B.html
嵌入在C页面中,它是隐藏的,通过parent.parent访问到A,再改变A的iframe(C.html)高度,这是最关键的,因为A,B是同域的所以可以访问A的文档对象等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
C.html
嵌入在A中,和A不同域,要实现C的自适应,C多高则A里的iframe就设为多高。C里嵌入B.html 和 D.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
D.js
在页面C载入后计算其高度,然后将计算出的height赋值给C里引入的iframe(B.html)的src
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
线上示例:http://snandy.github.io/lib/iframe/A.html
我们继续讲解LINQ to SQL语句,这篇我们来讨论Group By/Having操作符和Exists/In/Any/All/Contains操作符。
Group By/Having操作符
适用场景:分组数据,为我们查找数据缩小范围。
说明:分配并返回对传入参数进行分组操作后的可枚举对象。分组;延迟
1.简单形式:
var q = from p in db.Products group p by p.CategoryID into g select g;
语句描述:使用Group By按CategoryID划分产品。
说明:from p in db.Products 表示从表中将产品对象取出来。group p by p.CategoryID into g表示对p按CategoryID字段归类。其结果命名为g,一旦重新命名,p的作用域就结束了,所以,最后select时,只能select g。当然,也不必重新命名可以这样写:
var q = from p in db.Products group p by p.CategoryID;
我们用示意图表示:
如果想遍历某类别中所有记录,这样:
foreach (var gp in q) { if (gp.Key == 2) { foreach (var item in gp) { //do something } } }
2.Select匿名类:
var q = from p in db.Products group p by p.CategoryID into g select new { CategoryID = g.Key, g };
说明:在这句LINQ语句中,有2个property:CategoryID和g。这个匿名类,其实质是对返回结果集重新进行了包装。把g的property封装成一个完整的分组。如下图所示:
如果想遍历某匿名类中所有记录,要这么做:
foreach (var gp in q) { if (gp.CategoryID == 2) { foreach (var item in gp.g) { //do something } } }
3.最大值
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, MaxPrice = g.Max(p => p.UnitPrice) };
语句描述:使用Group By和Max查找每个CategoryID的最高单价。
说明:先按CategoryID归类,判断各个分类产品中单价最大的Products。取出CategoryID值,并把UnitPrice值赋给MaxPrice。
4.最小值
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, MinPrice = g.Min(p => p.UnitPrice) };
语句描述:使用Group By和Min查找每个CategoryID的最低单价。
说明:先按CategoryID归类,判断各个分类产品中单价最小的Products。取出CategoryID值,并把UnitPrice值赋给MinPrice。
5.平均值
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, AveragePrice = g.Average(p => p.UnitPrice) };
语句描述:使用Group By和Average得到每个CategoryID的平均单价。
说明:先按CategoryID归类,取出CategoryID值和各个分类产品中单价的平均值。
6.求和
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, TotalPrice = g.Sum(p => p.UnitPrice) };
语句描述:使用Group By和Sum得到每个CategoryID 的单价总计。
说明:先按CategoryID归类,取出CategoryID值和各个分类产品中单价的总和。
7.计数
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, NumProducts = g.Count() };
语句描述:使用Group By和Count得到每个CategoryID中产品的数量。
说明:先按CategoryID归类,取出CategoryID值和各个分类产品的数量。
8.带条件计数
var q = from p in db.Products group p by p.CategoryID into g select new { g.Key, NumProducts = g.Count(p => p.Discontinued) };
语句描述:使用Group By和Count得到每个CategoryID中断货产品的数量。
说明:先按CategoryID归类,取出CategoryID值和各个分类产品的断货数量。 Count函数里,使用了Lambda表达式,Lambda表达式中的p,代表这个组里的一个元素或对象,即某一个产品。
9.Where限制
var q = from p in db.Products group p by p.CategoryID into g where g.Count() >= 10 select new { g.Key, ProductCount = g.Count() };
语句描述:根据产品的―ID分组,查询产品数量大于10的ID和产品数量。这个示例在Group By子句后使用Where子句查找所有至少有10种产品的类别。
说明:在翻译成SQL语句时,在最外层嵌套了Where条件。
10.多列(Multiple Columns)
var categories = from p in db.Products group p by new { p.CategoryID, p.SupplierID } into g select new { g.Key, g };
语句描述:使用Group By按CategoryID和SupplierID将产品分组。
说明: 既按产品的分类,又按供应商分类。在by后面,new出来一个匿名类。这里,Key其实质是一个类的对象,Key包含两个Property:CategoryID、SupplierID。用g.Key.CategoryID可以遍历CategoryID的值。
11.表达式(Expression)
var categories = from p in db.Products group p by new { Criterion = p.UnitPrice > 10 } into g select g;
语句描述:使用Group By返回两个产品序列。第一个序列包含单价大于10的产品。第二个序列包含单价小于或等于10的产品。
说明:按产品单价是否大于10分类。其结果分为两类,大于的是一类,小于及等于为另一类。
Exists/In/Any/All/Contains操作符
适用场景:用于判断集合中元素,进一步缩小范围。
Any
说明:用于判断集合中是否有元素满足某一条件;不延迟。(若条件为空,则集合只要不为空就返回True,否则为False)。有2种形式,分别为简单形式和带条件形式。
1.简单形式:
仅返回没有订单的客户:
var q = from c in db.Customers where !c.Orders.Any() select c;
生成SQL语句为:
SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax] FROM [dbo].[Customers] AS [t0] WHERE NOT (EXISTS( SELECT NULL AS [EMPTY] FROM [dbo].[Orders] AS [t1] WHERE [t1].[CustomerID] = [t0].[CustomerID] ))
2.带条件形式:
仅返回至少有一种产品断货的类别:
var q = from c in db.Categories where c.Products.Any(p => p.Discontinued) select c;
生成SQL语句为:
SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture] FROM [dbo].[Categories] AS [t0] WHERE EXISTS( SELECT NULL AS [EMPTY] FROM [dbo].[Products] AS [t1] WHERE ([t1].[Discontinued] = 1) AND ([t1].[CategoryID] = [t0].[CategoryID]) )
All
说明:用于判断集合中所有元素是否都满足某一条件;不延迟
1.带条件形式
var q = from c in db.Customers where c.Orders.All(o => o.ShipCity == c.City) select c;
语句描述:这个例子返回所有订单都运往其所在城市的客户或未下订单的客户。
Contains
说明:用于判断集合中是否包含有某一元素;不延迟。它是对两个序列进行连接操作的。
string[] customerID_Set = new string[] { "AROUT", "BOLID", "FISSA" }; var q = ( from o in db.Orders where customerID_Set.Contains(o.CustomerID) select o).ToList();
语句描述:查找"AROUT", "BOLID" 和 "FISSA" 这三个客户的订单。 先定义了一个数组,在LINQ to SQL中使用Contains,数组中包含了所有的CustomerID,即返回结果中,所有的CustomerID都在这个集合内。也就是in。 你也可以把数组的定义放在LINQ to SQL语句里。比如:
var q = ( from o in db.Orders where ( new string[] { "AROUT", "BOLID", "FISSA" }) .Contains(o.CustomerID) select o).ToList();
Not Contains则取反:
var q = ( from o in db.Orders where !( new string[] { "AROUT", "BOLID", "FISSA" }) .Contains(o.CustomerID) select o).ToList();
1.包含一个对象:
var order = (from o in db.Orders where o.OrderID == 10248 select o).First(); var q = db.Customers.Where(p => p.Orders.Contains(order)).ToList(); foreach (var cust in q) { foreach (var ord in cust.Orders) { //do something } }
语句描述:这个例子使用Contain查找哪个客户包含OrderID为10248的订单。
2.包含多个值:
string[] cities = new string[] { "Seattle", "London", "Vancouver", "Paris" }; var q = db.Customers.Where(p=>cities.Contains(p.City)).ToList();
语句描述:这个例子使用Contains查找其所在城市为西雅图、伦敦、巴黎或温哥华的客户。
总结一下这篇我们说明了以下语句:
Group By/Having | 分组数据;延迟 |
Any | 用于判断集合中是否有元素满足某一条件;不延迟 |
All | 用于判断集合中所有元素是否都满足某一条件;不延迟 |
Contains | 用于判断集合中是否包含有某一元素;不延迟 |
本系列链接:LINQ体验系列文章导航
LINQ推荐资源
LINQ专题:http://kb.cnblogs.com/zt/linq/ 关于LINQ方方面面的入门、进阶、深入的文章。
LINQ小组:http://space.cnblogs.com/group/linq/ 学习中遇到什么问题或者疑问提问的好地方。
方法:
alert,对话框,OK按钮
confirm,对话框,OK和Cancel按钮
prompt,对话框,可输入
close,关闭当前浏览器窗口
navigate,在当前窗口中导航到指定的URL资源
setInterval,设置每隔一定时间调用指定程序代码,毫秒,setInterval("Func()",5000)
setTimeout,设置经过一定时间后执行一次指定程序代码,毫秒,setTimeout("Func()",5000)
clearInterval,
clearTimeout,
moveTo,将浏览器窗口移动到屏幕上的某个位置
resizeTo,改变浏览器窗口的大小
open,打开一个新窗口 window.open("abc.html","_blank","top=0,left=0,width=100,height=200,toolbar=no");
showModalDialog产生一个模态对话框
showModelessDialog产生一个非模态对话框窗口
属性:
closed
opener
defaultstatus
status
screenTop
screenLeft
事件:
onload,onunload,onmouseover,...
对象属性:
location对象:设置和返回当前网页的URL信息。
载入一个新的网页:window.location.href="http://g.cn";
刷新当前页:window.location.reload();
event对象:获取和设置当前事件的有关信息。
altKey属性,用于检测事件发生时Alt键是否被按下
ctrlKey。。。
shiftKey...
screenX,screenY设置和返回鼠标相对屏幕顶点的x,y坐标
offsetX,offsetY设置和返回鼠标相对事件源顶点的x,y坐标
x,y 设置和返回鼠标相对事件源的父元素顶点x,y坐标
returnValue设置和返回事件的返回值,一般情况下设置为false
cancelBubble设置和返回当前事件是否继续向下传递
srcElement设置和返回事件源对象
keyCode设置和返回键盘按下或弹起时的键的unicode码
button检索鼠标动作使用的是哪个按键,1左鍵,2右键,3左右同时
function window_onkeypress()
{
// alert(window.event.keyCode);
if(window.event.keyCode==27)
{
window.close();
}
}

--------------------
常量:
整型,实型,布尔值,字符串型,null,undefined
变量:var
--------------------
除法运算:9/4 = 2.25 (而不是2)
--------------------
系统函数:
1,encodeURI URL编码
var urlStr=encodeURI("http://www.abc.com/?country=吴&name=z x");
结果:http://www.abc.com/?country=%E5%90%B4&name=z%20x
2,decodeURI URL解码
3,parseInt 将字符串按指定进制转换成一个整数,参数二表示进制
parseInt("32",10) 结果:32
parseInt("3c2",10) 结果:3
parseInt("c32",10) 结果:NaN
parseInt("0x18",10) 结果:0
parseInt("12",16) 结果18
4,parseFloat 将字符串转成小数
parseFloat("2.5") 结果:2.5
parseFloat("2.c5") 结果:2
parseFloat("c2.5") 结果:NaN
5,isNaN 用于检测parseInt和parseFloat返回是否为NaN
返回true/false
6,escape 编码
非ASCII替换为%xx
7,unescape 解码
8,eval 将字符串作为JS表达式执行,例
for(var i=0;i<3;i++) eval("var a"+i+"="+i);
相当于:
var a0=0; var a1=1; var a2=2;
--------------------
对象
1,Object
2,String
方法:
indexOf,
lastIndexOf,
match,使用正则表达式模式对字符串执行搜索,返回包含该搜索结果的数组
replace,
search,使用正则表达式搜索,第一个匹配的字符的位置
slice,截字符串:参数一,开始位置,参数二,结束位置(不指定或为-1时表示末位置)
split,返回一个字符串按照某种分隔标志符拆分为若干子字符串时所产生的字符串数组,分隔符可以是多个字符或一个正则表达式,它不作为任何数组元素的一部分返回。
substr,截字符串:参数一,开始位置,参数二,长度
toLowerCase,
toUpperCase,
3,Math(不能用new创建)
方法:
abs,绝对值
sin,cos,正余弦
asin,acos,反正余弦
random,返回介于0~1之间的伪随机数
例:var num = Math.randow();
4,Date
var currentTime=new Date();
//var currentTime=new Date(2002,3,4);
var strDate=currentTime.getYear()+"年";
strDate+=currentTime.getMonth()+"月";
strDate+=currentTime.getDate()+"日";
strDate+=currentTime.getHours()+":";
strDate+=currentTime.getMinutes()+":";
strDate+=currentTime.getSeconds()+" ";
strDate+=currentTime.getMilliseconds();
alert(strDate);
结果:2008年1月19日15:27:10 518
----------------------
数组
1,
var arr=["abc",123,'abc',,3.4];
for(var i=0;i<arr.length;i++)
{
alert(arr[i]);
}
2,用对象的方式实现数组
function MyArray(){this.length=arguments.length;for(var i=0;....
3,Array对象
var arr=new Array(2.4,"abc",2);
arr.sort(); //排序
alert的结果为 2 2,4 abc
-----------------------

CatalogEdit.aspx
<asp:ListBox ID="ListBox1" runat="server" DataSourceID="SqlDataSource1" DataTextField="catalog" DataValueField="ID" Rows="10"></asp:ListBox> <asp:LinkButton ID="LinkButton_up" runat="server" OnClick="LinkButton_up_Click">上移</asp:LinkButton> <asp:LinkButton ID="LinkButton_down" runat="server" OnClick="LinkButton_down_Click">下移</asp:LinkButton> <asp:LinkButton ID="LinkButton_del" runat="server" OnClick="LinkButton_del_Click">删除</asp:LinkButton> <asp:Label ID="Label_alert" runat="server" ForeColor="Red" Text="Label"></asp:Label><br /> <asp:TextBox ID="TextBox_newCatalog" runat="server"></asp:TextBox> <asp:LinkButton ID="LinkButton_add" runat="server" OnClick="LinkButton_add_Click">新增</asp:LinkButton> <asp:LinkButton ID="LinkButton_edit" runat="server" OnClick="LinkButton_edit_Click">修改</asp:LinkButton> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionStringLink %>" DeleteCommand="DELETE FROM [xLinkCategory] WHERE [ID] = ?" InsertCommand="INSERT INTO [xLinkCategory] ([username],[catalog],[order]) VALUES (?,?,0)" ProviderName="<%$ ConnectionStrings:ConnectionStringLink.ProviderName %>" SelectCommand="SELECT [ID], [catalog] FROM [xLinkCategory] WHERE ([username] = ?) ORDER BY [order],[ID] desc" UpdateCommand="UPDATE [xLinkCategory] SET [catalog] = ? WHERE [ID] = ?"> <DeleteParameters> <asp:Parameter Name="ID" Type="Int32" /> </DeleteParameters> <UpdateParameters> <asp:Parameter Name="catalog" Type="String" /> <asp:Parameter Name="ID" Type="Int32" /> </UpdateParameters> <SelectParameters> <asp:SessionParameter Name="username" SessionField="username" Type="String" /> </SelectParameters> <InsertParameters> <asp:SessionParameter Name="username" SessionField="username" Type="String" /> <asp:Parameter Name="catalog" Type="String" /> </InsertParameters> </asp:SqlDataSource>
CatalogEdit.aspx.cs
/**//// <summary> /// 上移 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void LinkButton_up_Click(object sender, EventArgs e) { if (ListBox1.SelectedItem != null && ListBox1.SelectedIndex > 0) { string tempValue = ListBox1.SelectedValue; string tempText = ListBox1.SelectedItem.Text; int index = ListBox1.SelectedIndex; ListBox1.SelectedItem.Value = ListBox1.Items[index - 1].Value; ListBox1.SelectedItem.Text = ListBox1.Items[index - 1].Text; ListBox1.Items[index - 1].Value = tempValue; ListBox1.Items[index - 1].Text = tempText; ListBox1.SelectedIndex--; operateDB_move(); } } /**//// <summary> /// 下移 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void LinkButton_down_Click(object sender, EventArgs e) { if (ListBox1.SelectedItem != null && ListBox1.SelectedIndex < ListBox1.Items.Count - 1) { string tempValue = ListBox1.SelectedValue; string tempText = ListBox1.SelectedItem.Text; int index = ListBox1.SelectedIndex; ListBox1.SelectedItem.Value = ListBox1.Items[index + 1].Value; ListBox1.SelectedItem.Text = ListBox1.Items[index + 1].Text; ListBox1.Items[index + 1].Value = tempValue; ListBox1.Items[index + 1].Text = tempText; ListBox1.SelectedIndex++; operateDB_move(); } } /**//// <summary> /// 添加 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void LinkButton_add_Click(object sender, EventArgs e) { if (TextBox_newCatalog.Text != "") { //检查同名 bool goon = true; foreach (ListItem li in ListBox1.Items) { if (li.Text == TextBox_newCatalog.Text) { goon = false; } } if (goon) { //操作 SqlDataSource1.InsertParameters["catalog"].DefaultValue = TextBox_newCatalog.Text; SqlDataSource1.Insert(); //设置selected if (ListBox1.Items.Count > 0) { ListBox1.SelectedIndex = 0; } } else { Label_alert.Text = "已存在"; } } } /**//// <summary> /// 修改 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void LinkButton_edit_Click(object sender, EventArgs e) { if (TextBox_newCatalog.Text != "" && ListBox1.SelectedItem != null) { int index = ListBox1.SelectedIndex; //检查同名 bool goon = true; foreach (ListItem li in ListBox1.Items) { if (li.Text == TextBox_newCatalog.Text) { goon = false; } } if (goon) { //操作 SqlDataSource1.UpdateParameters["catalog"].DefaultValue = TextBox_newCatalog.Text; SqlDataSource1.UpdateParameters["ID"].DefaultValue = ListBox1.SelectedItem.Value; SqlDataSource1.Update(); //设置selected ListBox1.SelectedIndex = index; } else { Label_alert.Text = "已存在"; } } } /**//// <summary> /// 删除 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void LinkButton_del_Click(object sender, EventArgs e) { if (ListBox1.SelectedItem != null) { int index = ListBox1.SelectedIndex; int count = ListBox1.Items.Count; //检查该 Catalog 下是否有 Link bool goon = true; goon = !checkSubLink(ListBox1.SelectedValue); //下有 Link 则返回真,注意前面有个"!",有则不继续 if (goon) { //操作 SqlDataSource1.DeleteParameters["ID"].DefaultValue = ListBox1.SelectedItem.Value; SqlDataSource1.Delete(); //设置selected if (index < count - 1) //删的不是最末项 { ListBox1.SelectedIndex = index; } if (index == count - 1 && index != 0) //删的是最末项,并且不是最首项 { ListBox1.SelectedIndex = index - 1; } if (index == count - 1 && index == 0) //删的是最末项,并且是最首项 { //不设索引 } } else { Label_alert.Text = "该节点下面存在Link(s),请删除后再删除该节点!"; } } }

public static bool loadRss(string RssUrl, int RssCount) { bool ok = true; XmlDocument doc = new XmlDocument(); if (RssUrl != "") { try { doc.Load(RssUrl); XmlNodeList nodelist = doc.GetElementsByTagName("item"); XmlNodeList objItems1; int i = 0; int count = 0; if (doc.HasChildNodes) { foreach (XmlNode node in nodelist) { string title = ""; string link = ""; string description = ""; string pubDate = ""; i += 1; if (node.HasChildNodes) { objItems1 = node.ChildNodes; foreach (XmlNode node1 in objItems1) { switch (node1.Name) { case "title": title = node1.InnerText; break; case "link": link = node1.InnerText; break; case "description": description = node1.InnerText; break; case "pubDate": pubDate = node1.InnerText; break; default: break; } } } if (i > RssCount) { break; } } } } catch (Exception ex) { ok = false; } } return ok; }

C# 中对 Session 的“(string)”、“.ToString()”与“Convert.ToString”用法笔记
在实际操作当中,我们经常会遇到将 Session 的值转为 String 去判断是否为空或者判断是否有权限访问某页,这里的转换过程如果用得不恰当会抛出异常,给访问者带来不好的用户体验。这里我把它写成笔记,以供参考。
一、当 Session["a"] == null 时,
Session["a"].ToString() 抛出异常;
(string)Session["a"] 为 null;
Convert.ToString(Session["a"]) 为 ""。
二、当 Session["a"] == "" 时,
它们的值都为 ""。
所以,在判断 Session["a"] 是否有值时,如果用“.ToString()”,那么必需按照下面的格式与顺序写:
在这里,要注意判断的顺序:先判断是否为 null,再判断是否为 empty。如果 Session["a"] 为 null,则 Session["a"] != null 为 false 自然不会执行 .ToString(),也就不会报错;如果 Session["a"] 不为 null,则执行 .ToString() 也不会报错。
同理 if (Session["a"] == null || Session["a"].ToString() == "") 此句也合法可用。
用 .ToString() 的方法写格式比较固定,如果换成用 (string) 写,会比较自由:
if (Session["a"] != null && (string)Session["a"] != "")
这两种写法都是可行的,而且对 null 和 empty 的判断顺序没有关系。
最简单的方法就是用 Convert.ToString
不管 Session["a"] 为 null 还是 empty,Convert.ToString(Session["aaa"]) 都是 empty。
