ตัวเลือกการนำทางสำหรับ SharePoint Online

สิ่งสำคัญ:  บทความนี้เป็นการแปลด้วยเครื่อง โปรดดู ข้อจำกัดความรับผิดชอบ โปรดดูบทความฉบับภาษาอังกฤษ ที่นี่ เพื่อใช้อ้างอิง

บทความนี้อธิบายถึงวิธีการปรับปรุงเวลาในการโหลดหน้าสำหรับ SharePoint Online โดยใช้โครงสร้างการนำทางและการนำทางจากการค้นหา

นำทางส่วนกลางและแบบสอบถามที่จำเป็นสำหรับการสร้างการนำทางแบบโครงสร้างสามารถทำให้หน้าของคุณโหลดเพิ่มเติมได้ช้าลงใน SharePoint Online นี่คือเนื่องจากแต่ละคิวรีเหล่านี้ส่งคำขออื่นไปยัง SQL server สำหรับแต่ละไซต์และไซต์ย่อยที่คุณมี เพิ่มเติมการร้องขอไปยัง SQL server ปัญหานี้จะมีผลต่อหน้าต้นแบบ ซึ่งหมายความ ว่า การนำทางส่วนกลางจะยังได้รับผลกระทบ

ไซต์ SharePoint บางอย่างจำเป็นต้องมีโครงสร้างที่ซับซ้อน และมีขนาดใหญ่ ใช้ตัวออกแบบในแบบที่พร้อมใช้โครงสร้างการนำทาง ซึ่งใช้เนื้อหา โดยคิวรี อาจก่อให้เกิดครั้งโหลดหน้าช้าได้เนื่องจากหลายชั้นของไซต์ แต่ละรายการของชั้นของไซต์ย่อยสร้างแบบสอบถามอื่นนอกจากนี้

มีสองตัวเลือกการนำทางการออกแบบในแบบที่พร้อมใช้หลักใน SharePoint เช่นเดียวกับที่สาม วิธีแบบกำหนดเอง จากการค้นหา แต่ละตัวเลือกมีข้อดีและข้อเสียตามที่ระบุไว้ในตารางต่อไปนี้

โครงสร้างการนำทาง

นำทางที่มีการจัดการ

นำทางจากการค้นหา

ผู้เชี่ยวชาญด้าน:

  • ง่ายต่อการกำหนดค่า

  • ตัดแต่งความปลอดภัย

  • ปรับปรุงโดยอัตโนมัติเมื่อมีเพิ่มไซต์

ผู้เชี่ยวชาญด้าน:

  • ง่ายต่อการบำรุงรักษา

ผู้เชี่ยวชาญด้าน:

  • ตัดแต่งความปลอดภัย

  • ปรับปรุงโดยอัตโนมัติเมื่อมีเพิ่มไซต์

  • การโหลดโครงสร้างการนำทางภายในเครื่องที่แคชไว้ และเวลาอย่างรวดเร็ว

ข้อเสีย:

  • สามารถดำเนินการดีกับโครงสร้างของไซต์ที่ซับซ้อน

ข้อเสีย:

  • ปรับปรุงโดยอัตโนมัติเพื่อแสดงโครงสร้างของไซต์

ข้อเสีย:

  • ไม่มีความสามารถในการสั่งไซต์ได้อย่างง่ายดาย

  • จำเป็นต้องใช้การกำหนดเองของหน้าต้นแบบ (ทักษะทางเทคนิคที่จำเป็น)

