跳到主要 | 跳到侧边栏

2010年10月13日,星期三

SP2010 AJAX-第1部分:将jQuery精简为基本要素

这是该系列的第一篇文章,着眼于在SharePoint 2010上构建AJAX样式的应用程序。正如您在上一篇文章中可能已经读到的那样,我最近在英国进行了演讲’的第一个关于该主题的SharePoint Saturday活动,本系列详细介绍了我在该主题中所讲的内容。

系列内容(注意‘technique’ and ‘tip’ article types):

  1. 将jQuery精简为要点(技术) - 本文
  2. 使用JavaScript Client OM处理列表 (技术)
  3. 结合使用jQuery AJAX和HTTP处理程序 (技术)
  4. 从HTTP处理程序返回JSON (技术)
  5. 为客户端OM和jQuery启用Intellisense (小费)
  6. 调试jQuery / JavaScript (小费)
  7. 构建AJAX应用程序时的有用工具 (小费)
  8. 将现有应用程序迁移到jQuery / AJAX

如果开发人员希望构建AJAX风格的应用程序,则他/她需要能够在不刷新页面的情况下更改页面上的内容。经过最初的学习后,开发人员开始喜欢上.Net,但是那太简单了 button_OnClick() 事件是有代价的–每次需要更新页面时回发一次。一时间还好–开发人员和最终用户实际上都对Web应用程序的用户体验抱有低期望。但是现在情况有所不同–回发是不好的,并且在开发方面,SharePoint开发人员可以说落后于曲线(与ASP.Net开发人员相比)“modern-day”应用程序。可能最流行的用于动态更新页面内容的工具是jQuery。那里’毫无疑问,jQuery是一个大话题。我不’不能将自己归类为专家,但是我的假设是jQuery可以归结为少数几种方法,这些方法可以为您提供巨大的功能–这篇文章涵盖了这些内容,并为构建AJAX风格的应用程序提供了基础。

jQuery的核心动作


类型

笔记

选择器

