精华内容
下载资源
问答
  • 分别是安全外包计算的向量模长计算协议,向量内积计算协议和向量夹角计算协议,并利用模拟范例证明了协议的安全性,然后利用这3个基础协议进一步解决了现实意义中如何保密判断空间面与面位置关系的问题,并给出了具体...
  • EDEM及其应用介绍

    2011-12-30 22:39:35
    传统的力学研究都是建立在连续性介质假设的基础上的,即认为研究对象是由相互连接没有间隙的大量微团构成。...通过求解系统中每个颗粒的受力(碰撞力及场力),不断地更新位置和速度信息,从而描述整个颗粒系统。
  • 电磁干扰(EMI)滤波减少精密 模拟应用中的误差 在医疗设备、汽车仪器仪表和工业控制等科技领域中,当设备设计涉及应变计、传感器接口和电流监控时,通常需要采用精密模拟前端放大器,以便提取并放大非常微弱的真实信号,...
  • 摘要:高精度高边电流检测对于汽车控制系统至关重要,例如电动助力转向、自动变速、传动控制、发动机燃料喷射控制、制动阀控制、以及主动悬挂系统。所有这些应用都需要精密调节通过电机或螺线管的电流,以控制...该信息
  • 它还应该能够确定故障设备的具体位置,并将详细信息报告给检修人员。新的智能系统还将试图告知检修人员应该带上什么工具,同时如果检修部门没有所需的匹配工具,它还可以自动与供应商或其他事业部门沟通
  • 3、地理定位 (获取地理位置信息) 4、web 存储 (在本地存储用户的浏览数据) 5、Web SQL (在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写) 6、应用程序缓存 (创建 web 应用的离线版本。可以在...

    HTML5 API:

    1、文件 API (规范与本地文件进行交互的标准方法)
    
    2、拖放 API (提供了直接支持拖放操作的API)
    
    3、地理定位 (获取地理位置信息)
    
    4、web 存储 (在本地存储用户的浏览数据)	
    
    5、Web SQL	(在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写)
    
    6、应用程序缓存 (创建 web 应用的离线版本。可以在没有网络连接的情况下进行访问。)
    
    7、Web Sockets (在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。)
    
    8、SSE	(网页自动获取来自服务器的更新)
    
    9、Web Workers (web worker 是运行在后台的 JavaScript,不会影响页面的性能)
    
    ......
    

    6、应用程序缓存

    内容概要:

    • 离线应用程序详解
    • manifest文件
    • 浏览器与服务器的交互过程
    • applicationCache对象
      html5 提供了一个供本地缓存使用的API,通过这个API,我们可以实现离线Web应用程序的开发

    1、离线应用程序详解
    新增的本地缓存:
    今天web应用程序已经变得越来越复杂,越来越成熟,很多领域都在利用着Web应用程序。但是,它有一个致命的缺点:如果用户没有和Internet建立连接,他就不能利用这个Web应用程序了。
    因此,在html5中新增了一个API,它使用一个本地缓存机制很好的解决了这个问题,为离线Web应用程序的开发的开发提供了可能性。
    为了让Web应用程序在离线状态下也能正常工作,就必须要把所有构成Web应用程序的资源文件,诸如HTML文件、CSS文件、JavaScript脚本文件等放在本地缓存中,当服务器没有和Internet建立连接的时候,也可以利用本地缓存中的资源文件来正常运行Web应用程序。

    本地缓存与浏览器网页缓存的区别
    首先,本地缓存为整个Web应用程序服务的,而浏览器的网页缓存只服务于单个页面。任何网页都具有网页缓存,而本地缓存只缓存那些你指定缓存的网页。
    其次,网页缓存也是不安全,不可靠的,因为我们不知道在网站中到底缓存了哪些网页,以及缓存了网页上的哪些资源。而本地缓存是可靠的,我们可以控制对哪些内容进行缓存,不对哪些内容进行缓存,开发人员还可以用编程的手段来控制缓存的更新,利用缓存对象的各种属性、状态和事件来开发出更加强大的离线应用程序。

    2、manifest文件
    Web应用程序的本地缓存是通过每个页面的mainfest文件来管理的。manifest文件是一个简单地文件,在该文件中以清单的形式列举了需要被缓存或不需要被缓存的资源文件的文件名称,以及这些资源文件的访问路径。你可以为每个页面指定一个manifest文件,也可以对整个Web应用程序指定一个总的manifest文件。

    hello.html网页的manifest文件:

    CACHE MANIFEST
    #文件的开头必须要书写CACHE MANIFEST
    #整个manifest文件的版本号
    #version 7
    CACHE:
    other.html
    hello.js
    images/myphoto.jpg

    NETWORK:
    *
    FALLBACK:
    online.js locacle.js

    CACHE:
    newhello.html
    newhello.js

    第一行"CACHE MANIFEST"文字,就是把文件的作用告诉浏览器,即对本地缓存中的资源文件进行具体设置。
    同时,真正运行或测试离线Web应用程序的时候,需要对服务器进行配置,让服务器支持text/cache-manifest这个MIME类型(在html5中规定manifest文件的MIME类型是text/cache-manifest)。
    例如对Apache服务器进行配置的时候,需要找到{apache_home}/conf/mime.types这个文件,并在文件最后添加如下代码:
    text/cache-manifest manifest
    但是,根据下面代码块中关于应用缓存最新版本知道manifest 文件的建议文件扩展名是:".appcache"。文件最后添加的代码也应该是:text/cache-manifest appcache

    Cache Manifest 基础
    如需启用应用程序缓存,请在文档的 <html> 标签中包含 manifest 属性:
    
    <!DOCTYPE HTML>
    <html manifest="demo.appcache">
    ...
    </html>
    每个指定了 manifest 的页面在用户对其访问时都会被缓存。如果未指定 manifest 属性,则页面不会被缓存(除非在 manifest 文件中直接指定了该页面)。
    
    manifest 文件的建议文件扩展名是:".appcache"。
    
    注意:manifest 文件需要设置正确的 MIME-type,即 "text/cache-manifest"。必须在 web 服务器上进行配置。
    
    
    

    在微软的IIS服务器中的步骤如下所示。
    1、右键选择默认网站或需要添加类型的网站,弹出属性对话框。
    2、选择“HTTP”标签
    3、在MIME映射下,单击文件类型按钮。
    4、在打开的MIME类型对话框中单击新建按钮。
    5、在关联扩展名文本框输入“manifest”,在内容类型文本框中输入“text/cache-manifest”,然后单击确认按钮。

    在manifest文件中最好加上一个版本号,版本号可以是任何形式,譬如“version 201012341108”,更新manifest文件的时候一般也会对这个版本号进行更新。

    接下来,指定资源文件,可以把资源文件分为三类: CACHE 、 NETWORK 、FALLBACK
    CACHE类别 中指定需要被缓存在本地的资源文件。为某个页面指定需要本地缓存的资源文件时,不需要把这个页面本身指定在CACHE类别中,因为如果一个页面有manifest文件,浏览器会自

    动对这个页面进行本地缓存。
    NETWORK类别 为显式指定不进行本地缓存的资源文件,这些资源文件只有当客户端与服务器端建立连接的时候才能访问。本示例该类别中的“*”为通配符,表示没有在本manifest文件中指

    定的资源文件都不进行本地缓存。
    FALLBACK类别中的每行中指定两个资源文件,第一个资源文件为能够在线访问时使用的资源文件,第二个资源文件为不能在线访问时使用的备用资源文件。

    每个类别都是可选的。但是如果文件开头没有类别而直接书写资源文件的时候,浏览器把这些资源视为CACHE类别。

    为了然浏览器能够正常阅读该文本文件,需要咋web应用程序页面上的html标签的manifest属性中指定manifest文件的URL地址。指定方法如下:
    //你可为每个页面单独指定一个manifest文件

    <html manifest="hello.manifest">
    ...
    </html>
    

    //也可为整个Web应用程序制定一个总的manifest文件

    <html manifest="flobal.manifest">
    ...
    </html>
    

    通过这些操作步骤,将资源文件保存到本地缓存去的基本操作就完成了。当要对本地缓存区的内容进行修改时,只要修改manifest文件就可以了。文件被修改后,浏览器可以自动检查manifest文件,并自动更新本地缓存区中的内容。

    3、浏览器与服务器的交互过程

    当使用离线Web应用程序进行工作的时候,有必要了解一下浏览器与服务器之间的交互过程,
    例如:访问 www.baidu.com 网站,以index.html为主页,该主页使用 index.manifest 文件为manifest文件,在该文件中请求本地缓存 index.html hello.js hello1.jpg hello2.jpg这几个文件

    首次访问:

    (1)浏览器发送请求访问网页

    (2)服务器返回 index.html 网页

    (3)浏览器解析 index.html网页,请求页面上所有资源,包括HTML文件,图像文件,CSS文件,JavaScript脚本文件,以及manifest文件

    (4)服务器返回所有资源文件

    (5)浏览器处理manifest文件,请求manifest文件中所有要求本地缓存的文件,包括index.html文件本身。即使刚才已经请求过这个文件。如果本地缓存所有文件,这是一个比较大重复过程。

    (6)服务器返回所有要求本地缓存的文件。

    (7)浏览器对本地缓存更新,存入包括页面本身在内的所有要求本地缓存的资源文件,并且触发一个事件,通知本地缓存被更新。

    再次打开,而且manifest没有被修改过,他们的交互过程如下:

    (1)浏览器再次请求网页

    (2)浏览器发现这个页面被本地缓存,于是使用本地缓存中的index.html文件

    (3)浏览器解析index.html文件,使用所有本地缓存中资源文件

    (4)浏览器向服务器请求manifest文件

    (5)服务器返回一个304代码,通知浏览器manifest没有发生变化

    只要页面上的资源文件被本地缓存过,下次浏览器打开这个页面时,总是先使用本地缓存中的资源,然后请求manifest文件。

    如果再次打开,manifest文件已经被更新过:

    (1)浏览器请求网页

    (2)浏览器发现这个网页被本地缓存,于是使用本地缓存中的index.html

    (3)浏览器解析index.html页面,使用所有本地缓存中的资源文件

    (4)浏览器向服务器请求manifest文件

    (5)服务器返回更新过的manifest文件

    (6)浏览器处理manifest文件,发现该文件已经被更新,于是请求所有要求进行本地缓存的资源文件,包括index.html页面本身。

    (7)浏览器返回要求进行本地缓存的的资源文件

    (8)浏览器对本地缓存进行更新,存入所有新的资源文件。并且触发一个事件,通知本地缓存更新。

    需要注意:更新后的资源不会立刻发生变化。更新过后本地缓存中的内容还不能被使用,只有重新打开这个网页的时候才会使用更新过后的资源文件。
    另外,如果你不想修改manifest文件中对于资源文件的设置,但是你对服务器上请求缓存的资源文件进行了修改,那么你可以通过修改版本号的方式来让浏览器认为manifest文件已经被更新过了,以便重新修改过的资源文件。

    4、applicationCache对象

    applicationCache对象代表了本地缓存,可以用来通知用户本地缓存已经被更新,也允许用户手工更新本地缓存。

    当浏览器对本地缓存进行更新,装入新的资源文件,会触发applicationCache对象的updateready事件,通知本地缓存已被更新。你可以利用这个事件告诉用户本地缓存已经被更新,用户需要

    手动刷新页面来得到最新版本的应用程序。这部分代码如下:
    applicationCache.onUpdateReady = function(){
    //本地缓存一杯更新,通知用户
    alert(“本地缓存已经更新,您可以刷新页面来得到本程序的最新版本。”);

    };
    另外,你可以通过applicationCache的swapChche 方法来控制如何进行本地缓存的更新及更新的时机。

    swapCache方法用来手工执行本地缓存的更新,它只能在applicationCache对象的updateReady事件被触发时调用,updateReady事件只有在服务器上的manifest文件被更新,并且把manifest文

    件中所要求的资源下载到本地后触发。顾名思义,这个事件的含义是“本地缓存准备被更新。下面,我们来见一下哪些场合需要这个方法。
    首先,如果本地缓存的容量非常大(假如超过100M),本都缓存的更新工作将需要相对较长的时间,而且还会把浏览器给锁住。这时最好有一个提示,告诉用户正在进行本地缓存的更新,该

    部分代码如下所示:
    applicationCache.onUpdateReaduy = function(){
    //本地缓存已经更新,通知用户
    alert(“正在更新本地缓存。。。”);
    applicationCache.swapCache();
    alert(“本地缓存已经被更新,您可以刷新页面来得到本程序的最新版本。”);
    }
    这时候,让我们考虑一个问题,在上面代码中,如果不调用swapCache方法会怎么样?本地缓存不会被更新了吗?答案否,但是更新的时间不一样。如果不调用swapCache方法,本地缓存将在下一次打开页面时被缓存;如果调用swapCache方法的话,本地缓存将会立刻被更新。因此,你可以使用confirm方法让用户自己选择更新的时机,是立刻更新,还是在下一次打开画面时 再更新,特别是当他们有可能正在页面上执行一个较大的操作的候。另外尽管使用swapCache方法立刻更新了本地缓存, 但是并不意味着我们页面上的图像和脚本文件也会被立刻更新,她们都是在重新打开页面时才会生效。
    接下来我们看一个完整的使用swapCache方法的示例。在该示例中使用到了applicationCache对象的另一个方法applicationCache.update,该方法的作用是检查服务器上的manifest文件是否有更新。在打开画面时设定每5秒钟执行一次该方法,检查服务器上的manifest文件是否更新。如果有更新,浏览器会自动下载manifest文件中所有请求本地缓存的资源文件,当这些资源文件下载完毕时,会触发updateReady事件,询问用户是否立刻刷新页面以使用最新版本的应用程序,如果用户选择立刻刷新,则调用swapCache方法手工更新本地缓存,更新完毕后刷新页面。

    <!DOCTYPE HTML>
    <html manifest="swapCache.manifest">
    <head>
    	<meta charset = 'UTF-8'>
    	<title></title>
    	<script src='script.js'></script>
    </head>
    <body onload = 'init()'>
      ...
    </body>
    </html>
    script.js如下:
    function init(){
    	setInterval(function(){
    		//手工检查是否有更新
    		applocationCache.update();
    	}, 5000)
    	applicationCache.addEventListerner("updateready", function(){
    		if(confirm("本地缓存已被更新,需要刷新画面来获取应用程序最新版本,是否刷新?"));
    		//手工更新本地缓存
    		location.reload();
    
    
    	}, true )
    
    }
    swapCache.manifest 如下:
    CACHE MANIFEST
    #version 1.20
    CACHE:
    script.js
    

    applicationCache 对象的事件
    applicationCache对象除了具有update方法与swapCache方法之外,还有一系列的事件,现在我们对前面讲过的浏览器与服务器的交互过程的内容进行扩充,看看在这个过程里这些事情是如何

    触发的。

    首次访问http://www.baidu.com网站:
    1、浏览器请求访问http://www.baidu.com
    2、服务器返回index.html网页
    3、浏览器发现该网页具有manifest属性,触发checking事件,检查manifest文件是否存在。不存在时触发error事件,表示manifest文件未找到,不执行步骤6开始交互过程。
    4、浏览器解析index.html网页,请求页面上的所有资源文件
    5、服务器返回所有资源文件。
    6、浏览器处理manifest文件,请求manifest中所要求本地缓存的文件,包括index.html页面本身,及时刚才已经请求过该文件。如果你要求本地缓存所有文件,这将是一个比较大的重复的请

    求过程。
    7、服务器返回所要求本地缓存的文件。
    8、浏览器触发downloading 事件看,然后开始下载这些资源。在下载的同时,周期性地触发progress事件,开发人员可以用编程的手段获取多少文件已被下载,多少文件仍然处于下载队列等

    信息。
    9、下载结束后触发cached事件,表示首次缓存成功,存入所有要求本地缓存的资源文件。
    再次访问http://www.baidu.com网站,步骤1-5同上,在步骤5执行完之后,浏览器将核对manifest文件是否被更新,若没有被更新,触发noupdatade事件,步骤6开始的交互过程不会被执行,如果

    被更新了,将继续执行后面的步骤,在步骤9中不触发cached事件,而是触发updateready事件,这表示下载结束,可以通过刷新页面来使用更新后的本地缓存,或调用swapCache方法来立刻使

    用更新后的本地缓存。
    另外,在访问缓存名单时如果返回一个HTTP404错误(页面未找到),后者410错误(永久消失),则触发obsolete事件。
    在整个过程中,如果任何与本地缓存有关的处理中发生错误的话,都会触发error事件。可能会触发error事件的情况分为以下几种:
    1、缓存名单返回一个HTTP404错误(页面未找到),或者410错误(页面永久消失)
    2、缓存名单被找到且没有更改,但引用缓存名单的HTTP页面不能正确下载。
    3、缓存名单被找到且被更改,但浏览器不能下载某个缓存名单中列出的资源。
    4、开始更新本地缓存时,缓存名单再次被更改
    为了说明这个事件流程,我们在下列代码中,将浏览器与服务器在交互过程中所触发的一系列事件用文字的形式显示在页面上,从这个页面中我们可以看出这些事件发生的先后顺序。

    <!DOCTYPE html>
    <html lang="en" manifest="applicationCacheEvent.manifest">
    <head>
        <meta charset="UTF-8">
        <title>applicationCache事件流程示例</title>
        <script>
            function init(){
                var msg = document.getElementById('msg');
                applicationCache.addEventListener("checking", function(){
                    msg.innerHTML += " checking<br>"
                }, true)
                applicationCache.addEventListener("noupdate", function(){
                    msg.innerHTML += " noupdate<br>"
                }, true)
                applicationCache.addEventListener("downloading", function(){
                    msg.innerHTML += " downloading<br>"
                }, true)
                applicationCache.addEventListener("progress", function(){
                    msg.innerHTML += " progress<br>"
                }, true)
                applicationCache.addEventListener("updateready", function(){
                    msg.innerHTML += " updateready<br>"
                }, true)
                applicationCache.addEventListener("cached", function(){
                    msg.innerHTML += " cached<br>"
                }, true)
                applicationCache.addEventListener("error", function(){
                    msg.innerHTML += " error<br>"
                }, true)
            }
        </script>
    </head>
    <body onload="init()">
        <h1>applicationCache事件流程示例</h1>
        <p id="msg"></p>
        <img src="./image/flower.jpg" alt="牡丹">
    </body>
    </html>
    applicationCacheEvent.manifest文件里面的内容是:
    CACHE MANIFEST
    #version 1.20
    CACHE:
    ./image/flower1.jpg
    

    首次打开会出现: checking downloading progress progress cached
    再次打开网页(且manifest文件没有更新时)会出现noupdate
    再次打开网页(且manifest文件已经更新时)会出现downloading progress progress updateready

    想知道浏览器处于在线状态还是离线状态,你可以通过检查navigator对象的onLine属性,或者处理特定的在线和离线事件来判断。
    上面这句话出自这个链接https://www.cnblogs.com/lyweb/archive/2013/04/18/3029120.html

    参考阅读:

    展开全文
  • 由于声场的复杂性和某些因素的不可预测性,没有模拟可以百分白的精确,但自90年以来,ease的预测被证明是有效而可靠的。) ease软件在建筑声学、建筑扩声设计中有广泛的应用。我们应用ease对扬子江药业大型会议厅...
  • 自己学了这么久的C语言,但没有写出过什么可以用的东西来,总觉得心里不爽。...外挂的主要思路:获取窗口位置,获取屏幕信息对图片编码,查找可消除对,模拟鼠标点击来消除。 1.外观: 这个是...

          自己学了这么久的C语言,但没有写出过什么可以用的东西来,总觉得心里不爽。这几天实在是不想干正事,在网上瞎逛逛,结果发现有人写了连连看的外挂。顿时觉得这很有意思啊。于是把代码下载下来,捣鼓了捣鼓。发现还挺简单的,于是自己研究了一下,仿照着写了一个。

     

    外挂的主要思路:获取窗口位置,获取屏幕信息对图片编码,查找可消除对,模拟鼠标点击来消除。

     

    1.外观:

    这个是用MFC做的,我自己是一点MFC都不会的,开始在界面上卡了好久,一直在网上找MFC的教程。但是网上的教程都大多扯些杂七杂八的东西,看了很久都不知道究竟怎样才能做出一个界面。后来我干脆不看了,直接上手试试,在vs2012里面创建了一个MFC的应用。结果发现基本的外观实现起来很简单。直接把控件拖进去就行了。再把属性改改就好了。

     

    外观做好后,要把点击按钮和功能函数联合起来。

    在MFC自动生成的Dlg的类中加入功能函数声明 

    里面还有一些后面需要用到的关于图像编码的信息也放在类里面。

    class CLinkGameHelperDlg : public CDialog
    {
    public:
        CWnd * myc;
        MYCOLOR * tc; //记录连连看游戏中的每一种图片信息
        int tcnum;  //记录连连看游戏中的图片种类数
        int* map;   //记录连连看游戏的编码结果
        int pnum;   //记录总的待消除图片数
        CRect loc; 
        CLinkGameHelperDlg(CWnd* pParent = NULL);    // 标准构造函数
        enum { IDD = IDD_LINKGAMEHELPER_DIALOG };
    protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
        HICON m_hIcon;
        virtual BOOL OnInitDialog();
        afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        afx_msg void OnButtonLock();   //下面的这些函数就是与按钮对应的
        afx_msg void OnButtonClear();
        afx_msg void OnButtonClearAll();
        afx_msg void OnButtonAuto();
        afx_msg void OnButtonUpGrade();
        afx_msg void OnButtonHelp();
        DECLARE_MESSAGE_MAP()
    };

    然后在对应的cpp文件中找到

    BEGIN_MESSAGE_MAP(CLinkGameHelperDlg, CDialog)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
    END_MESSAGE_MAP()

    下面加入函数与按钮的连接:

    BEGIN_MESSAGE_MAP(CLinkGameHelperDlg, CDialog)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDC_BUTTON_LOCK, OnButtonLock)
        ON_BN_CLICKED(IDC_BUTTON_CLEAR, OnButtonClear)
        ON_BN_CLICKED(IDC_BUTTON_CLEARALL, OnButtonClearAll)
        ON_BN_CLICKED(IDC_BUTTON_AUTO, OnButtonAuto)
        ON_BN_CLICKED(IDC_BUTTON_UPGRADE, OnButtonUpGrade)
        ON_BN_CLICKED(IDC_BUTTON_HELP, OnButtonHelp)
    END_MESSAGE_MAP()

     

    2.锁定窗口+编码

    现在进入功能实现的第一步:找到QQ连连看的游戏窗口。可以通过下面的语句实现:

    该语句会找到窗口名为:QQ游戏 - 连连看角色版 的窗口。如果失败了,我们提供失败的信息。

       CWnd *p = CWnd::FindWindowA(NULL, "QQ游戏 - 连连看角色版");
        if(p == NULL)
        {
            MessageBox("请启动连连看游戏窗口");
            return;
        }

     

    如果锁定成功,那么我们就可以通过获取窗口信息来对图片编码了。

    观察游戏界面:可以知道左上角的第一个图片距窗口上方180像素,左边10像素,每个图片大小为31*35,共有19*11个放图片的位置。

    获取窗口相对屏幕左上角的坐标

    myc = p;   //连连看的窗口
    myc->ClientToScreen(&loc); //获取连连看窗口相对屏幕的位置 loc是个CRect的类型,在上面的类里面有定义

    获取屏幕(x,y)处的像素值:

    CDC *pdc=myc->GetDC();
    pdc->GetPixel(x , y);

     

    根据上面的图片信息和获取的窗口相对屏幕的位置我们可以知道每一个图片相对屏幕左上角的坐标。

    我们在每张图片上采样4个点,获取像素值。

    定义一个MYCOLOR的结构来存一个图片的四个采样点的像素值:

    //图片结构的定义 取图片上的四个点的像素
    typedef struct MYCOLOR
    {
        COLORREF c[4];
    }MYCOLOR;

    定义一个MYCOLOR的数组tc,来存放不同种类型的图片,每获取一张图片的4个像素点信息后与tc中已经存放的图片做比较,如果有相同的就获取已经有的编号(在数组中的位置,从1开始),如果不同则在tc中加入这种新图片。

    注意:底色的深蓝像素是(48 76 112)如果四个采样点的像素都接近背景值,则认为该位置没有图片,编码0.

    用一个整数数组map来存放编码信息。

    下图是给定场景的编码结果:

    (题外话:大家能猜出来那露出了半个眼睛的人是谁吗?)

     

    3.找可消除的图片对

    有了编码信息后,我们就可以查找可以消除的图片了。关键是图片要一致,且路线不能超过两个弯。

     

    图片一致很好解决,选一个基准图,然后从后面遍历所有的图片,找到与其编码相同的。

    难点在判断路径:从下图给出路径判断的方法,分析横竖横类型的连线。

    竖横竖类型的连线同理。

    只要能够找到两种连线的任意一种,即表明两个图片可以相消。

     

    4.鼠标点击消除

    用下面的语句实现鼠标移动和点击:

    ::SetCursorPos(point1x * PICTUREWIDTH + LEFTGAP + r1.left + 15, point1y * PICTUREHEIGHT + UPGAP + r1.top + 17); //点击point1位置的图片
    mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,0,0,0,0);

    点击后把相应位置的编码改为0.

     

    至此基本的原理就讲完了。

    我的界面里面,锁定是实现锁定和编码功能的。

    消除是点击一下消除一个的。 这里要注意,每次点击后,要把鼠标的位置移动到辅助软件的消除键上,要不然点一样鼠标就保持在游戏窗口的某个图片上,还要人工的再把鼠标放到消除键上点击,非常麻烦。每次把鼠标移动到消除键上方便连续点击。

    全消:顾名思义,一次全清。但问题是360总会冒出来,把屏幕给占了,导致点击出错。如果有安全软件弹出来需要重新锁定。

    自动消除:全消虽然爽,但是容易招骂。自动消除就是会隔200ms-1200ms的随机时间点击一下。看起来比较真实。问题是,在自动消除的过程中,鼠标一直是被占用的,难以中途停止。我加了一个窗口移位检测,每次消除前重新获取一下窗口位置,如果改变了就停止,并弹出消息。这样可以防止意外情况。

    升级:没有实现。

    帮助:顾名思义,就是使用说明。

     

    发布版本:

    把属性的Release配置中的的MFC使用改成在静态库中使用MFC

    平台工具集改为 Visual Studio 2012 - Windows XP(v110_xp) 没有这个选项的需要下载补丁。

     

    问题:

    1.所有的工作都不能出现意外,如果说在自动消除的过程中,有个人给扔了个禁手的道具,辅助工具是检测不出来的,并且还会不断的点击屏幕。这时必须晃动窗口退出自动消除,再重新锁定。

    2.在扩展屏上,这个外挂会失效。必须去掉扩展屏。

     

    工具和源码下载:

    http://yun.baidu.com/share/link?shareid=2181599825&uk=2757788903

    转载于:https://www.cnblogs.com/dplearning/p/4453560.html

    展开全文
  • 压缩包中含有多个文档,从了解httpclient到应用。 httpClient 1httpClint 1.1简介 HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持...
  • 位置标记等更高级的功能使处理多个目标变得容易,而批量读取允许在“战争行走”目标时隐蔽地捕获多张卡片。 安装 文档 . 有关最终用户信息,例如 Walrus 是什么以及如何在现场使用它,请查看 ! 发展 Walrus 由 ...
  • 本篇文章应用范围为期刊搜索(不包括外文文献),其他内容,没有进行测试!!! 本次爬虫所采用到的技术: selenium自动化 正则表达式匹配文本字符串 xpath查询标签位置 pandas导出excel requests发起请求 第...

    知网关键词搜索爬取摘要信息

    由于技术不成熟,代码冗余度较高。同时代码也可能会存在错误,也请各路高人指正。
    本篇文章应用范围为期刊搜索(不包括外文文献),其他内容,没有进行测试!!!

    本次爬虫所采用到的技术:

    1. selenium自动化
    2. 正则表达式匹配文本字符串
    3. xpath查询标签位置
    4. pandas导出excel
    5. requests发起请求

    第一部分,获取详情页内容链接,并存入本地文件。

    第一步,分析知网搜索页。本次我们以两个关键词为例(‘农地流转’,风险),通过selenium模拟浏览器动作进行列表页的访问。

    • 我们找到知网高级检索页面(我用的是旧版入口)

    在这里插入图片描述

    • 我们通过selenium完成输入点击的过程。有关xpath内容不详细展开。
    # 选择期刊板块
    qikan = tb.find_elements_by_xpath('//*[@id="CJFQ"]/a')[0]  # 寻找
    qikan.click() # 点击期刊
    sleep(1.5)
    # 输入关键词
    keywords1 = tb.find_element_by_id('txt_1_value1')  # 寻找第一个关键词输入框
    keywords2 = tb.find_element_by_id("txt_1_value2")  # 寻找第二个关键词输入框
    keywords1.send_keys("农地流转")   # 传值
    keywords2.send_keys("风险")      # 传值
    
    
    btn1 = tb.find_element_by_id("btnSearch")  # 寻找检索按钮
    btn1.click()   # 点击检索
    sleep(1.5)
    
    • 完成检索之后,我们可以看到这样的页面
      在这里插入图片描述
    • 接下来我们需要点击使一页能够显示50条项目。
      需要注意选择展示项目数量的代码在iframe标签中,因此需要重新进行定位。
      在这里插入图片描述
    # 我们发现知网的列表内容是嵌入在iframe标签下的,因此要将目标定位到iframe标签内
    tb.switch_to.frame('iframeResult')  # iframe的id
    page_text = tb.page_source   # 获取页面内容
    tree1 = etree.HTML(page_text)   # etree对象
    sleep(1.5)
    
    # 设置每页显示五十页,跳转到新的url
    fifty_url=tree1.xpath('//*[@id="id_grid_display_num"]/a[3]/@href')[0]  # 我们设置每页显示50个,有利于快速获取
    new_url = 'https://kns.cnki.net'+fifty_url  # 在selenium中,访问50页会跳往新的页面(因为这里我们是get一个新的url,正常访问知网是不会跳页面的)
    tb.get(new_url)  # 跳转
    sleep(1.5)
    
    page_text = tb.page_source  # 获取当前页面所有内容
    
    

    第二步,然后你就会看到这样一个页面,我们所有的爬取操作都是基于这一页面而进行的。

    在这里插入图片描述
    点击标题能够进入到最终的详情页,因此我们只需要获得每个标题的a链接并多次翻页就可以喽!

    • 获取标题链接的xpath:
    content = tree2.xpath('//*[@id="ctl00"]/table/tbody/tr[2]/td/table/tbody//tr/td[2]/a/@href')
    
    • 找到下一页按钮,复制xpath路径。
      在这里插入图片描述
    next_src = tree2.xpath('//*[@id="ctl00"]/table/tbody/tr[3]/td/table/tbody/tr/td/div/a[last()]/@href')[0]
    next_url = "https://kns.cnki.net/kns/brief/brief.aspx"+next_src
    tb.get(next_url)  # 跳转到下一页
    page_text = tb.page_source   # 获取下一页的页面内容
    

    第三步,这样以来,你的selenium会以很快的速度跳转页面并获取内容,最终把所有的链接存入本地文件当中。

    • 全部代码:
    from selenium import webdriver
    from time import sleep
    from lxml import etree
    from 其他文件.知网url正则匹配 import get_detail
    tb = webdriver.Chrome(executable_path="E:\Anaconda3\chromedriver.exe")
    tb.get("https://kns.cnki.net/kns/brief/result.aspx?dbprefix=SCDB&crossDbcodes=CJFQ,CDFD,CMFD,CPFD,IPFD,CCND,CCJD")
    # 选择期刊板块
    qikan = tb.find_elements_by_xpath('//*[@id="CJFQ"]/a')[0]  # 寻找
    qikan.click() # 点击期刊
    sleep(1.5)
    # 输入关键词
    keywords1 = tb.find_element_by_id('txt_1_value1')  # 寻找第一个关键词输入框
    keywords2 = tb.find_element_by_id("txt_1_value2")  # 寻找第二个关键词输入框
    keywords1.send_keys("农地流转")   # 传值
    keywords2.send_keys("风险")      # 传值
    
    
    btn1 = tb.find_element_by_id("btnSearch")  # 寻找检索按钮
    btn1.click()   # 点击检索
    sleep(1.5)
    
    # 我们发现知网的列表内容是嵌入在iframe标签下的,因此要将目标定位到iframe标签内
    tb.switch_to.frame('iframeResult')  # iframe的id
    page_text = tb.page_source   # 获取页面内容
    tree1 = etree.HTML(page_text)   # etree对象
    sleep(1.5)
    
    # 设置每页显示五十页,跳转到新的url
    fifty_url=tree1.xpath('//*[@id="id_grid_display_num"]/a[3]/@href')[0]  # 我们设置每页显示50个,有利于快速获取
    new_url = 'https://kns.cnki.net'+fifty_url  # 在selenium中,访问50页会跳往新的页面(因为这里我们是get一个新的url,正常访问知网是不会跳页面的)
    tb.get(new_url)  # 跳转
    sleep(1.5)
    
    page_text = tb.page_source  # 获取当前页面所有内容
    
    fp = open("农地流转.txt",'a',encoding="utf8")  # 打开存储文件
    
    # 设置读取10页的内容
    for i in range(10):
        tree2= etree.HTML(page_text)  # etree对象
        # 使用xpath获取列表页链接信息(通过标题链接,我们能最终访问到详情页)并存入文件
        content = tree2.xpath('//*[@id="ctl00"]/table/tbody/tr[2]/td/table/tbody//tr/td[2]/a/@href')
        for index,j in enumerate(content,start=1):
            print(index*(i+1),j)  # 这里不用看,只是为了方便看爬下来的信息,使用时正常for循环就可以
            # 这里是不是看不大懂,为什么要调用一个函数,嘿嘿,等会你就知道了
            res = get_detail(j)  # 调用正则表达式,本人正则极其没有天赋,不要嘲笑我。
            fp.write(res+'\n')   # 写入
    
        # 换页(找到下一页按钮的位置,我们选择div下的最后一个a标签,获取其链接)
        next_src = tree2.xpath('//*[@id="ctl00"]/table/tbody/tr[3]/td/table/tbody/tr/td/div/a[last()]/@href')[0]
        next_url = "https://kns.cnki.net/kns/brief/brief.aspx"+next_src
        tb.get(next_url)  # 跳转到下一页
        page_text = tb.page_source   # 获取下一页的页面内容
    
    sleep(2000)  # 等待时间
    fp.close()   # 关闭文件
    tb.quit()  # 关闭selenium
    

    注意:第四步,我兴高采烈地打开文件,发现,爬取下来的链接根本进不去,我们比对一下原链接和我们爬取到的链接:

    我们的:/kns/detail/detail.aspx?QueryID=0&CurRec=1&DbCode=CJFD&dbname=CJFDAUTO&filename=HXLT202101012&urlid=&yx=
    原链接:https://kns.cnki.net/KCMS/detail/detail.aspx?dbcode=CJFD&dbname=CJFDAUTO&filename=HXLT202101012&v=MDE0MDdTN0RoMVQzcVRyV00xRnJDVVI3dWZadVJyRnl2a1Y3dk5MVFhIZXJHNEhORE1ybzlFWm9SOGVYMUx1eFk=

    很奇怪,为什么标题点进去变成了另外一个链接。其实仔细对比这两个链接,好像都有dbcode,dbname参数,filename好像也有。于是我就在原链接试了试,发现去掉dbname,以及后面的v=…,好像也可以进去。
    因此,我们可以将原链接转化为:

    https://kns.cnki.net/KCMS/detail/detail.aspx?dbcode=CJFQ&filename=HXLT202101012

    这样以来,我们就只需要知道filename就可以了。至于dbcode,我试了试,好像没有什么影响。因此只需要用正则表达式把我们爬取到的链接的filename拿到就可以了。

    • 附上代码(真的很low):
    def get_detail(test_url):
        t1 = re.search('filename',test_url,re.I)
        t2 = test_url.split(t1.group(0))[-1]
        c = re.match(r'\W(.*?)\W',t2,re.I)
        filename = c.group(0).strip('&')
        detail_url = base_url + filename
        print(detail_url)
        return detail_url
    

    至此,我们已经获取到了所有的内容。如下:(链接较长的,应该为外文文献,无法访问
    在这里插入图片描述

    第二部分,开始详情页内容爬取

    1. 毋庸置疑,我们现在已经存储的链接是直接可以访问的,因此不用担心请求方式的问题。

    所以,直接上代码。
    在这里插入图片描述

    import requests
    import time
    from lxml import etree
    import pandas as pd
    # 请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:58.0) Gecko/20100101 Firefox/58.0',
    }
    start_time = time.time()  # 开始时间
    def get_detail(url,df_all):
        global count
        print("正在尝试第%d篇......"%(count+1))
        try:  # 处理外文文献报错
            # time.sleep(2)
            response = requests.get(url=url,headers=headers)  # 发起请求
            tree = etree.HTML(response.content)   # 获取二进制信息
            title = tree.xpath('/html/body/div[2]/div[1]/div[3]/div/div/div[3]/div/h1/text()')[0] # 标题
            author = tree.xpath('//*[@id="authorpart"]//text()')[0] # 作者
            abstract = tree.xpath('//*[@id="ChDivSummary"]/text()')[0]  # 摘要
            keywords = tree.xpath("/html/body/div[2]/div[1]/div[3]/div/div/div[5]/p//text()")  # 关键词
            journal = tree.xpath('/html/body/div[2]/div[1]/div[3]/div/div/div[1]/div[1]/span/a[1]/text()')[0]  # 期刊
            hasPeking = tree.xpath('/html/body/div[2]/div[1]/div[3]/div/div/div[1]/div[1]/a[1]/text()')  # 是否北大核心
            hasCSSCI = tree.xpath('/html/body/div[2]/div[1]/div[3]/div/div/div[1]/div[1]/a[2]/text()')   # 是否CSSCI
            # 由于某些原因,不大会写逻辑,因此判断是否是北大核心以及CSSCI有点复杂
            isPeking_true = ""
            isCSSCI_true = ""
            if  hasPeking and hasPeking[0] == "北大核心":
                isPeking_true = hasPeking[0]
            elif hasPeking and hasPeking[0] == "CSSCI":
                isCSSCI_true = hasPeking[0]
                hasPeking[0] = ""
            else:
                isPeking_true = " "
            if isCSSCI_true == ''  and hasCSSCI:
                isCSSCI_true = hasCSSCI[0]
            keyword = ""
            for item in keywords:
                keyword += item.strip()
            df = pd.DataFrame({
                '标题': title,
                '作者': author,
                '摘要': abstract,
                '关键词': keyword,
                '期刊类型': journal,
                '北大核心': isPeking_true,
                'CSSCI': isCSSCI_true,
            }, index=[0])
            df_all = df_all.append(df, ignore_index=True)
            print("sucess")
            # time.sleep(1)
            count+=1
        except:
            print("无法访问!")
        return df_all
    
    with open("农地流转.txt",'r') as f:
        url_list = f.readlines()
    df_all = pd.DataFrame()
    count = 0
    for i in url_list[:150]:
        df_all = get_detail(i,df_all)
    
    df_all.to_excel('demo1.xlsx', index=False)  # 导出excel
    print("成功获取%d篇论文,耗时%ds"%(count,time.time()-start_time))  
    
    

    在这里插入图片描述
    在这里插入图片描述

    • 最终成果展示:
      在这里插入图片描述
    展开全文
  • 实例037 没有标题栏但可以改变大小的窗口 39 1.11 设置窗体位置 40 实例038 设置窗体在屏幕中的位置 40 实例039 始终在最上面的窗体 41 1.12 设置窗体大小 42 实例040 限制窗体大小 42 实例041 获取...
  • 3、地理定位 (获取地理位置信息) 4、web 存储 (在本地存储用户的浏览数据) 5、Web SQL (在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写) 6、应用程序缓存 (创建 web 应用的离线版本。可以在...

    HTML5 API:

    1、文件 API (规范与本地文件进行交互的标准方法)
    
    2、拖放 API (提供了直接支持拖放操作的API)
    
    3、地理定位 (获取地理位置信息)
    
    4、web 存储 (在本地存储用户的浏览数据)	
    
    5、Web SQL	(在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写)
    
    6、应用程序缓存 (创建 web 应用的离线版本。可以在没有网络连接的情况下进行访问。)
    
    7、Web Sockets (在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。)
    
    8、SSE	(网页自动获取来自服务器的更新)
    
    9、Web Workers (web worker 是运行在后台的 JavaScript,不会影响页面的性能)
    
    ......
    

    9、Web Workers (使用Web Workers处理线程)

    • 基础知识
    • 与线程进行数据的交互
    • 线程嵌套
    • 线程中可用的变量、函数与类

    本章介绍HTML5新增的与线程有关的一个功能—使用Web Workers来实现Web平台上的多线程处理功能。通过Web Workers,你可以创建一个不会影响前台处理的后台线程,并且在这个后台线程中创建多个子线程。通过Web Workers,你可以将耗时较长的处理交给后台线程去运行,从而解决了HTML5之前因为某个处理耗时过长而跳出一个提示用户脚本运行时间过长,导致用户不得不结束这个处理的尴尬状况。
    学习内容:

    • 掌握Web Workers的基本知识,能够使用Web Workers在Web网站或应用程序中创建一个后台线程。
    • 掌握在前台页面与后台线程进行数据交互时所使用到的方法与事件,能够在JavaScript脚本中实现前台页面与后台线程之间的数据交互。
    • 掌握在主线程之间嵌套子线程的方法,能够利用JavaScript脚本在主线程之中创建一个或多个子线程,能够实现主线程与子线程,子线程与子线程之间的数据传递。
    • 了解在后台线程中可以使用的JavaScript 脚本中的对象、方法与事件。

    基础知识

    Web Workers是在HTML5中新增的,用来在Web应用程序中实现后台处理的一项技术。
    在使用HTML4与JavaScript创建出来的web应用程序中,因为所有的处理都是在单线程内执行的所以如果花费的时间比较长的话,程序界面会处于长时间没有响应的状态。最恶劣的是,当时间长到一定程度的话,浏览器还会跳出一个提示脚本运行时间过长的提示框,使用户不得不中断正在执行的处理。
    为了解决这个问题,HTML5新增了一个Web Workers API。使用这个API,用户可以很容易地创建在后台运行的线程(在HTML5中被称为worker),如果将可能耗费较长时间的处理交给后台去做的话,对用户在前台页面中执行的操作就完全没有影响了。
    创建后台线程的步骤十分简单。只要在Worker类的构造器中,将需要在后台线程中执行的脚本文件的URL地址作为参数,饭后创建Workers对象就可以了,如下所示:
    var worker = new Worker(“worker.js”);
    但是,要注意在后台线程中是不能访问页面面或窗口对象的。如果在后台线程的脚本文件使用到window对象或document对象,则会引起错误的发生。
    另外,可以通过发送和接收消息来与后台线程互相传递数据。通过对Worker对象的onmessage事件句柄的获取可以在后台线程之中接收消息,如下所示:
    worker.onmessage = function(event){
    //处理收到的消息
    }

    使用worker对象的postMessage方法来对后台线程发送消息,如下例所示。发送的消息是文本数据,但也可以是任何JavaScript对象(需要通过JSON对象的stringify方法将其转换成文本数据

    )。
    worker.postMessage(message);
    另外,同样可以通过Worker对象的onmessage事件句柄及Worker对像的postMessage方法在后台线程内部进行消息的接收和发送。
    接下来,让我们看一个使用后台线程的示例。在该示例中放置了一个文本框,用户在该文本框输入数字,然后点击旁边的计算按钮,在后台计算从1到给定的合计值,虽然对于从1到给定值得求和计算只需要一个求和公式就可以了,但是本示例中为了展示后台线程的使用方法,采用循环计算的方法。
    首先给出HTML4中的关于这个求和运算的示例代码。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>workers</title>   
    </head>
    <body>
        <h1>从1到给定数值的求和:</h1>
        输入数值:<input type="text" id="num">
        <button onclick="calculate()">计算</button>
    
    </body>
    <script>
        function calculate(){
            var num = parseInt(document.getElementById("num").value, 10);
            var result = 0;
            //循环计算求和
            for(var i = 0; i <= num ; i++){
                result += i
            }
            alert("合计值为:" + result)
        }
    </script>
    </html>
    

    执行这段代码的时候,在数值文本框中输入数值,在点击计算按钮之后,并在弹出合计值消息框之前,用户是不能再该页面上进行操作的。另外虽然用户在文本框柱输入比较小的值时,不会有什么问题,但是当用户输入100亿以上的值时,浏览器会弹出一个框,提示脚本执行运行时间过长的对话框,导致用户不得不停止当前计算。

    在HTML5 中,可以对上例子重写,使用WebWorkers API让耗时较长的运算在后台运行,这样在上例的文本框无论输入多大的数值都可以正常运算了。代码如下:

    HTML
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>workers</title>      
    </head>
    <body>
        <h1>从1到给定数值的求和:</h1>
        输入数值:<input type="text" id="num">
        <button onclick="calculate()">计算</button>
    </body>
    <script>
    
        //创建执行运算的线程
        var worker = new Worker("SumCalculate.js");
        //接收从线程中传出的计算结果
        worker.onmessage = function(event){
            //消息文本放置在data属性中,可以使任何JavaScript对象
            alert("h合计值为:" + event.data)
        };
        function calculate(){
            var num = parseInt(document.getElementById("num").value, 10);
            //将值传给线程
            worker.postMessage(num)
        }
    </script>
    </html>
    
    SumCalculate.js:
    onmessage = function(event){
        var num = event.data;
        var result = 0;
        for(var i = 0; i <= num; i++){
            result += i;
        }
        //向线程创建源送回消息
        postMessage(result);
    }
    

    与线程进行数据的交互
    上一节中我们介绍过,使用后台线程时不能访问页面或窗口对象,但是并不代表后台线程不能与页面之间进行数据交互。
    与线程进行数据交互示例(与上一个示例道理一样):

    html:
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>与线程进行数据交互</title>
    </head>
    <body>
      <h1>从随机生成的数字中抽取3的倍数并显示示例</h1>
      <table id="table"></table>
    </body>
    <script>
      var intArray = new Array(100);
      var intStr = "";
      for (let i = 0; i < 100; i++) {
          intArray[i] = parseInt(Math.random()*100);
          if(i != 0)
            intStr += ';';
          intStr += intArray[i];
        
      }
      //向后台进程提交随机数组
      var worker = new Worker("script.js");
      worker.postMessage(intStr);
      //从线程中取得计算结果
      worker.onmessage = function(event){
        if(event.data != ""){
          var j,k,tr,td;
          var intArray = event.data.split(';');
          var table = document.getElementById('table');
          for (var  i = 0; i < intArray.length; i++) {
            j = parseInt(i/10,0);
            k = i%10;
            //改行不存在
            if(k==0){
              //添加行
              tr = document.createElement('tr');
              tr.id = "tr" + j;
              table.appendChild(tr);
            }
            //该行已存在
            else{
              //huo获取该行
              tr = document.getElementById("tr" + j);
            }
            //添加列
            td = document.createElement("td");
            tr.appendChild(td);
            //设置该列内容
            td.innerHTML = intArray[j*10 + k];
            //设置该列背景色
            td.style.backgroundColor = "blue";
            //设置该列字体颜色
            td.style.color = "white";
            //设置列宽
            td.width = "30px";
          }
        }
      };
    </script>
    </html>
    script.js
    onmessage = function(e){
        var data = e.data;
        var returnStr;
        var intArray = data.split(';');
        returnStr = "";
        for (var i = 0; i < intArray.length; i++) {
           if(parseInt(intArray[i])%3 == 0){
               if(returnStr != "")
                returnStr += ";";
                returnStr += intArray[i]
           }
            
        }
        postMessage(returnStr);
    }
    

    线程嵌套
    线程中可以嵌套子线程,这样的话,我们可以把一个较大的后台线程切分成几个子线程,在每个子线程中各自完成相对独立的一部分工作

    • 单层嵌套
      单层嵌套示例的HTML5页面代码:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>单层嵌套</title>
    </head>
    <body>
        <h1>从随机生成的数字中抽取3的倍数并显示示例</h1>
        <table id="table"></table>
      </body>
      <script>
    
        var worker = new Worker("worker1.js");
        worker.postMessage("");
        //从线程中取得计算结果
        worker.onmessage = function(event){
          if(event.data != ""){
            var j,k,tr,td;
            var intArray = event.data.split(';');
            var table = document.getElementById('table');
            for (var  i = 0; i < intArray.length; i++) {
              j = parseInt(i/10,0);
              k = i%10;
              //改行不存在
              if(k==0){
                //添加行
                tr = document.createElement('tr');
                tr.id = "tr" + j;
                table.appendChild(tr);
              }
              //该行已存在
              else{
                //huo获取该行
                tr = document.getElementById("tr" + j);
              }
              //添加列
              td = document.createElement("td");
              tr.appendChild(td);
              //设置该列内容
              td.innerHTML = intArray[j*10 + k];
              //设置该列背景色
              td.style.backgroundColor = "blue";
              //设置该列字体颜色
              td.style.color = "white";
              //设置列宽
              td.width = "30px";
            }
          }
        };
      </script>
    </html>
    

    后台线程的主线程代码部分即worker1.js:

    onmessage = function(){
        var intArray = new Array(100);
        for (var i = 0; i < 100; i++) {
            intArray[i] = parseInt(Math.random()*100);
        }
        //创建子线程
        var worker;
        worker = new Worker("worker2.js");  //运行后报错:Uncaught ReferenceError: Worker is not defined。这里好像在后台不能得到Worker这个函数吧,书本上的例子,不知道书本上是怎么运行的,找了好多也没找到如如何解决,后面的多个子进程也是一样。如果你知道请告诉我一下哈,这个问题纠结了好久,在这先谢谢了。
        worker.postMessage(JSON.stringify(intArray));
        worker.onmessage = function(event){
            postMessage(event.data);
        }
    }
    

    注意:本例中向子线程中提交消息时使用的是worker.postMessage方法,而向主页面提交消息时使用postMessage方法。在线程中,向子线程提交消息时使用子线程对象的postMessage方法,而向本线程的创建源发送消息时直接使用postMessage方法。

    子线程代码:

    onmessage = function(event){
        var intArray = JSON.parse(event.data);
        var returnStr;
        var intArray = data.split(';');
        returnStr = "";
        for (var i = 0; i < intArray.length; i++) {
           if(parseInt(intArray[i]) %3 == 0){
               if(returnStr != "")
                returnStr += ";";
                returnStr += intArray[i]
           }
            
        }
        postMessage(returnStr);
        close();
    }
    

    注意在子线程向发送源发送回消息后,最好使用close语句关闭子线程,如果该子线程不再使用的话。

    在多个子线程中进行数据的交互

    当主线程使用多个子线程时,多个子线程之间如何实现数据的交互。
    要实现子线程与子线程之间的数据交互,大致需要如下几个步骤:

    1. 先创建发送数据的子线程
    2. 执行子线程中的任务,然后把要传递的数据发送给主线程
    3. 在主线程接收到了子线程传回来的消息时,创建接收数据的子线程,然后把发发送数据的子线程中返回的消息传递给接收数据的子线程。
    4. 执行接收数据子线程中的代码。
      代码如下:
    HTML代码:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title></title>
    </head>
    <body>
        <h1>从随机生成的数字中抽取3的倍数并显示示例</h1>
        <table id="table"></table>
      </body>
      <script>
        var worker = new Worker("worker1.js");
        worker.postMessage("");
        //从线程中取得计算结果
        worker.onmessage = function(event){
          if(event.data != ""){
            var j,k,tr,td;
            var intArray = event.data.split(';');
            var table = document.getElementById('table');
            for (var  i = 0; i < intArray.length; i++) {
              j = parseInt(i/10,0);
              k = i%10;
              //改行不存在
              if(k==0){
                //添加行
                tr = document.createElement('tr');
                tr.id = "tr" + j;
                table.appendChild(tr);
              }
              //该行已存在
              else{
                //huo获取该行
                tr = document.getElementById("tr" + j);
              }
              //添加列
              td = document.createElement("td");
              tr.appendChild(td);
              //设置该列内容
              td.innerHTML = intArray[j*10 + k];
              //设置该列背景色
              td.style.backgroundColor = "blue";
              //设置该列字体颜色
              td.style.color = "white";
              //设置列宽
              td.width = "30px";
            }
          }
        };
      </script>
    </html>
    
    主线程 worker1.js中的代码
    onmessage = function(e){
        var worker;
        //创建发送数据的子线程
        worker = new Worker("worker2.js");
        worker.postMessage("");
        worker.onmessage = function(e){
            //接收子线程中的数据,本示例为创建好的随机数组
            var data = e.data;
            //创建接收数据子线程;
            worker = new Worker("worker3.js");
            //把从发送数据的子线程中发回的消息传递给接收数据的子线程
            worker.postMessage(data);
            worker.onmessage = function(e){
                //获取接收数据的子线程中传回的数据,本例中为挑选结果
                var data = e.data;
                //把挑选结果发送回主页面
                postMessage(data);
            }
        }
    }
    
    发送数据(本例中为创建好的随机数组)的子线程1 worker2.js:
    onmessage = function(){
        var intArray = new Array(100);
        for (var i = 0; i < 100; i++) {
            intArray[i] = parseInt(Math.random()*100);
        }
       //发回随机数组
        postMessage(JSON.stringify(intArray));
        //关闭子进程
        close();
    }
    
    接收数据并发回挑选结果的子进程2 worker3.js:
    onmessage = function(event){
        var intArray = JSON.parse(event.data);
        var returnStr;
        var intArray = data.split(';');
        returnStr = "";
        for (var i = 0; i < intArray.length; i++) {
           if(parseInt(intArray[i]) %3 == 0){
               if(returnStr != "")
                returnStr += ";";
                returnStr += intArray[i]
           }
            
        }
        postMessage(returnStr);
        close();
    }
    
    

    线程中可用的变量、函数与类
    最后,我们再来总体看一下在线程用的JavaScript脚本文件中所有可用的变量、函数与类,如下所示:
    self self关键词用来表示本线程范围内的作用域。
    postMessage(message) 向创建线程的源窗口发送消息
    onmessage 获取接收消息的事件句柄
    importScripts(url)导入其他JavaScript脚本文件。参数为该脚本文件的URL地址,可以导入多个脚本文件如下所示:importScript(‘script1.js’, ‘scripts/script2.js’, ‘script/script3.js’);导入的脚本文件必须与使用该线程文件的页面在同一域中,并在同一个端口中。
    navigator对象 与window.navigator对象类似,具有appName、platform、userAgent、appVersion这些属性。
    sessionStorage/localStorage 可以在线程中使用Web Storage
    XMLHttpRequest 可以在线程中处理Ajax请求。
    Web Workers 可以在线程中嵌套线程。
    setTimeout/setInterval() 可以在线程中实现定时处理。
    close 可以结束本线程
    eval()、isNaN()、escape()等 可以使用所有JavaScript核心函数。
    object 可以创建和使用本地对象
    WebSockets 可以使用WebSockets API来向服务器发送和接收信息。

    参考阅读:

    展开全文
  • 3、地理定位 (获取地理位置信息) 4、web 存储 (在本地存储用户的浏览数据) 5、Web SQL (在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写) 6、应用程序缓存 (创建 web 应用的离线版本。可以在...
  • 3、地理定位 (获取地理位置信息) 4、web 存储 (在本地存储用户的浏览数据) 5、Web SQL (在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写) 6、应用程序缓存 (创建 web 应用的离线版本。可以在...
  • 3、地理定位 (获取地理位置信息) 4、web 存储 (在本地存储用户的浏览数据) 5、Web SQL (在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写) 6、应用程序缓存 (创建 web 应用的离线版本。可以在...
  • 3、地理定位 (获取地理位置信息) 4、web 存储 (在本地存储用户的浏览数据) 5、Web SQL (在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写) 6、应用程序缓存 (创建 web 应用的离线版本。可以在...
  • 3、地理定位 (获取地理位置信息) 4、web 存储 (在本地存储用户的浏览数据) 5、Web SQL (在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写) 6、应用程序缓存 (创建 web 应用的离线版本。可以在...
  • 3、地理定位 (获取地理位置信息) 4、web 存储 (在本地存储用户的浏览数据) 5、Web SQL (在浏览器上模拟数据库,可以使用JS来操作SQL完成对数据的读写) 6、应用程序缓存 (创建 web 应用的离线版本。可以在...
  • 目前,该应用程序在显示数据时没有区分低、高和 g 等级,但这应该不难实现,因为这些信息是在模型端跟踪的。 其他问题:所有数据目前都是模拟数据,因此非常不完整。 很少有时间花在美学设计/可读性上。 需要...
  • 极验geetest破解

    千次阅读 2016-12-30 15:27:53
    搜索了一番,最终我没有采用网上的方法。是自己原创的方法。 极验geetest现已被很多网站应用。如果每次都要输入验证码对于某些有着敏感信息的网站,如果需要爬虫可是利器。...3.模拟人工滑动到正确位置。 经过
  • 渗透测试分类

    千次阅读 2020-04-02 09:48:29
    实际上渗透测试并没有严格的分类方式,即使在软件开发生命周期中,也...采用这种方式时,渗透测试团队将从一个远程网络位置来评估目标网络基础设施,并没有任何目标网络内部拓扑等相关信息,他们完全模拟真实网络环...
  • FMI符合性检查器(FMUChecker)应用程序的背景信息。 有关构建说明,请参见: 许可证信息在以下位置提供: 二手软件致谢: 有关发布说明,请执行以下操作: FMI符合性检查器旨在验证FMU 1.0和2.0是否符合在以下位置...
  • 如果我们没有有关现有自动售货机的信息,我们将依靠众包,允许用户通过移动应用程序将新机器及其当前内容提交到我们的数据库中。 团队背景: 亚历克斯:第六学期 语言:C,C ++,Java,Verilog HDL,Python 经验:IS...
  • 工业阀门将其用于获得位置信息,测量流量; 汽车将其用于发动机定时、牵引力控制、踏板定位以及门禁等; 游戏控制器将其用于传感各种触发器; 膝上型电脑将其用于传感上盖闭合; 车把把套、操纵杆以及转盘将其...
  • 此工具箱中的Matlab函数具有提供位置信息的矢量和矩阵的标准约定。围绕这些约定开发的函数允许有效地重用,兼容和修改工具箱函数。 以下矩阵和向量约定适用于所有适用的工具箱函数: 与阵列相关联的信号的集合...
  • 例如,模拟指针可指示空气质量沿黄色带的位置(例如,它更接近绿色,还是更接近橙色,或介于两者之间?) 它从指定的Purple Air传感器(以JSON格式返回的PM2.5数据)获取空气质量信息,并计算10分钟的平均AQI(空气...

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 265
精华内容 106
关键字:

模拟位置信息没有应用