ถ้าคุณมีไซต์ที่ มีไซต์ย่อยมากมาย และ คุณกำลังใช้โครงสร้างการนำทาง ก็อาจทำให้ช้า เพจของคุณโหลดลงอย่างมาก ตัวเลือกที่เหมาะสมที่สุดสำหรับไซต์ของคุณจะขึ้นอยู่ กับความต้องการของไซต์ของคุณ และ บนความสามารถด้านเทคนิคของคุณ ถ้าคุณพึงพอใจโดยใช้หน้าต้นแบบกำหนดเอง และมีความสามารถบางอย่างในองค์กรเพื่อบันทึกการเปลี่ยนแปลงที่อาจเกิดขึ้นในหน้าต้นแบบเริ่มต้นสำหรับ SharePoint Online แล้วเลือกจากการค้นหาจะทำให้ประสบการณ์ของผู้ใช้ดีที่สุด ถ้าคุณต้องการบกกลางอย่างง่ายระหว่างค้นหาและการนำทางโครงสร้างของออกแบบในแบบที่พร้อมใช้ แล้วนำทางที่มีการจัดการเป็นตัวเลือกที่ดีมาก ตัวเลือกการนำทางที่มีการจัดการสามารถเก็บไว้ผ่าน การกำหนดค่าไม่เกี่ยวข้องกับไฟล์การกำหนดเองโค้ด และเป็นอย่างมากเร็วกว่าการออกแบบในแบบที่พร้อมใช้โครงสร้างการนำทางได้

วิธีอื่นเพื่อ จัดโครงสร้างไซต์ที่มีอยู่ และลดจำนวนรายการนำทางและไซต์ย่อยที่จำเป็นต้องมีอยู่ นี่คือเนื่องจากโครงสร้างการนำทางด้วยตราบโครงสร้างของไซต์และการนำทางไม่ซับซ้อนมากเกินไป

บทความนี้เปรียบเทียบวิธีต่าง ๆ ในตัวอย่างการให้ไซต์คอลเลกชัน ตัวอย่างไซต์คอลเลกชันมีไซต์ย่อย 11 และแต่ละไซต์ย่อยมีไซต์ย่อยเพิ่มเติมที่สี่อย่างน้อย

สกรีนช็อตแสดงไซต์และไซต์ย่อย

ใช้โครงสร้างการนำทางใน SharePoint Online

นี่คือการ นำทางออกแบบตัวแบบที่พร้อมใช้งานตามค่าเริ่มต้น และเป็นโซลูชันที่เหมาะสม และซับซ้อนมากที่สุดในกรณีส่วนใหญ่ เว้นแต่มีโครงสร้างซับซ้อนของหลายไซต์หรือไซต์ย่อยหลายระดับ โครงสร้างการนำทางทำงาน ประโยชน์หลักของวิธีนี้คือ ว่า จะถูกตัดแต่งความปลอดภัย ปรับปรุงโดยอัตโนมัติเมื่อมีเพิ่มไซต์ใหม่ และไม่จำเป็นต้องมีการกำหนดเองใด ๆ ของหน้าต้นแบบ ผู้ใช้เทคนิคสามารถเพิ่มเติมได้อย่างง่ายดายเพิ่มรายการ ซ่อนรายการ และจัดการการนำทางจากหน้าการตั้งค่า

การเปิดใช้งานโครงสร้างการนำทางใน SharePoint Online

เมื่อต้องการแสดงตัวอย่างวิธีประสิทธิภาพการทำงานใน SharePoint Online โซลูชันมาตรฐานกับโครงสร้างการนำทางและแสดง subsites ตัวเลือกเปิดใช้งาน ต่อไปนี้คือหน้าจอภาพจากตั้งค่าการตรวจพบบนหน้าการตั้งค่าไซต์ >การนำทาง

สกรีนช็อตแสดงไซต์ย่อย

การวิเคราะห์ประสิทธิภาพโครงสร้างการนำทางใน SharePoint Online

เมื่อต้องการวิเคราะห์ ประสิทธิภาพการทำงานของหน้า SharePoint ให้ใช้แท็บเครือข่าย ของเครื่องมือของนักพัฒนา F12 ใน Internet Explorer

สกรีนช็อตแสดงเครื่องมือสำหรับนักพัฒนา F12 จากแท็บ เครือข่าย

บนแท็บเครือข่าย คลิกบนหน้า.aspx ที่ถูกโหลด จากนั้น คลิกที่แท็บรายละเอียด

สกรีนช็อตแสดงแท็บรายละเอียด

คลิก ส่วนหัวของการตอบรับ

สกรีนช็อตของแท็บ รายละเอียด

