65.9K
CodeProject 正在变化。 阅读更多。
Home

ThinDoc:零占用空间,全屏 PDF 查看器

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.50/5 (2投票s)

2008年7月24日

CPOL

7分钟阅读

viewsIcon

34626

PDF 是可能是地球上最流行的数字文档交换格式。ThinDoc 通过提供零占用的 PDF 查看器简化了这一过程,允许您在不下载的情况下查看 PDF。

一些背景信息

image001.jpg

PDF 是可能是地球上最流行的数字文档交换格式。最近被批准为 ISO 标准无疑对 Adobe 的业务有利。由于其普及性,您在网上经常会遇到这些文档,而浏览器中的“就地查看”功能很大程度上是伪装的。点击其中一个 PDF 文件,Adobe 就会打开,同时文档在后台下载,最终您就能看到它完整的样子。嗯,我认为有更好的方法。

有什么意义?

很简单。PDF 文件可能很大。如果您只想查看我们 369 页文档 PDF 的第 150 页,为什么还要花时间下载整个文档并启动 Adobe Reader 呢?没有意义。 ThinDoc 使用 Atalasoft DotImage SDK 中的 WebImageViewer 实现零占用 PDF 查看器的目标,并且只需一点点魔法,就可以集成到您的日常生活中,而无需任何编程知识。“零占用”意味着 ThinDoc 不需要任何插件(如 Flash)、Acrobat Reader 或 Applet。它在客户端纯粹使用 JavaScript 和 HTML。

设计目标

它需要快速,需要全屏(即“全浏览器”),并且需要简单。

  • 第一点我们免费获得。WebImageViewer 以与 Google Maps 相同的基于瓦片的方式加载图像。
  • 全屏功能有点棘手,因为 W3C 要求将高度设置为基于其包含块(通常是其中内容的实际高度)的百分比计算。
  • 简单……嗯,这有点主观,但我们稍后再处理。

全屏显示 WebImageViewer

要使 HTML 页面中的任何块级元素具有 100% 的高度,您不仅需要将该元素的高度设置为 100%,还需要设置其父元素……及其父元素的父元素……依此类推。当您到达 body 元素时,这可能会感觉有点奇怪,您的 IDE 可能会提示错误,但还是这样做:<body style=”height:100%”>。更令人“抓狂”的是,您必须设置根 HTML 元素的高度!之后,全屏查看器就近在咫尺了。

WebImageViewer 是由一个 iFrame 构建的。为了与图像交互和进行平移,iFrame 带有滚动条。底部的滚动条我们可以处理——它很有用——但是每个浏览器对页面高度的解释略有不同,因此您不能保证查看器不会超出浏览器窗口的长度,从而导致窗口的滚动条出现。我们需要做的是使用一些技巧来强制每个浏览器完全隐藏滚动条。

除 IE 外的所有浏览器修复方案

要移除除 IE 之外所有浏览器的滚动条,只需将 body 的 overflow CSS 属性设置为 hidden。您的 CSS 文件中应包含类似内容:

body {
    ...
    overflow:hidden;
}

对于剩下 85% 的用户……

要移除 IE 的滚动条,您需要将 body 的 scroll 属性设置为 no。如果您在 Visual Studio 中执行此操作,它会发出警告,告知您这是无效的……真是奇怪。您的 body 标签现在应该如下所示:<body style=”height:100%” scroll=”no”>

使其简单

image002.gif

尽可能最小化是我们的目标。有两组控件,并且它们都不会显示,除非您移动鼠标;这使您可以查看整个文档,而没有任何东西阻碍您的视线。缩放、关闭和下载控件相当直接,因此我不会详细介绍。

缩略图

底部的缩略图查看器使用一些 JavaScript 来分页浏览帧。以下是其内部结构的一瞥:

var ScrollInterval; 
var xPos = 0;  
var _thumbWidth;

function scrollright() {

    clearInterval(ScrollInterval); 
    ScrollInterval = setInterval(&quot;moveright()&quot;, 25); 
}

function moveright() {

    if(xPos > -_thumbWidth * (WebThumbnailViewer1.getCount()-4)) {

        xPos = xPos - 50; 
        WebThumbnailViewer1.setScrollPosition(new atalaPoint(xPos,0)); 
    } 
}

function scrollleft() {

    clearInterval(ScrollInterval); 
    ScrollInterval = setInterval(&quot;moveleft()&quot;, 25); 
}

function moveleft() {

    if(xPos < 0) {

        xPos = xPos + 50; 
        WebThumbnailViewer1.setScrollPosition(new atalaPoint(xPos,0)); 
    } 
}

// This makes sure that we are seeing exactly 4 full 
// thumbnails when the user stops scrolling 

function snap() {

    clearInterval(ScrollInterval); 
    var numThumbs = Math.round(xPos / _thumbWidth);

    xPos = numThumbs * _thumbWidth; 
    WebThumbnailViewer1.setScrollPosition(new atalaPoint(xPos,0)); 
}

<!-- the Scroll Right Button -->

<a href=&quot;#&quot; onmousedown=&quot;scrollright();&quot; onmouseout=&quot;snap();&quot; onmouseup=&quot;snap();&quot;> 
    <img alt=&quot;Move Left Button&quot; src=&quot;images/moveRight.png&quot; height=&quot;140px&quot; width=&quot;30px&quot; />
</a>

缩略图查看器中控制向右滚动的右箭头按钮有一个名为 scrollRightOnMouseDown 事件处理程序。通过使用 setInterval,我们可以将缩略图快速滚动时的速度与脚本运行的计算机的速度分离开来。每隔 25 毫秒,就会调用 moveRight 方法,并将 WebThumbnailViewer 的滚动位置增加 50 像素,直到释放鼠标按钮并调用 snapsnap 确保查看器始终停在一组 4 个缩略图上。我们不希望看到半个缩略图、两个完整的缩略图和另一个半个。

