最近工作需要,要将TWebBrowser样式改头换面,包括菜单,滚动条等,都要换掉。
 由于滚动条已经屏蔽掉,所以关于页面滚动等,全部都需要自己写代码来模拟了。模拟的过程中发现获得页面的客户区大小ClientHeight,ClientWidth以及页面总大小ScrollHeight,ScrollWidth的时候,还有滚动条滑块位置ScrollTop,ScrollLeft的值总是有不对的情况,通过在网上查找才发现,原来是W3C标准在作怪,只要是使用了W3C标准格式
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
作为开头的,我使用
((FWebBrowser.Document as IHTMLDocument2).body as IHTMLElement2).scrollTop这些获得的值都有问题,始终为0
而不用该格式的,都不会有问题。
那么使用了该格式的,用什么方法来获得呢!通过资料发现
FWebBrowser.oleobject.document.documentelement.ClientHeight;这样的方式来获得标准格式的各个值。
资料原文如下

  1. JavaScript:
  2. function IeTrueBody(){//判断头部是否有标准声明
  3. return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
  4. }

通过这里我们可以看到,需要检查是否是标准文档,这个就需要document.compatMode的判断
资料如下:

转载:http://www.cnscn.org(CNS电脑与英语学习网)

声明:我写的博客就是我的学习笔记,让我在忘记的时候可以在任何时候,任何地方,打开连接就可以看到,让我想起忘记的东西. 
我的博客通常都有资料来源,只用于学习,没有任何其他目的,如果有版权问题,请跟我联系,如果对资料有什么疑问,可以留言! 
我的email:herhun@163.com

对于document.compatMode,很多朋友可能都根我一样很少接触,知道他的存在却不清楚他的用途。今天在ext中看到 document.compatMode的 使用,感觉这个对于我们开发兼容性的web页面还是很有帮助,我们都知道,IE对盒模型的渲染在 Standards Mode和Quirks Mode是有很大差别的,在Standards Mode下对于盒模型的解释和其他的标准浏览器是一样,但在Quirks Mode模式下则有很大差别,而在不声明Doctype的情况下,IE默认又是Quirks Mode。所以为兼容性考虑,我们可能需要获取当前的文档渲染方式。 
      document.compatMode正好派上用场,它有两种可能的返回值:BackCompat和CSS1Compat,对其解释如下: 
BackCompat Standards-compliant mode is not switched on. (Quirks Mode) 
CSS1Compat Standards-compliant mode is switched on. (Standards Mode)

在实际的项目中,我们还需要在获取浏览是否IE,这样就可以得到IE的渲染模式了。在Ext中的代码:isBorderBox=isIE&&!isStrict。

当文档有了标准声明时, document.compatMode 的值就等于 "CSS1compat", 因此, 我们可以根据document.compatMode 的值来判断文档是否加了标准声明

var height = document.compatMode=="CSS1Compat" ? document.documentElement.clientHeight :document.body.clientHeight;

浏览器的两种模式

在看js代码时,有时会看到关于quirks mode(怪异模式)和strict mode(严格格式)的东西,一直也没深究怎么回事,只是零零碎碎的有些概念,最近终于受不了这种似懂非懂的感觉,决定好好学习总结一下。

1、quirks mode和strict mode是浏览器解析css的两种模式,或者可以称之为解析方法。目前正在使用的浏览器这两种模式都支持 。

2、历史原因。

当早期的浏览器Netscape 4和Explorer 4对css进行解析时,并未遵守W3C标准,这时的解析方式就被我们称之为quirks mode(怪异模式),但随着W3C的标准越来越重要,众多的浏览器开始依照W3C标准解析CSS,仿照W3C标准解析CSS的模式我们叫做strict mode(严格模式).

3、后来的浏览器虽然支持strict mode,但众多浏览器并未放弃支持quirks mode。

一个重要的原因就是为了之前大量在quirks mode下开发的网页能够得到正确的显示。所以,这些支持两种模式的浏览器当拿到一张网页时,所做的一个前期工作就是判断采取何种方式进行解析(判断条件 后面会说)。注:Explorer 5仍然只支持quirks mode