$(‘#someId’)

通过HTML ID选择一个元素,例如<button ID=”someId” />

选择器

$(‘.someClass’)

通过HTML / CSS类选择一个元素,例如<button class=”someClass” />

事件

$(document).ready()
-jQuery也为此提供了一个快捷方式:$()

将应在页面加载时运行的代码放在此处

事件

.click()

放置应在单击元素时运行的代码(例如$(‘#myButton’).click())

事件

。更改()

放置在元素更改时应运行的代码(例如$(‘#myDropdown’).change())

方法

.html()

设置元素的HTML–元素可以是单个跨度或巨大的主要内容div,因此功能非常强大。

方法

。显示隐藏()

显示或隐藏元素。

我确实认为这些工具可以为您提供jQuery所需的大部分功能,至少可以进行页面操作(但不能提供AJAX)–稍后再说)。当然啦’总是需要做其他事情,一旦您了解了如何使用基础知识,“the next tier”向下的jQuery操作可能是这样的(N.B.这里没有注释,但是您可以猜测每个语句的作用):

类型

选择器

$(‘.someClass’)[0]
$(‘.someClass’).parent()
$(‘.someClass:visible’)

事件

$(document).ready()
.onmouseover()
.onkeyup()

方法

。淡入淡出()
。附加()
。包()
.addClass()

我建议超越这些初始水平 jQuery在行动 作为用来深入了解jQuery的书。

例子

为了说明‘core’jQuery工具,这些是我在“jQuery用于页面操作”我的谈话部分。对于每个示例,我’快速概述,显示屏幕截图并显示HTML / jQuery代码。当然,平面截图不会’t really convey what’发生在页面上,但是 请记住,这里没有回发。

  1. 显示/隐藏元素

    在处理页面时,我们可能要做的最基本的事情就是显示和隐藏内容(当然,不回发)。在此示例中,单击按钮将显示微调器图像–这通常是将jQuery与AJAX方法结合使用时发生的事情的一部分。请注意,在页面加载(document.ready)时,jQuery立即隐藏了图像–一种替代方法是添加一个 样式=”display:none”<img> 元素:

    jQuery_Demo1_Off
    <fieldset id="fldDemo1">
        <legend>Demo 1 - showing/hiding</legend>
        <div class="demoRow">
                <button id="btnDemo1" type="button">Show/hide image</button>
                <img src="../images/COB.SPSaturday.Demos/ajax-loader.gif" id="spinnerImg" />
        </div>
    </fieldset>
    <script type="text/javascript">
        $(function () {
            $('#spinnerImg').hide();
        });
     
        $('#btnDemo1').click(function () {
            if ($('#spinnerImg').is(':visible')) {
                $('#spinnerImg').hide();
            }
            else {
                $('#spinnerImg').show();
            }
        });
    </script>

  2. 设置元素的HTML

    在页面上设置元素的HTML内容同等重要,就像获得对该元素的引用并将HTML字符串传递给 .html() 方法。尽管我的示例很简单,但是HTML包含应用了CSS的图像和元素–希望表明HTML可以是页面上的小DIV到包含大部分页面内容的巨大面板之间的任何内容:



    <fieldset id="fldDemo2"> 
        <legend>Demo 2 - setting HTML</legend> 
        <div class="demoRow"> 
            <button id="btnDemo2" type="button">Set HTML</button> 
            <span id="demo2Span"></span> 
        </div> 
    </fieldset> 
    <script type="text/javascript"> 
        $('#btnDemo2').click(function () { 
            $('#demo2Span').html('The <i>quick</i> <span id=\'brown\'>brown</span> <img src=\'/_layouts/images/COB.SPSaturday.Demos/fox.jpg\' /> jumped over the lazy <img src=\'/_layouts/images/COB.SPSaturday.Demos/dog.jpg\' />'); 
        }); 
    </script>

  3. 级联下拉菜单

    尽管人们有时会做出很多级联的下拉菜单(似乎在那里’每周都会发表有关该主题的新文章),jQuery大大简化了事情–关键是回应 。更改() 父级下拉列表的事件。因为我们’尚未涵盖AJAX,这里的示例使用下拉列表项,这些下拉列表项在JavaScript中进行了硬编码,而不是从查询中提取到服务器。还要注意,此代码使用jQuery填充父下拉列表中的项目,甚至–如果只有2nd 下拉菜单动态加载项目。


    <fieldset id="fldDemo2">
        <legend>Demo 3 - cascading dropdowns</legend>
        <div class="demoRow">
            <div><span class="demoLabel">Car manufacturer:</span><select id="carManufacturer"></select></div>
            <div><span class="demoLabel">Car model:</span><select id="carModel"></select></div>
        </div>
    </fieldset>
    <script type="text/javascript">
        $(function () {
            var output = [];
     
            var manufacturers = ['Select..', 'Ford', 'Vauxhall', 'Honda'];
            $.each(manufacturers, function (index, value) {
                output.push('<option value="' + value + '">' + value + '</option>');
            });
     
            $('select#carManufacturer').html(output.join(''));

        });
     
        $('select#carManufacturer').change(function () {
            var fordModels = ['Fiesta', 'Focus', 'Mondeo', 'Galaxy'];
            var vauxhallModels = ['Corsa', 'Astra', 'Insignia'];
            var hondaModels = ['Jazz', 'Pilot', 'Civic', 'Accord'];
     
            var selectedArray;
            if ($('select#carManufacturer').val() == 'Ford') {
                selectedArray = fordModels;
            }
            if ($('select#carManufacturer').val() == 'Vauxhall') {
                selectedArray = vauxhallModels;
            }
            if ($('select#carManufacturer').val() == 'Honda') {
                selectedArray = hondaModels;
            }
     
            var models = [];
            $.each(selectedArray, function (index, value) {
                models.push('<option value="' + value + '">' + value + '</option>');
            });
     
            $('select#carModel').html(models.join(''));
     
        });
    </script>
  4. 调光面板

    .addClass() 方法在不重新加载页面的情况下更改元素样式很有用。当然,应用不同的CSS样式可能会导致页面发生重大变化。为了说明这一点,我选择了显示对话框的想法,‘dimming’ the background –一种非常流行的UI技术,当然,SharePoint 2010也使用过’自己的对话框框架。如果已经定义了CSS类,则可以简单地使用 .addClass()/。removeClass() 代码需要做的主要事情是: 
     


    <!-- DIV for grey background, CSS makes larger than whole page -->
    <div id="dimmer"></div>  
    <!-- DIV for progress panel, CSS layers above page -->
    <div id="progressPanel">
        <a class="close" href="#" >
           <img id="close" src="/_layouts/images/COB.SPSaturday.Demos/close.jpg" />
        </a> 
        This is an important message!   
    </div>  
     
    <fieldset id="fldDemo4">
        <legend>Demo 4 - dimmed panel</legend>
        <div class="demoRow">
            <button id="btnDemo4" type="button">Dimmed panel</button>
       </div>
    </fieldset>
    <script type="text/javascript">
        $(function () {
            $('a.close').click(function () {
                $('div#progressPanel').fadeOut();
                $('div#dimmer').fadeOut().removeClass('dimmed');
            });
        });
     
        $('#btnDemo4').click(function () {
            $('div#progressPanel').fadeIn();
            $('div#dimmer').addClass('dimmed').fadeIn();
        });
    </script>
     
    这里’关联的CSS:
    div#progressPanel
    {
        position:absolute; 
        width:200px; 
        height:150px; 
        z-index:20; 
        border:2px solid #222; 
        background: #FFF; 
        top: 50%; 
        left: 50%; 
        margin-top: -150px; 
        margin-left: -200px; 
        opacity: 1.0;
        -moz-opacity: 0.00;
        filter: alpha(opacity=0);
        display:none;
        padding:10px;   
        font-size:1.5em;
        font-weight:bold;
    }
     
    .dimmed
    {
        height: 100%;
        width: 100%;
        position:fixed;
        top: 0px;
        left: 0px;
        background-color: rgb(0, 0, 0);
        background-repeat:repeat;
        -moz-opacity: 0.70;
        opacity: 0.7;
        filter: alpha(opacity=70);
        z-index: 10;
    }
     
    .close 
    {
        top:0px; 
        float:right; 
    }
     
    .msgbox 
    {
        position:absolute; 
        width:300px; 
        height:200px; 
        z-index:200; 
        border:5px solid #222; 
        top: 50%; 
        left: 50%; 
        margin-top: -100px; 
        margin-left: -150px; 
    }   
     
    img#close 
    {
        border:none; 
        margin:5px;
    }

  5. 通过AJAX提取HTML

    尽管这篇文章试图纯粹专注于在客户端上操作页面,但是这里’一个简单的示例,它确实与服务器对话(以激发您的AJAX胃口)。这里我们使用的是jQuery之一’■AJAX方法,用于获取页面内容并将其放入当前页面的DIV中。这对于大多数页面都可以正常工作,但是我遇到了与SharePoint管理页面有关的问题’t深入(请参见代码中的注释)–希望它证明了做这样的事情有多么容易,并且认为我可以轻松地解析结果并用它做一些更有用的事情。


     

    <fieldset id="Fieldset1">
        <legend>Demo 5 - fetch HTML via AJAX</legend>
        <div class="demoRow">
            <button id="btnDemo5" type="button">Fetch HTML</button>
            <span id="demo5Span"></span>
       </div>
    </fieldset>
    <script type="text/javascript">
        // Some smoke and mirrors here unfortunately, SP pages 
        //  have some weird JavaScript redirect which would need to be solved 
        //  for this 技术, so I'm using a (copied) flat HTML page..
        $('#btnDemo5').click(function () {
            $.get("/_layouts/COB.SPSaturday.Demos/settings_aspx.htm", function (data) {
                $('#demo5Span').html(data);
            });
        });
    </script>

这些代码示例(以及下一篇文章中的代码示例)可以从以下位置下载: http://db.tt/rUq5lm9

下次 - 使用JavaScript客户端OM + jQuery处理列表.

5条评论:

MOSSBUDDY said...

很棒的解释等待下一篇文章,很棒的克里斯!继续努力

匿名 said...

克里斯,我认为您的最后一个示例是错误的,因为您是通过在现有页面中重新插入完整的html页面来创建无效的标记。 jQuery load()函数在这里更合适。

至于JavaScript问题,我一直在做的是获取页面标记,但阻止脚本的评估。也许这对您有帮助...

克里斯·奥'Brien说过...

@克里斯托夫,

是的,我'd同意这一点-由于我们'd有2个头部/身体标记等。'd需要仅获取部分页面内容或对完整HTML进行一些后处理。但是,该示例有望说明使用jQuery这种技术非常容易。

什么'阻止脚本的技巧是什么?那'如果返回的HTML中包含脚本标签,则正是需要的。

非常感谢您的反馈:)

克里斯。

匿名 said...

什么 I do is overwrite the jQuery globalEval function responsible for evaluating the scripts.
我从未与jQuery专家讨论过这一点,但到目前为止,它对我还是有用的。例如,我在SharePoint for Ajax工具提示中使用了此技术。

保罗·亨特说过...

模式对话框上有趣的行为问题。如果我单击一次,它可以很好地工作并且具有40%的不透明度。

关闭对话框,然后再次执行而不重新加载页面,这次的不透明度为100%。

不知道这是否是IE8问题。