SharePoint ส่งกลับข้อมูลการวินิจฉัยมีประโยชน์บางอย่างในส่วนหัวของคำตอบ หนึ่งประโยชน์มากที่สุดคือSPRequestDuration   ซึ่งเป็นค่า มิลลิวินาที ของระยะการเรียกใช้กระบวนการบนเซิร์ฟเวอร์

ในต่อไปนี้จอแสดงไซต์ย่อย ถูกเลือกสำหรับการนำทางแบบโครง ซึ่งหมายความ ว่า มีเฉพาะไซต์คอลเลกชันการเชื่อมโยงในการนำทางส่วนกลาง:

สกรีนช็อตแสดงระยะเวลาในการโหลดเป็นระยะเวลาที่ร้องขอ

คีย์รีจิSPRequestDuration   มีค่าเป็นมิลลิวินาที 245 นี้หมายถึงเวลาใช้เพื่อส่งกลับคำขอนั้น เนื่องจากมีเพียงหนึ่งรายการนำทางบนไซต์ นี้เป็นเกณฑ์มาตรฐานดีสำหรับวิธี SharePoint Online ดำเนินการโดยไม่ต้องการนำทางจำนวนมาก ภาพหน้าจอถัดไปแสดงวิธีการเพิ่มไซต์ย่อยที่มีผลต่อคีย์นี้

สกรีนช็อตแสดงระยะเวลาการร้องขอของ 2502

การเพิ่มไซต์ย่อยที่มีมากเพิ่มเวลาใช้เพื่อส่งกลับการร้องขอของหน้า

ประโยชน์ของการใช้การนำทางที่มีแบบแผนทั่วไปคือ คุณสามารถได้อย่างง่ายดายลำดับการจัดระเบียบ ซ่อนไซต์ เพิ่มหน้า ผลลัพธ์จะตัดแต่งความปลอดภัย และคุณกำลัง deviating จากหน้าต้นแบบได้รับการสนับสนุนที่ใช้ใน SharePoint Online ถ้าคุณจัดโครงสร้างของไซต์ของคุณอย่างระมัดระวัง และลดขนาดของไซต์ย่อยในไซต์คอลเลกชันของคุณ แล้วโครงสร้างการนำทางทำงาน

ใช้ metadata ที่มีการจัดการและการนำทางที่มีการจัดการใน SharePoint Online

นำทางที่มีการจัดการถูกออกแบบในแบบที่พร้อมใช้ตัวเลือกอื่นที่คุณสามารถใช้เพื่อสร้างการเรียงลำดับเดียวกันของฟังก์ชันกับโครงสร้างการนำทาง

ข้อได้เปรียบของการใช้ metadata ที่มีการจัดการคือ จะเร็วเพื่อเรียกข้อมูลกว่าโดยใช้เนื้อหาโดยคิวรีเพื่อสร้างการนำทางของไซต์ แม้ว่าคุณจะได้เร็วมากไม่มีวิธีในการตัดแต่งความปลอดภัยผลลัพธ์ ดังนั้นถ้าผู้ใช้ไม่สามารถเข้าถึงไซต์ที่ระบุ ลิงก์จะยังคงแสดง แต่จะนำไปสู่ข้อผิดพลาด

วิธีการดำเนินการนำทางที่มีการจัดการและผลลัพธ์   

มีหลายบทบน TechNet เกี่ยวกับรายละเอียดของการนำทางที่มีการจัดการ ตัวอย่างเช่น ดูภาพรวมของการนำทางที่มีการจัดการใน SharePoint Server 2013

เมื่อต้องดำเนินการนำทางที่มีการจัดการ คุณจำเป็นต้องมีสิทธิ์ของผู้ดูแลที่เก็บคำ นำทางที่มีการจัดการสามารถใช้เพื่อแทนโครงสร้างการนำทาง ด้วยการตั้งค่าเงื่อนไขด้วย Url ที่ตรงกับโครงสร้างของไซต์คอลเลกชัน ตัวอย่าง:

ตัวอย่างสกรีนช็อตของไซต์ย่อย1

ตัวอย่างต่อไปนี้แสดงประสิทธิภาพการทำงานของการนำทางที่ซับซ้อนที่ใช้การนำทางที่มีการจัดการ