4、浏览器如何判断何用哪种方式解析CSS?

解决方案就是采用doctype声明,大多数浏览器采用下面的这些判断规则

  • 浏览器要使老旧的网页正常工作,但这部分网页是没有doctype声明的,所以浏览器对没有doctype声明的网页采用quirks mode解析。
  • 对于拥有doctype声明的网页,什么浏览器采用何种模式解析,这里有一张详细列表可参考:http://hsivonen.iki.fi/doctype/
  • 对于拥有doctype声明的网页,这里有几条简单的规则可用于判断:

对于那些浏览器不能识别的doctype声明,浏览器采用strict mode解析

在doctype声明中,没有使用DTD声明或者使用HTML4以下(不包括HTML4)的DTD声明时,基本所有的浏览器都是使用quirks mode呈现,其他的则使用strict mode解析。

可以这么说,在现有有doctype声明的网页,绝大多数是采用strict mode进行解析的。

在ie6中,如果在doctype声明前有一个xml声明(比如:<?xml version="1.0" encoding="iso-8859-1"?>),则采用quirks mode解析。这条规则在ie7中已经移除了。

5、mozilla提出了almost strict moede ,和strict mode的区别是:

img元素在strict中是inline的,而在almost strict mode中是block的。其实我们前面所说,在大多数浏览器,大多数doctype声明触发的是almost strict mode;

6、quirks mode和strict mode最大的不同就是提现在对盒模式的解释上 ,这也是我们在js里要注意的地方。

什么是盒模式? 这是针对块级元素说的,我这里只简单说一下(详情请查阅相关资料)。说白了就是把块级元素想像成一个装东西的盒子,而margin,padding,border,width这些css属性构成了盒模式。

而区别就是产生在width属性上:

strict mode中 :

width是内容宽度 ,也就是说,元素真正的宽度 = margin-left  +  border-left-width  +  padding-left  + width  +  padding-right  +  border-right-width  +  margin-right;

quirks mode中 :

width则是元素的实际宽度 ,内容宽度 = width  -  (margin-left  +  margin-right  +  padding-left  +  padding-right  +  border-left-width  +  border-right-width)

这里把盒模式相关的东西记录一下,备忘 !

·内联元素 ,例如<a>、<span>等,定义上下边界不会影响到行高(line-height),内联元素距离上一行元素的距离由行高决 定,而不是填充或边界。 注2.  内联元素(display: inline) 内联元素不需要在新行内显示,而且也不强迫其后的元素换行,如a、em、span等都为内联元素。内联元素可以为任何其他元素的子元素。

·浮动元素(无论左或者右浮动)边界不压缩 ,且若浮动元素不声明宽度,则其宽度趋向于0,即压缩到其内容能承受的最小宽度。

·如果盒中没有内容,则即使定义了宽度和高度都为100%,实际上只占0% ,因此不会被显示,此点在采取层布局的时候需特别注意。

·边界值可为负,其显示效果各浏览器可能不相同 。

·填充值不可为负 。

·边框默认的样式(border-style)为不显示(none) 。

7、在quirks mode 和 strict mode中还有一个区别 ,但没经过验证,我只是发现有这个现象。

strict mode 中,

table的css属性font-size会继承父级元素的 ,也就是说,table中的字体大小会继承父级元素字体的大小。

quirks mode 中,

table的css属性font-size不会继承父级元素的 ,需要专门设置一下。也就是说,table中的字体大小不会继承父级元素字体的大小。

8、在js中如何判断当前浏览器正在以何种方式解析? 
    document对象有个属性compatMode ,它有两个值:
        BackCompat    对应quirks mode
        CSS1Compat    对应strict mode

在Delphi中判断代码如下:

  1. procedure TDxSkinWebBrowser.CheckIfW3CStd;
  2. var
  3. compatMode: string;
  4. begin
  5. //判断文档是否有加标准声明
  6. //当文档有了标准声明时, document.compatMode 的值就等于 "CSS1compat"
  7. //否则就为BackCompat
  8. compatMode := FWebBrowser.oleobject.document.compatMode;
  9. IsW3CStd := CompareText(compatMode,'CSS1Compat') = 0;
  10. end;