隐藏和显示控件

image003.jpg

应用程序启动时,控件会显示出来,以提示用户它们的存在。只需移动鼠标,它们就会重新出现并保持可见,直到鼠标停止移动 2 秒钟。

WebImageViewer 提供了一个 MouseMove 事件,但它只在鼠标移动到图像上时触发。当图像被缩放到足够远,鼠标可以在查看器内但不在图像上时,该怎么办?如果我们只使用该事件,控件最终会消失,而我们永远无法找回它们。因此,我们需要使用 WebImageViewer 的父 iFrame 的 onmousemove 事件。

var iframes = 
    document.getElementById(&quot;WebImageViewer1&quot;).getElementsByTagName(&quot;iframe&quot;);

iframe = iframes[0].contentWindow || iframes[0].contentDocument; 
if(iframe.document) 
    iframe = iframe.document; 
iframe.onmousemove = showAll;

首先,我们获取 ID 为我们 WebImageViewer 的文档元素。在这种情况下,它是 WebImageViewer1。接下来,我们需要获取它所有的子 iFrame 元素。由于只有一个(我知道这一点是因为我在 FireBug 中深入研究了 DOM),我们可以通过索引零来访问它。在确保我们获得了正确的 DOM 元素(根据我们使用的浏览器)之后,我们可以设置 onmousemove 事件,使其在触发时调用 showAll 函数。

var HideAllTimeout; 
function showAll() {

    clearTimeout(HideAllTimeout); 
    HideAllTimeout = setTimeout(&quot;hideAll();&quot;, &quot;2000&quot;);

    WebThumbnailViewer1.setVisibility(&quot;visible&quot;); 
    document.getElementById(&quot;thumbs&quot;).style.visibility = &quot;visible&quot;; 
    document.getElementById(&quot;controls&quot;).style.visibility = &quot;visible&quot;; 
}

// if they keep their mouse still for 2 whole seconds, we hide the controls 

function hideAll() {

    clearTimeout(HideAllTimeout);

    WebThumbnailViewer1.setVisibility(&quot;hidden&quot;); 
    document.getElementById(&quot;thumbs&quot;).style.visibility = &quot;hidden&quot;; 
    document.getElementById(&quot;controls&quot;).style.visibility = &quot;hidden&quot;; 
}

showAll 函数通过清除对 hideAll 的任何延迟调用来确保它不会被调用,准备一个对 hideAll 的新延迟调用,然后确保控件和缩略图可见。当鼠标停止移动时,hideAll 方法的最新 setTimeout 将不会被清除,在延迟 2 秒后,控件将消失。

缓存

为了确保请求的文档能够快速加载,我们需要将其本地缓存以供将来处理。首先,代码后端会抓取请求 URL 的图像并将其保存到磁盘上的一个文件夹中。

url = Server.HtmlDecode(url); 
filename = MapPath(FileMapper.GetHashedName(url)); 
if (!File.Exists(filename)) 
{ 
    WebClient client = new WebClient(); 
    client.DownloadFile(url, filename); 
}

这不仅使我们能够更快地加载文档的后续页面,还使得下次加载此文档的速度飞快。由于我不想占用超过 50MB 的磁盘空间,因此我会移除 n 个最近最少使用的文档,直到缓存小于 50MB。

书签小工具

为了使此应用程序尽可能易于使用,我编写了一个简单的书签小工具。将此 ThinDocify 链接拖放到浏览器的书签栏(适用于 Firefox 和 Safari)中,或右键单击它并将其添加为收藏夹(适用于 IE)。要使用它,请导航到包含 PDF 文档链接您喜欢的页面,点击书签栏中的 ThinDocify 书签小工具,然后点击该页面上的 PDF 链接。

书签小工具本质上是一段被塞进链接里的 JavaScript 代码。当您将该链接添加到书签栏并运行它时,它会在浏览器当前页面的上下文中运行。在下面的代码中,我们遍历页面上的每个链接,并检查 URL 是否以 PDF 或 TIF 结尾。我还进行了一个快速的“不破坏 Google”检查,确保没有任何 URL 包含问号。诚然,这限制了它在从脚本提供 PDF 的网站上的功能,这些脚本在查询字符串中接收文件名,但嘿,至少它不会破坏互联网。对于这些 URL 中的每一个,我们将其替换为对 JavaScript 函数 window.open 的调用,并将位置设置为 http://thindoc.atalasoft.com/url=http://thedesiredurl.com/file.pdf

<script type=&quot;text/javascript&quot;> 
<!--

(function() { 
    var i; 
    for(i = 0; i < document.links.length; i++) { 
        var url = document.links[i].href; 
        if((url.substring(url.length-3, url.length) == 'pdf' ||  
            url.substring(url.length-3, url.length) == 'tif') && 
            url.indexOf('?') == -1) { 
                document.links[i].href =  
                    'javascript:window.open(\'http://thindoc.atalasoft.com/?url=' +  
                    escape(url) + 
                    '\',\'_thindoc\');';document.links[i].target = '_thindoc'; 
            } 
        } 
    }
)();

--> 
</script>

您还可以将此脚本添加到您自己网页的底部,它将自动将所有 PDF 链接转换为在 ThinDoc 中打开。

有关 ThinDoc 的更多信息,请访问 其关于页面

示例文档

点击以下文档,了解 ThinDoc 的实际应用

链接到文档中的特定页面

下载源代码

您可以在此处获取 ThinDoc 的源代码

© . All rights reserved.