ตัวอย่างสกรีนช็อตของ SPRequestDuration

ใช้การนำทางที่มีการจัดการอย่างสอดคล้องกันช่วยปรับปรุงประสิทธิภาพการเปรียบเทียบกับเนื้อหา ด้วยวิธีการนำทางในโครงสร้างแบบสอบถาม

ใช้จากการค้นหาการเขียนสคริปต์ฝั่งไคลเอ็นต์

ใช้การค้นหาคุณสามารถใช้ประโยชน์จากดัชนีหมายเลขที่ถูกสร้างขึ้นโดยใช้การตระเวนแบบต่อเนื่องพื้นหลัง ออก นั่นหมายความว่า มีไม่มีคิวรีเนื้อหาจำนวนมาก ผลลัพธ์การค้นหาจะถูกดึงมาจากดัชนีการค้นหา และผลลัพธ์จะตัดแต่งความปลอดภัย นี่คือเร็วกว่าโดยใช้คิวรีเนื้อหาทั่วไป ใช้การค้นหาสำหรับการนำทางในโครงสร้าง โดยเฉพาะอย่างยิ่งถ้าคุณมีโครงสร้างซับซ้อนไซต์ จะเร่งความเร็วหน้าการโหลดเวลาอย่างมาก หลักข้อได้เปรียบของนี้เหนือนำทางที่มีการจัดการได้ว่า คุณได้รับประโยชน์จากการตัดแต่งความปลอดภัย

วิธีนี้เกี่ยวข้องกับการสร้างหน้าต้นแบบกำหนดเอง จากแทนรหัสการนำทางการออกแบบตัวอย่างที่พร้อม ด้วย HTML แบบกำหนดเอง ทำตามขั้นตอนนี้เมื่อต้องการแทนรหัสนำทางใน seattle.html ไฟล์

ในตัวอย่างนี้ คุณจะเปิดไฟล์ seattle.html และแทนองค์ประกอบทั้งid = "DeltaTopNavigation" มีโค้ด HTML กำหนดเอง