所以,滚动控制就要加上这样一个判断,如果是标准的就使用
FWebBrowser.oleobject.document.documentelement.ClientHeight
否则就使用另一种方式:

DelphiCode:

 procedure TDxSkinWebBrowser.ReSetWebSize;
var
WebClientWidth,WebClientHeight: Integer;
MaxScrollWidth, MaxScrollHeight: Integer;
webPoint: TPoint;
begin
if (FWebBrowser.Document <> nil) and ((FWebBrowser.Document as IHTMLDocument2).body <> nil) then
begin
{先获得页面的最大高度}
if (FScrollBars = ssVertical) or (FScrollBars = ssBoth) then
begin
if IsW3CStd then //如果是W3C标准
MaxScrollHeight := FWebBrowser.oleobject.document.documentelement.ScrollHeight
else
MaxScrollHeight := (FWebBrowser.Document as IHTMLDocument2).body.getAttribute('ScrollHeight', 0);
if MaxScrollHeight > FWebBrowser.Height then //总高度大于显示高度度出现滚动条
begin
if IsW3CStd then
begin
WebClientHeight := FWebBrowser.oleobject.document.documentelement.ClientHeight;
webPoint.Y := FWebBrowser.oleobject.document.documentelement.scrollTop;
end
else
begin
WebClientHeight := (FWebBrowser.Document as IHTMLDocument2).body.getAttribute('ClientHeight', 0);
webPoint.Y := ((FWebBrowser.Document as IHTMLDocument2).body as IHTMLElement2).scrollTop;
end;
FVScrollBar.SetRange(0,MaxScrollHeight,webPoint.Y,WebClientHeight);
FVScrollBar.Visible := true;
end else FVScrollBar.Visible := False;
end;
if (FScrollBars = ssHorizontal) or (FScrollBars = ssBoth) then
begin
if IsW3CStd then //如果是W3C标准
MaxScrollWidth := FWebBrowser.oleobject.document.documentelement.ScrollWidth
else
MaxScrollWidth := (FWebBrowser.Document as IHTMLDocument2).body.getAttribute('ScrollWidth', 0);
//总宽度大于显示宽度,出现滚动条
if MaxScrollWidth > FWebBrowser.Width then
begin
if IsW3CStd then
begin
WebClientWidth := FWebBrowser.oleobject.document.documentelement.ClientWidth;
webPoint.x := FWebBrowser.oleobject.document.documentelement.ScrollLeft;
end
else
begin
WebClientWidth := (FWebBrowser.Document as IHTMLDocument2).body.getAttribute('clientWidth', 0);
webPoint.x := ((FWebBrowser.Document as IHTMLDocument2).body as IHTMLElement2).scrollLeft;
end;
FHScrollBar.SetRange(0,MaxScrollWidth,webPoint.X,WebClientWidth);
FHScrollBar.Visible := True;
end else FHScrollBar.Visible := False;
end;
end;
end;
 
 http://blog.csdn.net/suiyunonghen/article/details/3735578
 

