必威体育下载基督教Heilmann

“php”标签的文章

用PHP/JS/CSS为Mozilla构建降临节日历(第1部分)

周二,11月29日,2011

昨天早上,我受到启发,尝试为Mozilla开发人员网络构建一个降临节日历,我们将为您提供一个每日链接。这是我的工作日志。也许这对你来说是鼓舞人心的,也许不是。让我们试一试。

第一步:将24扇“门”分布在一个巨大的标识上

这是简单的。我将徽标作为背景放入具有正确尺寸的元素中,并将其定位为相对的元素。然后我写了一个小脚本,在“画布”上随机放置24个链接正确的列表项:


             
回声 '
             
    ' ; 美元的宽度 = 700 ; 美元的高度 = 800 ; ( 我美元 = 0 ; 我美元 < 24 ; 我美元 ++ ) { $ x = 兰德 ( 10 , 美元的宽度 - - - - - - 10 ) ; $ y = 兰德 ( 10 , 美元的宽度 - - - - - - 10 ) ; 回声 '
  1. $ x“px;最高:”$ y“px“>” '(我美元+1)“>”(我美元+1)'' '
  2. '
    ; } 回声 '
'
; ? >
  • ”。'”。(i + 1美元)。””。'
  • “;}回声””;? >

    我给了列表项一个大小,并将它们完全定位,然后查看结果。我重新加载,直到没有很多重叠,用手移动它们,在Firebug中抓取列表的innerHTML,我就有了很棒的日历布局。:)

    看这里:http://isithackday.com/calendar-tutorial/random.php

    步骤2:构建API

    下一步是构建API以显示当您单击其中一个链接时。这是我做的一个模型,了。很简单,真的。

    
                
      元数据 = ;
      美元一天 = 0;
      美元一天 = +$ _GET[“天”];
      如果 (美元一天 > 24) { 美元一天 = 24; }如果 (美元一天) {
        元数据 .= '

    标题的美元一天'

    '
    '

    描述

    '
    '

    看到它的作用在这里

    '
    ; } ? >

    标题“美元一天。”

    ”。'

    描述

    ”。'

    看到它的作用在这里

    ”;} ?

    我决定了日子URL参数,并确保它不大于24。如果有一个有效的号码发送进来,我组装了一串HTML与输出数据显示的一天。由于$day被预先设置为0,当发送的数据不是一个有效数字时,$day将为0,$data将为空。

    然后在页面中创建一个元素,有条件地写出内容:

    我所需要做的就是在以后的降临节日历中添加一个日期验证。

    
                 
    如果 (+日期(“米”) < 12 | | 美元一天 > +日期(' d ')) {
      美元一天 = 0;
    }
    ? >

    就目前而言,我把它注释掉了,虽然。

    在这里看到它的行动:http://isithackday.com/calendar-tutorial/dummyapi.php

    步骤3:ajax化

    现在一切都好了,但为了让它更光滑,如果可能的话,让我们通过Ajax加载内容。第一步是将article元素定义为输出容器,并使用事件委托找出单击了哪个list元素:

    var列表=文档。querySelector(“ol”),输出=文档。querySelector(“文章”);列表。addEventListener(“点击”, 函数(电动汽车) {
      vart=电动汽车。目标;
      如果 (t。tagName = = =“一个”) {负载(+t。innerHTML);
      }电动汽车。preventDefault();
    }, );函数负载(一天) {警报(一天);
    }

    然后我将虚拟api移到一个自己的文件(simpleapi)中,并添加了另一个参数检查:

    
                
      元数据 = ;
      美元一天 = 0;
      美元一天 = +$ _GET[“天”];
      如果 (美元一天 > +日期(' d ')) {
        美元一天 = 0;
      }
      如果 (美元一天 > 24) { 美元一天 = 24; }如果 (美元一天) {
        元数据 .= '

    标题的美元一天'

    '
    '

    描述

    '
    '

    看到它的作用在这里

    '
    ; } 如果 (收取($ _GET[“ajax”])) { 回声 元数据; } ? >

    标题“美元一天。”

    ”。'

    描述

    ”。'

    看到它的作用在这里

    ”;} if (isset($_GET['ajax'])) {echo $data;} ?

    这样,我只需执行一个经典的Ajax调用,向url中添加一个新参数来触发PHP:

    函数负载(一天) {
      varhttpstats= / 200 | 304 /;
      var请求= XMLHttpRequest();请求。onreadystatechange = 函数() {
        如果 (请求。请求处理 = = 4) {
          如果 (请求。状态 & &httpstats。测试(请求。状态)) {输出。innerHTML =请求。responseText;
          } 其他的 {文档。位置 = “index . php ?天= ' +一天;
          }
        }
      };请求。开放(“得到”, “simpleapi.php ? ajax = 1后= '+一天, 真正的);请求。setRequestHeader(“if - modified - since”,
                               “结婚,2006年04月05日00:00:00 GMT);请求。发送();  
    }

    如果您想知道请求头中的日期,是的,我确实撕了我自己的代码来自我2006年的Ajax书。:)

    http://isithackday.com/calendar-tutorial/ajax.php

    今天就到这里

    这是主要的功能,真的。在第2部分中,我将向您展示如何从web上提取真实数据并使其看起来更加性感,如下所示:

    社交网络的研究界面——现在就分叉,找到人们在谈论什么

    周三,9月22日,2010

    在网上搜索东西是很烦人的。搜索引擎一年比一年好,但是有很多社交网站没有被编入索引。例如,如果我搜索一张漂亮的照片一只小熊猫的照片我使用谷歌图像搜索。如果我以后想使用这张照片,我最好使用Flickr或Picasa看看照片的许可是什么。

    雅虎的研究人员也有同样的问题,这就是为什么他们把所有的社交更新整合在一起XML喂- - -雅虎消防带。这一点,与雅虎的其他api不同的是附带商业条款和条件可透过YQL。在数据方面,消防水管汇集了许多不同的来源:

    雅虎360年,美国在线,Bebo,博主,博客订阅,Digg,Diigo,Goodreads,谷歌,谷歌阅读器,last . fm,gnolia活动类型,Netflix,潘多拉,Picasa,Pownce,Seesmic,Slideshare,SmugMug,StumbleUpon,ThisNext,TravelPod,Tumblr,推特,TypePad,Vimeo,声音,Webshots,Xanga,Yelp,YouTube,Zooomr,雅虎阿凡达,雅虎Buzz,雅虎概要文件,紫藤,雅虎答案,雅虎购物,雅虎汽车、Bix雅虎,雅虎书签,雅虎公文包,雅虎日历,雅虎分类,美味,雅虎的家庭,雅虎体育运动,雅虎金融、Flickr,雅虎食物,雅虎游戏,雅虎your own,雅虎绿色,雅虎问候,雅虎组,雅虎健康,雅虎Hotjobs,雅虎孩子,雅虎本地的,雅虎电影,雅虎音乐,MyBlogLog,雅虎新闻,我的天啊!从雅虎,雅虎个人,雅虎宠物,雅虎状态更新,雅虎留言板的评论,SearchMonkey从雅虎!雅虎购物,雅虎体育运动,雅虎技术,雅虎旅行,雅虎电视,雅虎视频。

    你可以做数据上瘾的部分,并在YQL控制台:

    这很烦人,尤其是当你看不到照片和视频的时候。这就是为什么我把一个研究界面放在Yahoo Firehose上面:

    你可以参见这里的research接口但更重要的是,的接口的源代码可以在GitHub上找到这意味着您可以自己托管它——例如在防火墙后面或将其作为内部网的一部分。

    对于本地安装,您需要这样做注册一个开发人员密钥,edit the keys.php file,把所有的文件都放在你的文件夹里PHP启用服务器,就完成了。如果你陷入困境,你可以寻求帮助YDN论坛

    请注意,当您的浏览器支持它时,我将它存储在本地存储中,从而保持您上次搜索的状态——这对于大型搜索非常有用。

    黑客日工具箱-让你开始得更快

    周四,7月29日2010

    刚刚花了很多时间在班加罗尔的开放黑客日,我发现,关于使用雅虎技术发动黑客攻击的大多数问题都围绕着几个问题:

    • 如何从web服务访问web上的数据?
    • 如何使用YQL从JavaScript或PHP吗?
    • 如何显示接收到的信息YQLPHP或JavaScript ?
    • 我如何获得用户的位置,如何分析地理位置的内容?
    • 我如何访问雅虎的oAuth认证信息?
    • 我如何设置PHP在哪里可以看到错误?

    所以,为了避免再次重复,我把它们放在一起Hackday工具箱其中包含处理所有这些问题的示例代码。

    Hackday工具箱

    黑客日工具箱包含:

    • 安装和使用的介绍PHPMAMP/XAMPP并调试它
    • YQL地理满足您所有的地理位置需求
    • 演示的查询YQL在JavaScript中,YUI3PHP
    • 演示显示YQL数据
    • 访问Yahoo Firehose的经过身份验证的示例
    • 将Yahoo Geoplanet数据绘制成地图

    你可以在GitHub上下载Hackday工具箱试的例子

    工具箱是BSD许可,如果你想添加Java/Ruby/Python/Heskell/Pascal/Logo/Fortran/6502汇编代码示例,请这样做。

    我把我的弓放在一个盒子里……

    使用jQuery和YQL使用Ajax加载外部内容

    星期天,1月10日,2010

    让我们用jQuery中的Ajax来解决加载外部内容(在其他域中)的问题。您在这里看到的所有代码都是GitHub上可用可以在这个演示页面上看到吗所以不需要复制粘贴!

    好吧,使用jQuery的Ajax非常容易实现——就像大多数解决方案一样,它只有几行代码:

    美元(文档)准备好了(函数(){美元(“.ajaxtrigger”)点击(函数(){美元(“#目标”)负载(“ajaxcontent.html”);
      });
    });

    看看这个简单而引人注目的Ajax演示看看它有什么用。

    这将转换类的所有元素ajaxtriggerinto triggers to load "ajaxcontent.html" and display its contents in the element with theID目标

    这是可怕的,因为大多数情况下,这意味着人们将使用毫无意义的链接,如“点击我”与#作为href,但这不是今天的问题。我正在撰写一篇关于Ajax可用性和可访问性的好文章。

    然而,为了使它更可重用,我们可以做以下工作:

    美元(文档)准备好了(函数(){美元(“.ajaxtrigger”)点击(函数(){美元(“#目标”)负载(美元()attr(“href”));
        返回 ;
      });
    });

    然后你可以使用加载一些内容加载内容,使整个内容可重用。

    看看这个更多可重用Ajax演示看看它有什么用。

    我想要找到的一个很好的解决方案是当您单击演示中的第二个链接时发生的问题:加载外部文件失败,因为Ajax不允许跨域加载内容。这意味着看到我的投资组合将无法加载Ajax内容,并在此情况下静默失败。你可以点击链接,直到你的脸是蓝色的,但什么也没有发生。避免这种情况的一种肮脏的方法是,如果有人真的试图加载外部链接,则允许浏览器加载文档。

    看看这个允许遵循外部链接看看它有什么用。

    美元(文档)准备好了(函数(){美元(“.ajaxtrigger”)点击(函数(){
        varurl=美元()attr(“href”);
        如果(url。匹配(“^ http”)){
          返回 真正的;
        } 其他的 {美元(“#目标”)负载(url);
          返回 ;
        }
      });
    });

    代理与PHP

    如果你在网上搜索,你会发现大多数情况下的解决方案是PHP代理脚本(或任何其他语言)。的东西使用旋度例如proxy.php:

    
                
    $ url = $ _GET[“url”];
    ch美元 = curl_init(); 
    curl_setopt(ch美元,CURLOPT_URL, $ url); 
    curl_setopt(ch美元,CURLOPT_RETURNTRANSFER, 1); 
    输出美元 = curl_exec(ch美元); 
    curl_close(ch美元);
    回声 美元的内容;
    ? >

    然后人们可以使用稍微改变的脚本(使用代理):

    美元(文档)准备好了(函数(){美元(“.ajaxtrigger”)点击(函数(){
        varurl=美元()attr(“href”);
        如果(url。匹配(“^ http”)){url= “proxy.php ? url = ' +url;
        }美元(“#目标”)负载(url);
        返回 ;
      });
    });

    它也是非常愚蠢的想法拥有这样的代理脚本。原因是,如果不过滤,人们可以使用它来加载服务器的任何文档并将其显示在页面中(只需使用firebug重命名链接以显示服务器上的任何内容),他们可以使用它将一个mass-mailer脚本注入到您的文档中,或者简单地使用它重定向到任何其他web资源,使其看起来像是您的服务器发送的。这是垃圾邮件制造者的天堂。

    使用白名单和过滤代理!

    如果你想使用代理,确保列出允许的uri。此外,这是一个很好的计划,摆脱一切,但身体的另一个HTML文档。另一个好主意是过滤掉脚本。这可以防止显示故障和不希望在站点上执行的脚本被执行。

    是这样的:

    
                
    $ url = $ _GET[“url”];
    allowedurls美元 = 数组(
      “http://developer.yahoo.com”,
      “http://icant.co.uk”
    );
    如果(in_array($ url,allowedurls美元)){
      ch美元 = curl_init(); 
      curl_setopt(ch美元,CURLOPT_URL, $ url); 
      curl_setopt(ch美元,CURLOPT_RETURNTRANSFER, 1); 
      输出美元 = curl_exec(ch美元); 
      curl_close(ch美元);
      美元的内容 = preg_replace(“/ *。
                 
                  ]* > / msi的
                 ,,输出美元);
      美元的内容 = preg_replace(' / > < \ /身体。* / msi的,,美元的内容);
      美元的内容 = preg_replace(' /
                 ]* > / msi的,,美元的内容);
      美元的内容 = preg_replace(' / [| \ r \ n] + / msi ',,美元的内容);
      美元的内容 = preg_replace(' / <,[\ S \ S]*吧> / msi ',,美元的内容);
      美元的内容 = preg_replace(' /
                 
                  )* >[\ S \ S]* ?”
                 
                              < \ / noscript > / msi的,
                              ,美元的内容);
      美元的内容 = preg_replace(' /
                 
                  ]* > [\ S \ S] * ? > < \ /脚本/ msi '
                 ,
                              ,美元的内容);
      美元的内容 = preg_replace(' /
                 / msi ',,美元的内容);
      回声 美元的内容;
    } 其他的 {
      回声 错误:URL不允许在这里加载。;
    }
    ? >

    使用纯JavaScript解决方案YQL

    但是,如果您没有服务器访问权限或者希望继续使用JavaScript,该怎么办呢?别担心,这是可以做到的。YQL允许您加载任何HTML记录下来,拿回去JSON。jQuery有一个很好的接口可以加载JSON,这可以一起用来实现我们想要的。

    得到HTMLYQL简单易用:

    选择*从html url=“http://icant.co.uk”

    YQL为我们做一些额外的事情:

    • 它加载HTML记录并消毒
    • 它运行的HTML文档通过HTML整齐地搬运东西net讨厌的框架考虑标记。
    • 它缓存HTML有一段时间
    • 它只返回。的主体内容HTML-所以没有样式(除了内联样式)可以通过。

    作为输出格式,您可以选择XMLJSON。如果你定义一个回调参数JSON你得到JSON-P和所有的HTML作为一个JavaScript对象-不好玩的重新组装:

    喷火({
      “查询”:{
      “数”:“1”,
      “创建”:“2010 - 01 - 10 t07:51:43z”,
      “朗”:“en - us”,
      “更新”:“2010 - 01 - 10 t07:51:43z”,
      “uri”:“http://query.yahoo[…无论…]k % 22”,
      “结果”:{
        “身体”:{
          " div ":{
            “id”:“doc2”,
            " div ":[{“id”:“高清”,
              “标题”:"icant.co.uk - everything 必威体育下载Christian Heilmann"
            },
            {“id”:“bd”,
            " div ":[
            {" div ":[{“氢气”:“betway体育官方网关于这个和我”,“[…等等…]}}}}}}}});

    当您使用。定义回调时XML的函数调用HTML数据作为字符串在一个数组-更容易:

    喷火({
      “查询”:{
      “数”:“1”,
      “创建”:“2010 - 01 - 10 t07:47:40z”,
      “朗”:“en - us”,
      “更新”:“2010 - 01 - 10 t07:47:40z”,
      “uri”:"http://query.y[...who cares...]%22"},
      “结果”:[
        "\ n    
                
    \”doc2 \”> \ n
    \”高清 \”> \ n

    icant.co.uk -\ n所有基督徒Heilma必威体育下载nn <\ /h1 >\ n…等等……” ] });

    \ n
    \ n

    icant.co.uk - \n everything 必威体育下载Christian Heilmann<\/h1>\n ...and so on ..." ]});

    使用jQuery的getJSON()方法和访问YQL端点这很容易实现:

    美元。getJSON(“http://query.yahooapis.com/v1/public/yql?”+
              “q =选择% 20 * % 20从% 20 html % 20 % 20 url % 3 d % 22”+encodeURIComponent(url)+
              “% 22 format = xml调= ?”,
      函数(数据){
        如果(数据。结果[0]){
          var数据=filterData(数据。结果[0]);容器。html(数据);
        } 其他的 {
          varerrormsg= '

    错误:可以不要加载页面。 p>”;container.html (errormsg);}});

    错误:无法加载页面。

    ”;container.html (errormsg);}});

    把它们放在一起就得到a跨域Ajax解决方案与jQuery和YQL:

    美元(文档)准备好了(函数(){
      var容器=美元(“#目标”);美元(“.ajaxtrigger”)点击(函数(){doAjax(美元()attr(“href”));
        返回 ;
      });
      函数doAjax(url){
        //如果它是一个外部URI
        如果(url。匹配(“^ http”)){
          / /调用YQL美元。getJSON(“http://query.yahooapis.com/v1/public/yql?”+
                    “q =选择% 20 * % 20从% 20 html % 20 % 20 url % 3 d % 22”+encodeURIComponent(url)+
                    “% 22 format = xml调= ?”,
            //这个函数从success获取数据
            / / JSON-P电话
            函数(数据){
              //如果有数据,过滤并渲染它
              如果(数据。结果[0]){
                var数据=filterData(数据。结果[0]);容器。html(数据);
              //否则就告诉世界出了问题
              } 其他的 {
                varerrormsg= '

    错误:可以不要加载页面。 p>”;container.html (errormsg);} });//如果它不是外部URI,使用Ajax load()} else {$(')#目标”).load (url);过滤掉一些不好的函数filterData(data){data = data.replace(/) \ /身体[^ >]* > / g,””);data = data.replace (/ (r \|\ n)+ / g”,”);data = data.replace(/ <——[\ S\ s)* ? - - > / g”,”);data = data.replace(/ ]* >[ \ S \ s)* ? < \ /noscript > / g。” ”);data = data.replace(/ ]* >[ \ S \ s)* ? < \ /脚本> / g”, ”);data = data.replace(/ \ / > /,”);返回数据;} });

    错误:无法加载页面。

    ”;container.html (errormsg);} });//如果它不是外部URI,使用Ajax load()} else {$('#target').load(url);过滤掉一些不好的函数filterData(data){data = data.replace(/) )* > / g,”);data = data.replace(/[| \ r \ n]+ / g,”);data = data.replace (/ <, [\ S \ S] *吧> / g,”);data = data.replace(/ )* >[\ S \ S]* ? < \ / noscript > / g,”);data = data.replace(/ )* >[\ S \ S]* ? > < \ /脚本/ g,”);data = data.replace(/ /”);返回数据;} });

    这是粗糙的,当然是现成的。真正的Ajax解决方案还应该考虑超时和未找到的场景。检查带有加载指示器的完整版本,错误处理和黄色渐变寻找灵感。

    目录脚本-我的老对手

    周三,1月6日2010

    我喜欢的一件事是——让我换一种说法——我喜欢Microsoft Word少有的令人惊讶的一点是你可以从一个文档中生成一个目录。Word将遍历标题并创建一个嵌套的TOC他们给你的:

    向Word文档中添加TOC

    微软Word生成的目录。

    现在,我总是喜欢对我写的文档这样做HTML,同样的,但是用手来维护它们是很痛苦的。我通常先写我的文件大纲:

    
                    
                    id=
                    “可爱”
                    >
                   网上可爱的东西>
    
                    
                    id=
                    “兔子”
                    >
                   兔子>
    
                    
                    id=
                    “小狗”
                    >
                   小狗>
    
                    
                    id=
                    “实验室”
                    >
                   拉布拉多>
    
                    
                    id=
                    “阿尔萨斯”
                    >
                   阿尔萨斯>
    
                    
                    id=
                    “corgies”
                    >
                   Corgies>
    
                    
                    id=
                    “猎犬”
                    >
                   猎犬>
    
                    
                    id=
                    “小猫”
                    >
                   小猫>
    
                    
                    id=
                    “沙鼠”
                    >
                   沙鼠>
    
                    
                    id=
                    “小鸭”
                    >
                   小鸭>

    网上可爱的东西

    兔子

    小狗

    拉布拉多

    阿尔萨斯

    Corgies

    猎犬

    小猫

    沙鼠

    小鸭

    然后我收集这些,复制粘贴,使用搜索和替换来旋转所有的hn到链接和id到片段标识符:

    
                   
                    >
                   
                   
                   href=
                   “#可爱的”
                   >
                  网上可爱的东西>>
    
                   
                    >
                   
                   
                   href=
                   “#兔子”
                   >
                  兔子>>
    
                   
                    >
                   
                   
                   href=
                   “#小狗”
                   >
                  小狗>>
    
                   
                    >
                   
                   
                   href=
                   “#实验室”
                   >
                  拉布拉多>>
    
                   
                    >
                   
                   
                   href=
                   “#阿尔萨斯人”
                   >
                  阿尔萨斯>>
    
                   
                    >
                   
                   
                   href=
                   “# corgies”
                   >
                  Corgies>>
    
                   
                    >
                   
                   
                   href=
                   “#猎犬”
                   >
                  猎犬>>
    
                   
                    >
                   
                   
                   href=
                   “#小猫”
                   >
                  小猫>>
    
                   
                    >
                   
                   
                   href=
                   “#沙鼠”
                   >
                  沙鼠>>
    
                   
                    >
                   
                   
                   href=
                   “#小鸭”
                   >
                  小鸭>>
                    
                    id=
                    “可爱”
                    >
                   网上可爱的东西>
    
                    
                    id=
                    “兔子”
                    >
                   兔子>
    
                    
                    id=
                    “小狗”
                    >
                   小狗>
    
                    
                    id=
                    “实验室”
                    >
                   拉布拉多>
    
                    
                    id=
                    “阿尔萨斯”
                    >
                   阿尔萨斯>
    
                    
                    id=
                    “corgies”
                    >
                   Corgies>
    
                    
                    id=
                    “猎犬”
                    >
                   猎犬>
    
                    
                    id=
                    “小猫”
                    >
                   小猫>
    
                    
                    id=
                    “沙鼠”
                    >
                   沙鼠>
    
                    
                    id=
                    “小鸭”
                    >
                   小鸭>
  • 网上可爱的东西
  • 兔子
  • 小狗
  • 拉布拉多
  • 阿尔萨斯
  • Corgies
  • 猎犬
  • 小猫
  • 沙鼠
  • 小鸭
  • 网上可爱的东西

    兔子

    小狗

    拉布拉多

    阿尔萨斯

    Corgies

    猎犬

    小猫

    沙鼠

    小鸭

    然后,我需要查看标题的权重和顺序,并添加嵌套TOC相应的列表。

    
                   
                    >
                   
      
                   
                    >
                   
                   
                   href=
                   “#可爱的”
                   >
                  网上可爱的东西>
        
                   
                    >
                   
          
                   
                    >
                   
                   
                   href=
                   “#兔子”
                   >
                  兔子>>
          
                   
                    >
                   
                   
                   href=
                   “#小狗”
                   >
                  小狗>
            
                   
                    >
                   
              
                   
                    >
                   
                   
                   href=
                   “#实验室”
                   >
                  拉布拉多>>
              
                   
                    >
                   
                   
                   href=
                   “#阿尔萨斯人”
                   >
                  阿尔萨斯>>
              
                   
                    >
                   
                   
                   href=
                   “# corgies”
                   >
                  Corgies>>
              
                   
                    >
                   
                   
                   href=
                   “#猎犬”
                   >
                  猎犬>>
            >
          >
          
                   
                    >
                   
                   
                   href=
                   “#小猫”
                   >
                  小猫>>
          
                   
                    >
                   
                   
                   href=
                   “#沙鼠”
                   >
                  沙鼠>>
          
                   
                    >
                   
                   
                   href=
                   “#小鸭”
                   >
                  小鸭>>
        >
      >
    >
                    
                    id=
                    “可爱”
                    >
                   网上可爱的东西>
    
                    
                    id=
                    “兔子”
                    >
                   兔子>
    
                    
                    id=
                    “小狗”
                    >
                   小狗>
    
                    
                    id=
                    “实验室”
                    >
                   拉布拉多>
    
                    
                    id=
                    “阿尔萨斯”
                    >
                   阿尔萨斯>
    
                    
                    id=
                    “corgies”
                    >
                   Corgies>
    
                    
                    id=
                    “猎犬”
                    >
                   猎犬>
    
                    
                    id=
                    “小猫”
                    >
                   小猫>
    
                    
                    id=
                    “沙鼠”
                    >
                   沙鼠>
    
                    
                    id=
                    “小鸭”
                    >
                   小鸭>

    网上可爱的东西

    兔子

    小狗

    拉布拉多

    阿尔萨斯

    Corgies

    猎犬

    小猫

    沙鼠

    小鸭

    现在,自动为我做那件事不是很好吗?用JavaScript和DOM这其实是一个比乍一看要复杂得多的问题(我总是喜欢在面试的时候问这个问题或在面试的时候问这个问题)DOM脚本研讨会)。

    以下是一些需要考虑的问题:

    • 你可以很容易地得到元素getElementsByTagName ()但是你不能这样做getElementsByTagName(h *)可悲的是足够了。
    • 标题在XHTMLHTML 4没有将它们应用到的元素作为子元素(XHTML2提出了这一点,并且?HTML5在某种程度上-布鲁斯·劳森写了一篇关于这方面的好文章betway体育官方网还有a相当漂亮的HTML5大纲窗口可用)。
    • 你可以做一个getElementsByTagName ()对于每个标题级别,然后连接它们的一个集合。然而,这并没有给出文档源中的顺序。
    • 为此PPK写了一个臭名昭著的TOC脚本很久以前在他的网站上用过getelementsbytagname ()不是每个浏览器都支持的功能。因此,它也不完全起作用。他还在大会上“作弊”TOC列表,因为他添加类是为了在视觉上缩进它们,而不是真正嵌套列表。
    • 这似乎是为所有使用DOM是痛苦的:做一个getElementsByTagName(“*”)走完全程DOM树,比较节点名标题是这样的。
    • 我想到的另一个解决方案是阅读innerHTML然后使用正则表达式来匹配标题。
    • 因为您不能假定每个标题都有一个ID,所以我们需要在需要时添加一个ID。

    下面是一些解决这个问题的方法:

    使用DOM:

    (函数(){
      var标题= [];
      varherxp= / h \ d /我;
      var= 0;
      var榆树=文档。getElementsByTagName(‘*’);
      (var=0,j=榆树。长度;<j;++){
        var坏蛋=榆树[];
        varid=坏蛋。id;
        如果(herxp。测试(坏蛋。节点名)){
          如果(坏蛋。id= = =){id= “头”+;坏蛋。id =id;+ +;
          }标题。(坏蛋);
        }
      }
      var= '
                  
      ' ; (= 0 ,j =标题。 长度 ;<j ;++ ) { var重量 =标题 []节点名字符串的子串 ( 1 , 1 ) ; 如果 (重量 >oldweight ) {+ = ' ' ; } 如果 (重量 = =nextweight ) {+ = '' ; } } varoldweight =重量 ; }+ = '
    '
    ;文档。getElementById(“目录”)innerHTML =; })();
      ”;} out += '
    • “+标题[我].innerHTML +””;if(heading [i+1]){var nextweight = heading [i+1].nodeName.substr(1,1);if(weight > nextweight){out+='
    ”;} if(weight == nextweight){out+='”;{} var oldweight =权重;} out += '”;document.getElementById('toc').innerHTML = out;})();

    你可以看到DOM实际解决方案。它的问题是,在处理大型文档和输入时,它会变得非常慢MSIE6

    正则表达式解决方案

    要绕过工作需要遍历的全部DOM,我认为在。上使用正则表达式可能是个好主意innerHTMLDOM一旦我添加了id并组装了TOC:

    (函数(){
      var双相障碍=文档。身体,x=双相障碍。innerHTML,标题=x。匹配(/
                  
                   )* >[\ S \ S]* ? < \ / h \ d >美元/毫克
                  ),r1= / > /,r2= / / <(\)? h(\ d)/ g,toc=文档。createElement(“div”),= '
                  
      ' ,= 0 ,j =标题。 长度 ,坏蛋 = ,重量 = 0 ,nextweight = 0 ,oldweight = 2 ,容器 =双相障碍 ; (= 0 ;<j ;++ ) { 如果 (标题 []indexOf ( “id =” ) = = - 1 ) {坏蛋 =标题 []取代 (r1 , “id =“h” ++ “>” ) ;x =x。 取代 (标题 [] ,坏蛋 ) ; } 其他的 {坏蛋 =标题 [] ; }重量 =坏蛋。 字符串的子串 ( 2 , 1 ) ; 如果 (<j - - - - - - 1 ) {nextweight =标题 [+ 1 ]字符串的子串 ( 2 , 1 ) ; } var一个 =坏蛋。 取代 (r2 , < 1美元的 ) ;一个 =一个。 取代 ( id = "的 , “href = " #” ) ; 如果 (重量 >oldweight ) {+ = '
        ' ; }+ = '
      • '+一个; 如果(nextweight<重量){+ ='
      '
      ; } 如果 (nextweight = =重量 ) {+ = '' ; }oldweight =重量 ; }双相障碍。 innerHTML =x ;toc。 innerHTML =+ '
    '
    ;容器=文档。getElementById(“目录”) | |双相障碍;容器。列表末尾(toc); })();
      ”,我= 0,j = headings.length,坏蛋= ",重量= 0,nextweight = 0,oldweight = 2,容器=双相障碍;(我= 0, ”);x = x.replace(标题[我]、cur);} else {cur =标题[i];}权值= cur.substr(2,1);如果(我 oldweight) {+ = '
        ”;}+ =”
      • ' +一个;如果(nextweight
      ”;container = document.getElementById('toc') || bd;container.appendChild (toc);}) ();

    你可以参见这里的正则表达式解决方案。问题在于阅读innerHTML然后写出来可能很昂贵(这需要测试),如果你有事件处理附加到元素,它可能会泄漏内存,我的同事马特琼斯指出(再次,这就需要测试)。Ara Pehlivavian还提到两种方法的组合可能更好—匹配标题,但不回写innerHTML—而使用DOM添加id。

    图书馆的救援- aYUI3例子

    和另一个同事聊天Dav玻璃——关于TOC问题是他指出了YUI3选择器引擎愉快地获取元素列表并以正确的顺序返回它们。这让事情变得很简单:

    <脚本类型=“text / javascript”src=“http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js”>
                  脚本>
    <脚本>YUI({结合: 真正的,超时: 10000})使用(“节点”, 函数(Y) {
      var节点=Y。所有(“h1, h2, h3, h4, h5,仅有的);
      var= '
                   
      ' ; var重量 = 0 ,nextweight = 0 ,oldweight ;节点。 每一个 ( 函数 (o ,k ) { varid =o。 得到 ( “id” ) ; 如果 (id = = = ) {id = “头” +k ;o。 ( “id” ,id ) ; } ;重量 =o。 得到 ( 的节点名 )字符串的子串 ( 1 , 1 ) ; 如果 (重量 >oldweight ) {+ = ' ' ; } 如果 (重量 = =nextweight ) {+ = '' ; } }oldweight =重量 ; } ) ;+ = '
    '
    ;Y。一个(“# toc”)(“innerHTML”,); }); 脚本>

    可能有一种更干净的方法来组装TOC列表。

    性能考虑

    生活不仅仅是提高速度。——甘地

    上面的一些代码可能非常慢。也就是说,讲到性能和JavaScript时,重要的是要考虑实现的上下文:内容表脚本通常用于大量文本,但简单,文档。在gmail或Yahoo主页上测试和判断这些运行它们的脚本是没有意义的。也就是说,更快和更少的内存消耗总是更好的,但是我总是对那些考虑边缘情况而不是解决方案应该应用于的情况的性能测试持怀疑态度。

    服务器端移动。

    我越来越怀疑的另一件事是客户端解决方案对于服务器上也有意义的事情。因此,我认为可以使用上面的正则表达式方法并将其移到服务器端。

    第一个版本是aPHP脚本可以循环anHTML文档通过。你可以see the outcome of tocit.php here:

    
                  
    美元的文件 = $ _GET[“文件”];
    如果(preg_match(' / ^ [a-z0-9 \ _ \] + $ /我',美元的文件)){
    美元的内容 = 函数(美元的文件);
    preg_match_all(“/
                   
                    )* >。* < \ / h。> /我们”
                   ,美元的内容,美元的头条新闻);
    美元了 = '
                   
      ' ; foreach ( 美元的头条新闻 [ 0 ] 作为 $ k = > h美元 ) { 如果 ( strstr ( h美元 , “id” ) = = = ) { $ x = preg_replace ( ' / > / ' , “id =“头” $ k “>” , h美元 , 1 ) ; 美元的内容 = str_replace ( h美元 , $ x , 美元的内容 ) ; h美元 = $ x ; } ; 美元的链接 = preg_replace ( ' / <(\ /)? h \ d / ' , < 1美元的 , h美元 ) ; 美元的链接 = str_replace ( id = "的 , “href = " #” , 美元的链接 ) ; 如果 ( $ k > 0 & & 美元的头条新闻 [ 1 ] [ $ k - - - - - - 1 ] < 美元的头条新闻 [ 1 ] [ $ k ] ) { 美元了 .= '
        ' ; } 美元了 .= '
      • '美元的链接; 如果(美元的头条新闻[1][$ k+1] & & 美元的头条新闻[1][$ k+1]<美元的头条新闻[1][$ k]){ 美元了.='
      '
      ; } 如果 ( 美元的头条新闻 [ 1 ] [ $ k + 1 ] & & 美元的头条新闻 [ 1 ] [ $ k + 1 ] = = 美元的头条新闻 [ 1 ] [ $ k ] ) { 美元了 .= '' ; } } 美元了 .= '
    '
    ; 回声 str_replace('
    '
    ,美元了,美元的内容); }其他的{ ('only files like text.html please!'); } ? >
      ”;foreach(标题[0]美元美元$ k = > h){如果(strstr(h,美元“id”)= = = false){ $ x = preg_replace(' / > / ',' id = "头,$ k。”>“,h,美元1);$内容= str_replace(h,x美元,美元的内容);h = x美元;};$链接= preg_replace(' / <(\ /)? h \ d /,< 1美元,美元h);美元的链接= str_replace (id =””、“href = " #”,美元的链接);如果($ k > 0 & & $标题[1][$ k - 1]<标题[1]美元($ k)){ $ = '。
        ”;} $out .= '
      • ”。美元的链接。”;如果(标题美元[1][$ k + 1] & & $标题[1][$ k + 1] <标题[1]美元($ k)) {$ = '。
      ”;}如果(标题美元[1][$ k + 1]& & $标题[1][$ k + 1]= = $标题[1][$ k]){ $ = '。”;}}$。= '
    ”,回声(大小写不敏感
    ',$out,$content);}else{ die('only files like text.html please!');}?>

    这是很好的,但不是有另一个文件要循环,我们也可以的输出缓冲区PHP:

    
                  
    函数tocit(美元的内容){
      preg_match_all(“/
                   
                    )* >。* < \ / h。> /我们”
                   ,美元的内容,美元的头条新闻);
      美元了 = '
                   
      ' ; foreach ( 美元的头条新闻 [ 0 ] 作为 $ k = > h美元 ) { 如果 ( strstr ( h美元 , “id” ) = = = ) { $ x = preg_replace ( ' / > / ' , “id =“头” $ k “>” , h美元 , 1 ) ; 美元的内容 = str_replace ( h美元 , $ x , 美元的内容 ) ; h美元 = $ x ; } ; 美元的链接 = preg_replace ( ' / <(\ /)? h \ d / ' , < 1美元的 , h美元 ) ; 美元的链接 = str_replace ( id = "的 , “href = " #” , 美元的链接 ) ; 如果 ( $ k > 0 & & 美元的头条新闻 [ 1 ] [ $ k - - - - - - 1 ] < 美元的头条新闻 [ 1 ] [ $ k ] ) { 美元了 .= '
        ' ; } 美元了 .= '
      • '美元的链接; 如果(美元的头条新闻[1][$ k+1] & & 美元的头条新闻[1][$ k+1]<美元的头条新闻[1][$ k]){ 美元了.='
      '
      ; } 如果 ( 美元的头条新闻 [ 1 ] [ $ k + 1 ] & & 美元的头条新闻 [ 1 ] [ $ k + 1 ] = = 美元的头条新闻 [ 1 ] [ $ k ] ) { 美元了 .= '' ; } } 美元了 .= '
    '
    ; 返回 str_replace('
    '
    ,美元了,美元的内容); } ob_start(“tocit”); ? >[…文档…] ob_end_flush();? >
      ”;foreach(标题[0]美元美元$ k = > h){如果(strstr(h,美元“id”)= = = false){ $ x = preg_replace(' / > / ',' id = "头,$ k。”>“,h,美元1);$内容= str_replace(h,x美元,美元的内容);h = x美元;};$链接= preg_replace(' / <(\ /)? h \ d /,< 1美元,美元h);美元的链接= str_replace (id =””、“href = " #”,美元的链接);如果($ k > 0 & & $标题[1][$ k - 1] <标题[1]美元($ k)) {$ = '。
        ”;} $out .= '
      • ”。美元的链接。”;如果(标题美元[1][$ k + 1] & & $标题[1][$ k + 1] <标题[1]美元($ k)) {$ = '。
      ”;}如果(标题美元[1][$ k + 1] & & $标题[1][$ k + 1] = = $标题[1][$ k]) {$ = '。”;} } $。= '
    ”;返回(“大小写不敏感
    ”,$,$内容);} ob_start(“tocit”);? >[…文档…]

    服务器端解决方案有几个好处:如果需要,还可以缓存结果一段时间。我相信PHP可以加速,虽然。

    查看所有解决方案并获取源代码

    我给你们看了我的,现在给我看看你的!

    所有这些解决方案都是相当粗略和现成的。你认为如何改进它们?为不同的库做一个版本如何?去吧,把这个项目放到GitHub上,让我看看你能做什么。