ตัวอย่าง: การแทนการนำทางการออกแบบในแบบที่พร้อมใช้โค้ดในหน้าต้นแบบ

  1. นำทางไปยังหน้าการตั้งค่าไซต์

  2. เปิดแกลเลอรีหน้าต้นแบบ โดยการคลิกหน้าต้นแบบ

  3. จากที่นี่ คุณสามารถนำทางไลบรารี และดาวน์โหลดไฟล์seattle.master

  4. แก้ไขโค้ดโดยใช้ตัวแก้ไขข้อความ และลบโค้ดบล็อกในภาพจากหน้าจอต่อไปนี้

    สกรีนช็อตของโค้ด DeltaTopNavigation เพื่อลบ
  5. เอารหัสระหว่าง < SharePoint:AjaxDelta id = "DeltaTopNavigation" > และ < \SharePoint:AjaxDelta > แท็ก และแทนที่ ด้วยส่วนย่อยของต่อไปนี้:

    <div id="loading">
      <!--Replace with path to loading image.-->
      <div style="background-image: url(''); height: 22px; width: 22px; ">
      </div>
    </div>
    <!-- Main Content-->
    <div id="navContainer" style="display:none">
        <div data-bind="foreach: hierarchy" class="noindex ms-core-listMenu-horizontalBox">
            <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                <span class="menu-item-text" data-bind="text: item.Title">
                </span>
            </a>
            <ul id="menu" data-bind="foreach: $data.children" style="padding-left:20px">
                <li class="static dynamic-children">
                    <a class="static dynamic-children menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                        <span aria-haspopup="true" class="additional-background ms-navedit-flyoutArrow dynamic-children">
                            <span class="menu-item-text" data-bind="text: item.Title">
                            </span>
                        </span>
                    </a>
                    <ul id="menu" data-bind="foreach: children; visible: children.length>0" class="dynamic" >
                        <li class="dynamic">
                            <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                                <span class="menu-item-text" data-bind="text: item.Title">
                                </span>
                            </a>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
  6. แทน URL ในการโหลดรูปแท็กจุดยึดที่จุดเริ่มต้น มีลิงก์ไปยังรูปการโหลดในไซต์คอลเลกชันของคุณ หลังจากที่คุณทำการเปลี่ยนแปลง เปลี่ยนชื่อแฟ้ม นั้นแล้ว อัปโหลดไปยังแกลเลอรีหน้าต้นแบบ ซึ่งสร้างไฟล์.master ใหม่

  7. HTML นี้มีมาร์กอัปพื้นฐานที่จะถูกสร้างขึ้น โดยผลลัพธ์การค้นหาที่ส่งกลับจากโค้ด JavaScript คุณจะต้องการแก้ไขโค้ดต่อไปนี้เพื่อเปลี่ยนค่าสำหรับvar root = “site collection URLตามที่แสดงในส่วนย่อยของต่อไปนี้:

    var root = “https://spperformance.sharepoint.com/sites/NavigationBySearch”;

    ไฟล์ JavaScript ทั้งหมดจะเป็นดังนี้:

    //Models and Namespaces
    var SPOCustom = SPOCustom || {};
    SPOCustom.Models = SPOCustom.Models || {}
    SPOCustom.Models.NavigationNode = function () {
    
        this.Url = ko.observable("");
        this.Title = ko.observable("");
        this.Parent = ko.observable("");
    
    };
    
    var root = "https://spperformance.sharepoint.com/sites/NavigationBySearch";
    var baseUrl = root + "/_api/search/query?querytext=";
    var query = baseUrl + "'contentClass=\"STS_Web\"+path:" + root + "'&trimduplicates=false&rowlimit=300";
    
    var baseRequest = {
        url: "",
        type: ""
    };
    
    
    //Parses a local object from JSON search result.
    function getNavigationFromDto(dto) {
        var item = new SPOCustom.Models.NavigationNode();
        if (dto != undefined) {
    
            var webTemplate = getSearchResultsValue(dto.Cells.results, 'WebTemplate');
    
            if (webTemplate != "APP") {
                item.Title(getSearchResultsValue(dto.Cells.results, 'Title')); //Key = Title
                item.Url(getSearchResultsValue(dto.Cells.results, 'Path')); //Key = Path
                item.Parent(getSearchResultsValue(dto.Cells.results, 'ParentLink')); //Key = ParentLink
            }
    
        }
        return item;
    }
    
    function getSearchResultsValue(results, key) {
    
        for (i = 0; i < results.length; i++) {
            if (results[i].Key == key) {
                return results[i].Value;
            }
        }
        return null;
    }
    
    //Parse a local object from the serialized cache.
    function getNavigationFromCache(dto) {
        var item = new SPOCustom.Models.NavigationNode();
    
        if (dto != undefined) {
    
            item.Title(dto.Title);
            item.Url(dto.Url);
            item.Parent(dto.Parent);
        }
    
        return item;
    }
    
    /* create a new OData request for JSON response */
    function getRequest(endpoint) {
        var request = baseRequest;
        request.type = "GET";
        request.url = endpoint;
        request.headers = { ACCEPT: "application/json;odata=verbose" };
        return request;
    };
    
    /* Navigation Module*/
    function NavigationViewModel() {
        "use strict";
        var self = this;
        self.nodes = ko.observableArray([]);
        self.hierarchy = ko.observableArray([]);;
        self.loadNavigatioNodes = function () {
            //Check local storage for cached navigation datasource.
            var fromStorage = localStorage["nodesCache"];
            if (false) {
                var cachedNodes = JSON.parse(localStorage["nodesCache"]);
    
                if (cachedNodes && timeStamp) {
                    //Check for cache expiration. Currently set to 3 hrs.
                    var now = new Date();
                    var diff = now.getTime() - timeStamp;
                    if (Math.round(diff / (1000 * 60 * 60)) < 3) {
    
                        //return from cache.
                        var cacheResults = [];
                        $.each(cachedNodes, function (i, item) {
                            var nodeitem = getNavigationFromCache(item, true);
                            cacheResults.push(nodeitem);
                        });
    
                        self.buildHierarchy(cacheResults);
                        self.toggleView();
                        addEventsToElements();
                        return;
                    }
                }
            }
            //No cache hit, REST call required.
            self.queryRemoteInterface();
        };
    
        //Executes a REST call and builds the navigation hierarchy.
        self.queryRemoteInterface = function () {
            var oDataRequest = getRequest(query);
            $.ajax(oDataRequest).done(function (data) {
                var results = [];
                $.each(data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results, function (i, item) {
    
                    if (i == 0) {
                        //Add root element.
                        var rootItem = new SPOCustom.Models.NavigationNode();
                        rootItem.Title("Root");
                        rootItem.Url(root);
                        rootItem.Parent(null);
                        results.push(rootItem);
                    }
                    var navItem = getNavigationFromDto(item);
                    results.push(navItem);
                });
                //Add to local cache
                localStorage["nodesCache"] = ko.toJSON(results);
    
                localStorage["nodesCachedAt"] = new Date().getTime();
                self.nodes(results);
                if (self.nodes().length > 0) {
                    var unsortedArray = self.nodes();
                    var sortedArray = unsortedArray.sort(self.sortObjectsInArray);
    
                    self.buildHierarchy(sortedArray);
                    self.toggleView();
                    addEventsToElements();
                }
            }).fail(function () {
                //Handle error here!!
                $("#loading").hide();
                $("#error").show();
            });
        };
        self.toggleView = function () {
            var navContainer = document.getElementById("navContainer");
            ko.applyBindings(self, navContainer);
            $("#loading").hide();
            $("#navContainer").show();
    
        };
        //Uses linq.js to build the navigation tree.
        self.buildHierarchy = function (enumerable) {
            self.hierarchy(Enumerable.From(enumerable).ByHierarchy(function (d) {
                return d.Parent() == null;
            }, function (parent, child) {
                if (parent.Url() == null || child.Parent() == null)
                    return false;
                return parent.Url().toUpperCase() == child.Parent().toUpperCase();
            }).ToArray());
    
            self.sortChildren(self.hierarchy()[0]);
        };
    
    
        self.sortChildren = function (parent) {
    
            // sjip processing if no children
            if (!parent || !parent.children || parent.children.length === 0) {
                return;
            }
    
            parent.children = parent.children.sort(self.sortObjectsInArray2);
    
            for (var i = 0; i < parent.children.length; i++) {
                var elem = parent.children[i];
    
                if (elem.children && elem.children.length > 0) {
                    self.sortChildren(elem);
                }
            }
        };
    
        // ByHierarchy method breaks the sorting in chrome and firefix 
        // we need to resort  as ascending
        self.sortObjectsInArray2 = function (a, b) {
            if (a.item.Title() > b.item.Title())
                return 1;
            if (a.item.Title() < b.item.Title())
                return -1;
            return 0;
        };
    
    
        self.sortObjectsInArray = function (a, b) {
            if (a.Title() > b.Title())
                return -1;
            if (a.Title() < b.Title())
                return 1;
            return 0;
        }
    }
    
    //Loads the navigation on load and binds the event handlers for mouse interaction.
    function InitCustomNav() {
        var viewModel = new NavigationViewModel();
        viewModel.loadNavigatioNodes();
    }
    
    function addEventsToElements() {
        //events.
        $("li.dynamic-children").mouseover(function () {
            var position = $(this).position();
            $(this).find("ul").css({ width: 125, left: position.left + 10, top: 50 });
    
        })
            .mouseout(function () {
                $(this).find("ul").css({ width: 0, left: -99999, top: 0 });
            });
    }
    
    _spBodyOnLoadFunctionNames.push("InitCustomNav");
    

    เมื่อต้องการสรุปโค้ดที่แสดงข้างต้นในฟังก์ชัน$(document).ready jQuery มีวัตถุviewModelสร้างขึ้นแล้วloadNavigationNodes()ฟังก์ชันบนวัตถุที่เรียกว่า ฟังก์ชันนี้โหลดลำดับชั้นการนำทางที่สร้างไว้ก่อนหน้านี้ถูกเก็บไว้ในเก็บข้อมูลภายใน HTML5 ของเบราว์เซอร์ไคลเอ็นต์ หรือฟังก์ชันqueryRemoteInterface()โทรได้

    QueryRemoteInterface()สร้างการเรียกใช้ฟังก์ชันgetRequest()กับคิวรีพารามิเตอร์ที่กำหนดไว้ก่อนหน้านี้ในสคริปต์แล้ว ส่งกลับข้อมูลจากเซิร์ฟเวอร์ ข้อมูลนี้เป็นอย่างยิ่งอาร์เรย์ของไซต์ทั้งหมดในไซต์คอลเลกชันซึ่งแสดงเป็นวัตถุการถ่ายโอนข้อมูลที่มีคุณสมบัติต่าง ๆ ข้อมูลนี้ถูกแล้วแยกวิเคราะห์ลงในวัตถุกำหนดไว้ก่อนหน้านี้SPO.Models.NavigationNodeซึ่งใช้ Knockout.js เพื่อสร้างคุณสมบัติ observable สำหรับการใช้งาน ด้วยข้อมูลผูกค่าลงใน HTML ที่เราได้กำหนดไว้ก่อนหน้านี้ วัตถุโดยทั่วไปแล้ววางลงในอาร์เรย์ในผลลัพธ์ อาร์เรย์นี้จะแยกวิเคราะห์ JSON ใช้ Knockout ใน และเก็บไว้ในเก็บข้อมูลภายในเบราว์เซอร์สำหรับประสิทธิภาพดียิ่งขึ้นบนโหลดหน้าในอนาคต

  8. ถัดไป ผลลัพธ์ได้กำหนดให้กับอาร์เรย์self.nodesและลำดับชั้นมีอยู่ออกจากวัตถุโดยใช้การกำหนดผลลัพธ์ไปอาร์เรย์self.heirarchylinq.js อาร์เรย์นี้เป็นวัตถุที่ถูกผูกไว้กับ HTML จะทำสิ่งนี้ในฟังก์ชันtoggleView()ด้วยส่งผ่านวัตถุตนเองไปยังฟังก์ชันko.applyBinding() นี้แล้วทำให้เกิดลำดับชั้นของอาร์เรย์จะถูกผูกไว้กับ HTML ต่อไปนี้:

    <div data-bind=”foreach: hierarchy” class=”noindex ms-core-listMenu-horizontalBox”>

    สุดท้าย ตัวจัดการเหตุการณ์สำหรับmouseenterและmouseexitจะถูกเพิ่มไปที่ระดับบนสุดการนำทางเพื่อจัดการเมนูดรอปดาวน์ไซต์ย่อยที่ทำในฟังก์ชันaddEventsToElements()

    คุณสามารถดูผลลัพธ์ของการนำทางจอด้านล่าง:

    สกรีนช็อตของผลลัพธ์การนำทาง

    ในตัวอย่างของเรานำทางที่ซับซ้อนหน้าทันสมัย โหลดโดยไม่ต้องแสดงการแคชข้อมูลภายในเวลาใช้ในบนเซิร์ฟเวอร์มีถูกตัดลงมาจากการนำทางเกณฑ์มาตรฐานโครงสร้างเพื่อแสดงผลลัพธ์คล้ายกันเป็นวิธีการนำทางที่มีการจัดการ

    สกรีนช็อตของ SPRequestDuration 301

    ประโยชน์หลักหนึ่งของวิธีนี้คือ ให้ โดยใช้การเก็บข้อมูลภายใน HTML5 นำทางจะเก็บไว้ภายในเครื่องสำหรับผู้ใช้ในครั้งถัดไปที่พวกเขาโหลดหน้า