自定义TWebBrowser浏览器控制遇到的一些问题的更多相关文章

  1. Jackson 通过自定义注解来控制json key的格式

    Jackson 通过自定义注解来控制json key的格式 最近我这边有一个需求就是需要把Bean中的某一些特殊字段的值进行替换.而这个替换过程是需要依赖一个第三方的dubbo服务的.为了使得这个转换 ...

  2. [C# 网络编程系列]专题四:自定义Web浏览器

    转自:http://www.cnblogs.com/zhili/archive/2012/08/24/WebBrowser.html 前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发 ...

  3. Day 5-8 自定义元类控制类的实例化行为

    __call__方法: 对象后面加括号,触发执行. 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() :而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类( ...

  4. 自定义chromium浏览器

    自定义chromium浏览器 来源  https://chaopeng.me/blog/2018/08/17/how-to-develop-full-homebrew-browser.html 最近有 ...

  5. 转:【专题四】自定义Web浏览器

    前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发出请求的正是本专题要介绍的Web浏览器,本专题通过简单自定义一个Web浏览器来简单介绍浏览器的工作原理,以及帮助一些初学者揭开浏览器这 ...

  6. 专题四:自定义Web浏览器

    前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发出请求的正是本专题要介绍的Web浏览器,本专题通过简单自定义一个Web浏览器来简单介绍浏览器的工作原理,以及帮助一些初学者揭开浏览器这 ...

  7. 浏览器控制之 selenium,phantomJs谷无头浏览器

    目录 浏览器控制之 selenium,phantomJs谷无头浏览器 selenium phantomJs 需求是尽可能多的爬取豆瓣网中的电影信息 谷歌无头浏览器 浏览器控制之 selenium,ph ...

  8. js自定义获取浏览器宽高

    /** * @description js自定义获取浏览器宽高 * * IE8 和 IE8 以下的浏览器不兼容 * window.innerWidth * window.innerHeight * * ...

  9. MySQL自定义函数用法详解-复合结构自定义变量/流程控制

    自定义函数 (user-defined function UDF)就是用一个象ABS() 或 CONCAT()这样的固有(内建)函数一样作用的新函数去扩展MySQL. 所以UDF是对MySQL功能的一 ...

随机推荐

  1. 【iOS技术】Xcode+GitHub远程代码托管(GIT, SVN)

    原创 2016-05-24 旭哥 蓝鸥 学生对旭哥的评价是这样的: 旭哥 为什么这么年轻 知识却比我们多这么多............ 旭哥很是负责,对同学的各种问题都能够热心地解答,在旭哥的带领下, ...

  2. Python进阶之面向对象编程(二)

    Python面向对象编程(二) .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB& ...

  3. css书写顺序和常用命名推荐

    写代码的时候有一个好的规范和顺序能够帮你节省很多时间.下文将推荐相关CSS书写顺序和规范的一些方法.这个文档将会整理进前端规范文档中,如果你有更好的意见,不妨留言告知我们. CSS书写顺序 该代码来自 ...

  4. Eclipse 打包过滤 Log.e

    我们在开发时,经常会输出各种日志来debug代码.但是等到应用发布的apk运行时不希望它输出日志. 关闭输出日志Log.v(),Log.i(),Log.w(),Log.v(),Log.e()等 原理: ...

  5. PHP_OOP

    1.存储器方法——用于限制对象的变量属性 对于弱类型的PHP,存储器方法来限制变量属性显得非常重要! 通过为所有属性创建存储器方法,可以简化添加数据验证或新的业务逻辑的工作,也可以简化在后边对对象执行 ...

  6. Internet设置->连接选项卡->局域网(LAN)设置 某些设置由系统管理员进行管理

    今天突然发现ss不能使用了.经过一系列排查发现 Internet设置->连接选项卡->局域网(LAN)设置 某些设置由系统管理员进行管理,如上图. 修改注册表值HKEY_LOCAL_MAC ...

  7. c语言中的制表符\t与空格

    (本文不讨论制表符与空格缩进问题) 编程过程中,我们常常用多个空格或制表符分隔两个字符串,那么这两个在显示效果上有什么区别呢? 比较如下两行代码的输出效果 代码1: printf("1\t1 ...

  8. 数组初始化(c, c++, gcc, g++)

    这是很基础的东西,但基础的重要性不言而喻,我敢肯定这个知识点我肯定曾经了解过,但现在,我不敢确定,由此可见纪录的重要性,这世界没有什么捷径,找对方向,然后不停重复.所以从今天开始,我会比较详细的纪录这 ...

  9. myeclipse 环境配置优化,不断跟新整理中

    myeclipse 环境配置,不断跟新整理中1.General --->Workspace ---> UTF-8 工作环境编码2.General --->Editors --> ...

  10. 占成本85% SSD深度选购教你如何看颗粒

    颗粒是固态硬盘负责容量和传输的介质,在这一方面上与优盘产品是相同的,从外观上看,颗粒占据了整个固态硬盘内部70%左右的空间,其同样做为成本技术,根据厂商的用料不同,成为了固态硬盘内部核心材料. 颗粒的 ...