เราได้รับการปรับปรุงประสิทธิภาพการทำงานที่สำคัญจากการใช้การค้นหา API สำหรับการนำทางโครงสร้าง อย่างไรก็ตาม จะใช้ความสามารถทางเทคนิคบางอย่างเพื่อดำเนินการ และฟังก์ชันการทำงานนี้ที่กำหนดเอง ในการดำเนินการตัวอย่าง ไซต์ไม่ได้เรียงลำดับในลักษณะเดียวกับการออกแบบในแบบที่พร้อมใช้โครงสร้างการนำทาง ตามลำดับตัวอักษร ถ้าคุณต้องการแตกต่างจากลำดับนี้ จะเป็นการพัฒนา และรักษาซับซ้อนยิ่งขึ้น นอกจากนี้ยัง วิธีนี้คุณจะต้องแตกต่างจากหน้าต้นแบบได้รับการสนับสนุน ถ้าไม่มีรักษาหน้าต้นแบบกำหนดเอง ไซต์ของคุณจะไม่ได้รับออกการอัปเดตและปรับปรุงที่ Microsoft ทำหน้าต้นแบบ

โค้ดด้านบนมีการอ้างอิงต่อไปนี้:

เวอร์ชันปัจจุบันของ LinqJS ไม่ประกอบด้วยวิธี ByHierarchy ที่ใช้ในโค้ดด้านบน และจะตัดโค้ดนำทาง เมื่อต้องการแก้ไขปัญหานี้ เพิ่มวิธีต่อไปนี้ไปยังไฟล์ Linq.js ก่อนบรรทัด " Flatten: ()ฟังก์ชัน"

ByHierarchy: function(firstLevel, connectBy, orderBy, ascending, parent) {
     ascending = ascending == undefined ? true : ascending;
     var orderMethod = ascending == true ? 'OrderBy' : 'OrderByDescending';
     var source = this;
     firstLevel = Utils.CreateLambda(firstLevel);
     connectBy = Utils.CreateLambda(connectBy);
     orderBy = Utils.CreateLambda(orderBy);
    
     //Initiate or increase level
     var level = parent === undefined ? 1 : parent.level + 1;

    return new Enumerable(function() {
         var enumerator;
         var index = 0;

        var createLevel = function() {
                 var obj = {
                     item: enumerator.Current(),
                     level : level
                 };
                 obj.children = Enumerable.From(source).ByHierarchy(firstLevel, connectBy, orderBy, ascending, obj);
                 if (orderBy !== undefined) {
                     obj.children = obj.children[orderMethod](function(d) {
                         return orderBy(d.item); //unwrap the actual item for sort to work
                     });
                 }
                 obj.children = obj.children.ToArray();
                 Enumerable.From(obj.children).ForEach(function(child) {
                     child.getParent = function() {
                         return obj;
                     };
                 });
                 return obj;
             };

        return new IEnumerator(

        function() {
             enumerator = source.GetEnumerator();
         }, function() {
             while (enumerator.MoveNext()) {
                 var returnArr;
                 if (!parent) {
                     if (firstLevel(enumerator.Current(), index++)) {
                         return this.Yield(createLevel());
                     }

                } else {
                     if (connectBy(parent.item, enumerator.Current(), index++)) {
                         return this.Yield(createLevel());
                     }
                 }
             }
             return false;
         }, function() {
             Utils.Dispose(enumerator);
         })
     });
 },

หมายเหตุ: ข้อจำกัดความรับผิดชอบของการแปลด้วยเครื่อง: บทความนี้มีการแปลด้วยระบบคอมพิวเตอร์โดยไม่มีการดำเนินการโดยบุคคล Microsoft จัดให้มีการแปลด้วยเครื่องนี้เพื่อช่วยให้ผู้ใช้ที่ไม่ได้พูดภาษาอังกฤษสามารถใช้ประโยชน์จากเนื้อหาเกี่ยวกับผลิตภัณฑ์ บริการและเทคโนโลยีของ Microsoft เนื่องจากบทความมีการแปลด้วยเครื่อง อาจมีข้อผิดพลาดด้านคำศัพท์ ไวยากรณ์หรือรูปประโยค

ขยายทักษะของคุณ
สำรวจการฝึกอบรม
รับฟีเจอร์ใหม่ก่อนใคร
เข้าร่วม Office Insider

ข้อมูลนี้เป็นประโยชน์หรือไม่

ขอบคุณสำหรับคำติชมของคุณ!

ขอขอบคุณสำหรับคำติชมของคุณ! เราคิดว่าอาจเป็นประโยชน์ที่จะให้คุณได้ติดต่อกับหนึ่งในตัวแทนฝ่ายสนับสนุน Office ของเรา

×