jQuery Mobile: เอกสารพร้อมกับเหตุการณ์หน้า


269

ฉันกำลังใช้ jQuery Mobile และฉันมีปัญหาในการทำความเข้าใจความแตกต่างระหว่างเอกสารแบบคลาสสิกที่พร้อมใช้งานกับกิจกรรมหน้า jQuery Mobile

  1. ความแตกต่างที่แท้จริงคืออะไร?

    ทำไมต้อง

    <!-- language: lang-js -->
    
    $(document).ready() {
    
    });

    จะดีกว่า

    $(document).on('pageinit') {
    
    });
  2. ลำดับเหตุการณ์ของเพจคืออะไรเมื่อคุณเปลี่ยนจากหน้าหนึ่งไปอีกหน้าหนึ่ง

  3. ฉันจะส่งข้อมูลจากหน้าหนึ่งไปอีกหน้าหนึ่งได้อย่างไรและสามารถเข้าถึงข้อมูลจากหน้าก่อนหน้าได้อย่างไร


ภายใต้คำถามที่ 1 พวกเขาทั้งคู่เหมือนกัน คุณสามารถปรับเปลี่ยนหรืออธิบายสิ่งที่คุณหมายถึงอีกเล็กน้อย?
Kirk

ดังนั้นน้อยกว่าหนึ่งปีต่อมาเกี่ยวกับเหตุการณ์ pageinit "เหตุการณ์นี้เลิกใช้แล้วใน 1.4.0 เพื่อสนับสนุนการสร้างเพจ" ดูapi.jquerymobile.com/pageinit
DOK

คำตอบ:


439

อัพเดต jQuery Mobile 1.4:

บทความต้นฉบับของฉันมีไว้สำหรับการจัดการหน้าเว็บแบบเก่าโดยทั่วไปทุกอย่างก่อน jQuery Mobile 1.4 วิธีการจัดการแบบเดิมเลิกใช้แล้วและจะยังคงใช้งานได้จนถึง (รวมถึง) jQuery Mobile 1.5 ดังนั้นคุณยังคงสามารถใช้ทุกอย่างที่กล่าวถึงด้านล่างอย่างน้อยก็จนถึงปีหน้าและ jQuery Mobile 1.6

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

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

เนื้อหาที่เก่ากว่า:

บทความนี้ยังสามารถพบได้เป็นส่วนหนึ่งของบล็อกของฉันที่นี่

$(document).on('pageinit') VS $(document).ready()

สิ่งแรกที่คุณเรียนรู้ในjQueryคือการเรียกรหัสภายใน$(document).ready()ฟังก์ชั่นเพื่อให้ทุกอย่างทำงานได้ทันทีที่โหลด DOM อย่างไรก็ตามในjQuery Mobile Ajax จะใช้ในการโหลดเนื้อหาของแต่ละหน้าใน DOM ในขณะที่คุณนำทาง เนื่องจากสิ่งนี้$(document).ready()จะทริกเกอร์ก่อนที่จะโหลดหน้าแรกของคุณและทุกรหัสสำหรับการจัดการหน้าจะถูกดำเนินการหลังจากรีเฟรชหน้า นี่อาจเป็นข้อผิดพลาดที่ลึกซึ้งมาก ในบางระบบอาจปรากฏว่าทำงานได้ดี แต่ในบางระบบอาจทำให้ผิดปกติและยากที่จะทำซ้ำ

ไวยากรณ์ jQuery คลาสสิก:

$(document).ready(function() {

});

เพื่อแก้ปัญหานี้ (และเชื่อฉันว่านี่เป็นปัญหา) นักพัฒนาjQuery Mobileสร้างกิจกรรมหน้า ในหน้าสรุปเหตุการณ์เหตุการณ์ที่เกิดขึ้นในจุดเฉพาะของการดำเนินการหน้า หนึ่งในกิจกรรมหน้าเหล่านั้นคือเหตุการณ์pageinitและเราสามารถใช้งานได้เช่นนี้:

$(document).on('pageinit', function() {

});

เราสามารถไปให้ไกลกว่านั้นและใช้ id หน้าแทนตัวเลือกเอกสาร สมมติว่าเรามีหน้า jQuery Mobile พร้อมดัชนี id :

<div data-role="page" id="index">
    <div data-theme="a" data-role="header">
        <h3>
            First Page
        </h3>
        <a href="#second" class="ui-btn-right">Next</a>
    </div>

    <div data-role="content">
        <a href="#" data-role="button" id="test-button">Test button</a>
    </div>

    <div data-theme="a" data-role="footer" data-position="fixed">

    </div>
</div>

ในการรันโค้ดที่จะสามารถใช้ได้เฉพาะกับหน้าดัชนีเราสามารถใช้ไวยากรณ์นี้:

$('#index').on('pageinit', function() {

});

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

นี่คือตัวอย่างการใช้งาน: http://jsfiddle.net/Gajotres/Q3Usv/เพื่อสาธิตปัญหานี้

มีข้อสังเกตเพิ่มเติมอีกเล็กน้อยสำหรับคำถามนี้ ไม่ว่าคุณจะใช้ 1 html หลายหน้าหรือกระบวนทัศน์ไฟล์ HTML หลายไฟล์ขอแนะนำให้แยกหน้า JavaScript ที่กำหนดเองทั้งหมดของคุณออกเป็นไฟล์ JavaScript แยกต่างหาก สิ่งนี้จะช่วยทำให้รหัสของคุณดีขึ้น แต่คุณจะมีภาพรวมของรหัสที่ดีขึ้นโดยเฉพาะในขณะที่สร้างแอปพลิเคชันjQuery Mobile

นอกจากนี้ยังมีอีกพิเศษมือถือ jQueryเหตุการณ์และเป็นที่เรียกmobileinit เมื่อjQuery Mobileเริ่มทำงานจะเรียกใช้เหตุการณ์mobileinitบนวัตถุเอกสาร แทนที่การตั้งค่าเริ่มต้นผูกพวกเขาที่จะmobileinit หนึ่งในตัวอย่างที่ดีของการใช้งานmobileinitคือการปิดการโหลดหน้า Ajax หรือเปลี่ยนพฤติกรรมการโหลด Ajax เริ่มต้น

$(document).on("mobileinit", function(){
  //apply overrides here
});

ลำดับการเปลี่ยนกิจกรรมหน้า

กิจกรรมแรกสามารถพบได้ที่นี่: http://api.jquerymobile.com/category/events/

สมมติว่าเรามีหน้า A และหน้า B นี่เป็นคำสั่งยกเลิกการโหลด / โหลด:

  1. หน้า B - เหตุการณ์pagebeforecreate

  2. หน้า B - เหตุการณ์สร้างหน้า

  3. หน้า B - เหตุการณ์pageinit

  4. หน้า A - หน้าเหตุการณ์ก่อนหน้า

  5. หน้า A - เพจเจอร์เหตุการณ์

  6. หน้า A - เหตุการณ์หน้าหนัง

  7. หน้า B - เหตุการณ์pagebeforeshow

  8. หน้า B - เหตุการณ์pageshow

สำหรับการทำความเข้าใจเหตุการณ์หน้าเว็บที่ดีขึ้นอ่านสิ่งนี้:

  • pagebeforeload, pageloadและpageloadfailedถูกยิงเมื่อหน้าภายนอกมีการโหลด
  • pagebeforechange, pagechangeและpagechangefailedมีเหตุการณ์การเปลี่ยนแปลงหน้า เหตุการณ์เหล่านี้เกิดขึ้นเมื่อผู้ใช้นำทางระหว่างหน้าต่างๆในแอปพลิเคชัน
  • pagebeforeshow, pagebeforehide, pageshowและpagehideเหตุการณ์เปลี่ยนแปลงหน้า เหตุการณ์เหล่านี้จะเริ่มก่อนระหว่างและหลังการเปลี่ยนภาพและตั้งชื่อ
  • pagebeforecreate, pagecreateและpageinitมีการเริ่มต้นหน้า
  • pageremove สามารถถูกไล่ออกและจัดการเมื่อหน้าถูกลบออกจาก DOM

การโหลดหน้าตัวอย่าง jsFiddle: http://jsfiddle.net/Gajotres/QGnft/

หากไม่เปิดใช้งาน AJAX เหตุการณ์บางอย่างอาจไม่ทำงาน

ป้องกันการเปลี่ยนหน้า

หากจำเป็นต้องป้องกันการเปลี่ยนหน้าด้วยเหตุผลบางประการคุณสามารถทำได้ด้วยรหัสนี้:

$(document).on('pagebeforechange', function(e, data){
    var to = data.toPage,
        from = data.options.fromPage;

    if (typeof to  === 'string') {
        var u = $.mobile.path.parseUrl(to);
        to = u.hash || '#' + u.pathname.substring(1);
        if (from) from = '#' + from.attr('id');

        if (from === '#index' && to === '#second') {
            alert('Can not transition from #index to #second!');
            e.preventDefault();
            e.stopPropagation();

            // remove active status on a button, if transition was triggered with a button
            $.mobile.activePage.find('.ui-btn-active').removeClass('ui-btn-active ui-focus ui-btn');;
        }
    }
});

ตัวอย่างนี้จะทำงานในกรณีใด ๆ เพราะจะทำให้เกิดการขอร้องของการเปลี่ยนแปลงหน้าทุกครั้งและสิ่งที่สำคัญที่สุดที่จะป้องกันการเปลี่ยนแปลงหน้าก่อนที่จะเกิดการเปลี่ยนแปลงหน้า

นี่คือตัวอย่างการทำงาน:

ป้องกันหลายเหตุการณ์ที่มีผลผูกพัน / วิกฤติ

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

$(document).on('pagebeforeshow','#index' ,function(e,data){
    $(document).on('click', '#test-button',function(e) {
        alert('Button click');
    });
});

ตัวอย่างการทำงาน jsFiddle: http://jsfiddle.net/Gajotres/CCfL4/

ทุกครั้งที่คุณไปที่หน้า#INDEXคลิกเหตุการณ์ความประสงค์จะถูกผูกไว้กับปุ่ม# ทดสอบปุ่ม ทดสอบโดยเลื่อนจากหน้า 1 เป็นหน้า 2 และย้อนกลับหลายครั้ง มีสองสามวิธีในการป้องกันปัญหานี้:

โซลูชันที่ 1

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

ตัวอย่างการทำงาน jsFiddle: http://jsfiddle.net/Gajotres/AAFH8/

วิธีแก้ปัญหาการทำงานนี้ทำขึ้นจากตัวอย่างที่มีปัญหาก่อนหน้านี้

โซลูชันที่ 2

ลบกิจกรรมก่อนที่จะผูก:

$(document).on('pagebeforeshow', '#index', function(){
    $(document).off('click', '#test-button').on('click', '#test-button',function(e) {
        alert('Button click');
    });
});

ตัวอย่างการทำงาน jsFiddle: http://jsfiddle.net/Gajotres/K8YmG/

โซลูชันที่ 3

ใช้ตัวเลือกตัวกรอง jQuery เช่นนี้:

$('#carousel div:Event(!click)').each(function(){
    //If click is not bind to #carousel div do something
});

เนื่องจากตัวกรองเหตุการณ์ไม่ใช่ส่วนหนึ่งของเฟรมเวิร์ก jQuery อย่างเป็นทางการคุณสามารถดูได้ที่นี่: http://www.codenothing.com/archives/2009/event-filter/

โดยสรุปหากความเร็วเป็นสิ่งที่คุณกังวลหลักโซลูชัน 2จะดีกว่าโซลูชัน 1 มาก

โซลูชันที่ 4

ใหม่อาจจะง่ายที่สุดของพวกเขาทั้งหมด

$(document).on('pagebeforeshow', '#index', function(){
    $(document).on('click', '#test-button',function(e) {
        if(e.handled !== true) // This will prevent event triggering more than once
        {
            alert('Clicked');
            e.handled = true;
        }
    });
});

ตัวอย่างการทำงาน jsFiddle: http://jsfiddle.net/Gajotres/Yerv9/

Tnx ไปยังsholsingerสำหรับการแก้ปัญหานี้: http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/

เหตุการณ์เปลี่ยนหน้า pageChange - เรียกสองครั้ง

บางครั้งเหตุการณ์การเปลี่ยนหน้าสามารถเรียกสองครั้งและไม่มีอะไรเกี่ยวข้องกับปัญหาที่กล่าวถึงก่อนหน้านี้

เหตุผลที่เหตุการณ์ pagebeforechange เกิดขึ้นสองครั้งเกิดจากการเรียกซ้ำใน changePage เมื่อ toPage ไม่ใช่วัตถุ DOM ขั้นสูง jQuery การเรียกซ้ำนี้เป็นสิ่งที่อันตรายเนื่องจากนักพัฒนาซอฟต์แวร์ได้รับอนุญาตให้เปลี่ยนหน้าภายในเหตุการณ์ หากผู้พัฒนาตั้งค่าหน้าเป็นสตริงอย่างสม่ำเสมอภายในตัวจัดการเหตุการณ์ pageBforechange ไม่ว่าวัตถุนั้นจะเป็นลูปวนซ้ำแบบวนซ้ำหรือไม่ก็ตาม เหตุการณ์ pageload ส่งหน้าใหม่เป็นคุณสมบัติหน้าของวัตถุข้อมูล (ควรเพิ่มลงในเอกสารประกอบซึ่งไม่ได้อยู่ในรายการในปัจจุบัน) เหตุการณ์ pageload จึงสามารถใช้เพื่อเข้าถึงหน้าที่โหลด

ในสองสามคำนี้เกิดขึ้นเพราะคุณกำลังส่งพารามิเตอร์เพิ่มเติมผ่าน pageChange

ตัวอย่าง:

<a data-role="button" data-icon="arrow-r" data-iconpos="right" href="#care-plan-view?id=9e273f31-2672-47fd-9baa-6c35f093a800&amp;name=Sat"><h3>Sat</h3></a>

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

หน้าเปลี่ยนเวลา

ตามที่ระบุไว้เมื่อคุณเปลี่ยนจากหน้า jQuery Mobile หนึ่งเป็นอีกหน้าหนึ่งโดยทั่วไปแล้วจะเป็นการคลิกลิงค์ไปยังหน้า jQuery Mobile อื่นที่มีอยู่แล้วใน DOM หรือโดยการเรียก $ .mobile.changePage ด้วยตนเองเหตุการณ์หลายอย่างและการกระทำที่ตามมาจะเกิดขึ้น ในระดับสูงการกระทำต่อไปนี้เกิดขึ้น:

  • กระบวนการเปลี่ยนหน้าเริ่มต้นขึ้น
  • มีการโหลดหน้าใหม่
  • เนื้อหาสำหรับหน้านั้นคือ“ ปรับปรุง” (สไตล์)
  • การเปลี่ยนแปลง (สไลด์ / ป๊อป / ฯลฯ ) จากหน้าปัจจุบันไปยังหน้าใหม่เกิดขึ้น

นี่เป็นเกณฑ์มาตรฐานการเปลี่ยนหน้าโดยเฉลี่ย:

การโหลดและการประมวลผลหน้า: 3 ms

การปรับปรุงหน้า: 45 ms

การเปลี่ยน: 604 ms

เวลาทั้งหมด: 670 ms

* ค่าเหล่านี้มีหน่วยเป็นมิลลิวินาที

ดังนั้นอย่างที่คุณเห็นเหตุการณ์การเปลี่ยนแปลงกำลังกินเวลาดำเนินการเกือบ 90%

การจัดการข้อมูล / พารามิเตอร์ระหว่างการเปลี่ยนหน้า

เป็นไปได้ที่จะส่งพารามิเตอร์ / s จากหน้าหนึ่งไปอีกหน้าหนึ่งในระหว่างการเปลี่ยนหน้า สามารถทำได้สองสามวิธี

การอ้างอิง: https://stackoverflow.com/a/13932240/1848600

โซลูชันที่ 1:

คุณสามารถส่งผ่านค่าด้วย changePage:

$.mobile.changePage('page2.html', { dataUrl : "page2.html?paremeter=123", data : { 'paremeter' : '123' }, reloadPage : true, changeHash : true });

และอ่านสิ่งเหล่านี้:

$(document).on('pagebeforeshow', "#index", function (event, data) {
    var parameters = $(this).data("url").split("?")[1];;
    parameter = parameters.replace("parameter=","");
    alert(parameter);
});

ตัวอย่าง :

index.html

<!DOCTYPE html>
  <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="widdiv=device-widdiv, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <title>
    </title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
    <script src="http://www.dragan-gaic.info/js/jquery-1.8.2.min.js">
    </script>
    <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
    <script>
        $(document).on('pagebeforeshow', "#index",function () {
            $(document).on('click', "#changePage",function () {
                $.mobile.changePage('second.html', { dataUrl : "second.html?paremeter=123", data : { 'paremeter' : '123' }, reloadPage : false, changeHash : true });
            });
        });

        $(document).on('pagebeforeshow', "#second",function () {
            var parameters = $(this).data("url").split("?")[1];;
            parameter = parameters.replace("parameter=","");
            alert(parameter);
        });
    </script>
   </head>
   <body>
    <!-- Home -->
    <div data-role="page" id="index">
        <div data-role="header">
            <h3>
                First Page
            </h3>
        </div>
        <div data-role="content">
          <a data-role="button" id="changePage">Test</a>
        </div> <!--content-->
    </div><!--page-->

  </body>
</html>

second.html

<!DOCTYPE html>
  <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="widdiv=device-widdiv, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <title>
    </title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
    <script src="http://www.dragan-gaic.info/js/jquery-1.8.2.min.js">
    </script>
    <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
   </head>
   <body>
    <!-- Home -->
    <div data-role="page" id="second">
        <div data-role="header">
            <h3>
                Second Page
            </h3>
        </div>
        <div data-role="content">

        </div> <!--content-->
    </div><!--page-->

  </body>
</html>

โซลูชันที่ 2:

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

var storeObject = {
    firstname : '',
    lastname : ''
}

ตัวอย่าง: http://jsfiddle.net/Gajotres/9KKbx/

โซลูชันที่ 3:

คุณยังสามารถเข้าถึงข้อมูลจากหน้าก่อนหน้าเช่นนี้:

$(document).on('pagebeforeshow', '#index',function (e, data) {
    alert(data.prevPage.attr('id'));
});

วัตถุprevPageเก็บหน้าก่อนหน้าเสร็จสมบูรณ์

โซลูชันที่ 4:

ในฐานะที่เป็นทางออกสุดท้ายเรามีการใช้ HTML ที่ดีของ localStorage ใช้งานได้กับเบราว์เซอร์ HTML5 เท่านั้น (รวมถึงเบราว์เซอร์ Android และ iOS) แต่ข้อมูลที่เก็บไว้ทั้งหมดจะคงอยู่ผ่านการรีเฟรชหน้า

if(typeof(Storage)!=="undefined") {
    localStorage.firstname="Dragan";
    localStorage.lastname="Gaic";
}

ตัวอย่าง: http://jsfiddle.net/Gajotres/J9NTr/

ทางออกที่ดีที่สุดน่าจะเป็นไปได้ แต่จะล้มเหลวใน iOS 5.X บางรุ่น มันเป็นข้อผิดพลาดที่รู้กันดี

ห้ามใช้.live()/ .bind()/.delegate()

ฉันลืมที่จะพูดถึง (และ tnx andleerสำหรับเตือนความจำฉัน) ใช้เปิด / ปิดสำหรับการเชื่อมโยงเหตุการณ์ / ยกเลิกการผูกสด / ตายและผูก / เลิกผูกจะเลิกใช้

วิธีการ. live () ของ jQuery ถูกมองว่าเป็นสวรรค์เมื่อได้รับการแนะนำให้รู้จักกับ API ในรุ่น 1.3 ในแอป jQuery ทั่วไปอาจมีการจัดการ DOM เป็นจำนวนมากและมันอาจกลายเป็นเรื่องน่าเบื่อหน่ายที่จะขอและไม่เปิดเผยเมื่อองค์ประกอบเข้ามา .live()วิธีการดังกล่าวทำให้สามารถเชื่อมต่อเหตุการณ์ตลอดอายุการใช้งานของแอพตามตัวเลือก เยี่ยมมาก ผิด.live()วิธีนั้นช้ามาก .live()วิธีจริง hooks เหตุการณ์ไปยังวัตถุเอกสารซึ่งหมายความว่าฟองเหตุการณ์ที่จะต้องเพิ่มขึ้นจากองค์ประกอบที่สร้างเหตุการณ์จนกว่าจะถึงเอกสาร อาจใช้เวลานานอย่างน่าอัศจรรย์

มันเลิกใช้แล้ว ผู้คนในทีม jQuery ไม่แนะนำให้ใช้อีกต่อไปและไม่ทำเช่นนั้นแม้ว่าจะเป็นเรื่องน่าเบื่อที่จะขอและปลดล็อกเหตุการณ์รหัสของคุณจะเร็วขึ้นกว่านี้หากไม่มี.live()วิธีการ

แทนการที่คุณควรใช้.live() เร็วกว่า. live ประมาณ 2-3เท่า ลองดูที่มาตรฐานนี้มีผลผูกพันเหตุการณ์: http://jsperf.com/jquery-live-vs-delegate-vs-on/34ทุกอย่างจะชัดเจนจากที่นั่น.on().on()

Benchmarking:

มีสคริปต์ที่ยอดเยี่ยมที่สร้างขึ้นสำหรับการเปรียบเทียบกิจกรรมหน้าjQuery Mobile มันสามารถพบได้ที่นี่: https://github.com/jquery/jquery-mobile/blob/master/tools/page-change-time.js แต่ก่อนที่คุณจะทำอะไรกับมันฉันแนะนำให้คุณลบalertระบบการแจ้งเตือนของมัน("หน้าการเปลี่ยนแปลง" แต่ละอันจะแสดงข้อมูลนี้โดยหยุดแอพ) และเปลี่ยนเป็นconsole.logฟังก์ชั่น

โดยพื้นฐานแล้วสคริปต์นี้จะบันทึกกิจกรรมหน้าทั้งหมดของคุณและถ้าคุณอ่านบทความนี้อย่างละเอียด (คำอธิบายเหตุการณ์หน้า) คุณจะรู้ว่าใช้เวลานานเท่าใดในการปรับปรุงหน้า jQm การเปลี่ยนหน้า ....

หมายเหตุสุดท้าย

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

การเปลี่ยนแปลง:

  • 30.01.2013 - เพิ่มวิธีการใหม่ในการป้องกันการเกิดเหตุการณ์หลายอย่าง
  • 31.01.2013 - เพิ่มความกระจ่างที่ดีขึ้นสำหรับบทการจัดการข้อมูล / พารามิเตอร์ระหว่างการเปลี่ยนหน้า
  • 03.02.2013 - เพิ่มเนื้อหา / ตัวอย่างใหม่ในบทการจัดการข้อมูล / พารามิเตอร์ระหว่างการเปลี่ยนหน้า
  • 22.05.2013 - เพิ่มโซลูชันสำหรับการเปลี่ยนหน้า / ป้องกันการเปลี่ยนแปลงและเพิ่มลิงค์ไปยังเอกสาร API ของเหตุการณ์ทางการหน้า
  • 18.05.2013 - เพิ่มโซลูชันอื่นจากการผูกเหตุการณ์หลายรายการ

2
$().live()ถูกคิดค่าเสื่อมราคาใน jQuery 1.7 และลบออกใน 1.9 ดังนั้นจึงควรเป็นส่วนหนึ่งของโซลูชัน jQuery Mobile ใด ๆ เวอร์ชันหลักขั้นต่ำปัจจุบันสำหรับ jQM 1.7
andleer

16
+1 สรุปที่เป็นประโยชน์มากเกี่ยวกับพฤติกรรมที่สำคัญเกี่ยวกับการโหลดหน้าเว็บ
RedFilter

2
pagecreateเหตุการณ์จะเริ่มทำงานเพียงครั้งเดียวเมื่อสร้างหน้าเว็บครั้งแรก ดังนั้นหากเราผูกกิจกรรมการคลิกไว้ภายในpagecreateจะไม่ทำงานหลายครั้ง มีบางอย่างที่ฉันรู้ขณะพัฒนาแอพ แต่เราไม่สามารถใช้pagecreateผูกเหตุการณ์ได้เสมอดังนั้นวิธีที่คุณมอบให้ดีที่สุด +1 ที่ได้รับ
Jay Mayu

1
คุณมีเพจก่อนหน้าแสดงรายการสองครั้ง มันถูกระบุว่าเป็นหมายเลข 5 และหมายเลข 8 มันถูกเรียกสองครั้งหรือไม่
Chase Roberts

นั่นคือการพิมพ์ผิดฉันได้แก้ไขแล้ว pagebeforeshow จะทริกเกอร์เพียงครั้งเดียว ขอบคุณสำหรับการสังเกต
Gajotres

17

บางท่านอาจพบว่ามีประโยชน์ เพียงคัดลอกวางลงในหน้าของคุณและคุณจะได้รับลำดับเหตุการณ์ที่เกิดขึ้นในคอนโซล Chrome ( Ctrl+ Shift+ I)

$(document).on('pagebeforecreate',function(){console.log('pagebeforecreate');});
$(document).on('pagecreate',function(){console.log('pagecreate');});
$(document).on('pageinit',function(){console.log('pageinit');});
$(document).on('pagebeforehide',function(){console.log('pagebeforehide');});
$(document).on('pagebeforeshow',function(){console.log('pagebeforeshow');});
$(document).on('pageremove',function(){console.log('pageremove');});
$(document).on('pageshow',function(){console.log('pageshow');});
$(document).on('pagehide',function(){console.log('pagehide');});
$(window).load(function () {console.log("window loaded");});
$(window).unload(function () {console.log("window unloaded");});
$(function () {console.log('document ready');});

คุณจะไม่เห็นการยกเลิกการโหลดในคอนโซลเนื่องจากมันถูกไล่ออกเมื่อหน้ากำลังถูกยกเลิกการโหลด (เมื่อคุณย้ายออกจากหน้า) ใช้มันแบบนี้:

$(window).unload(function () { debugger; console.log("window unloaded");});

และคุณจะเห็นสิ่งที่ฉันหมายถึง


4

นี่เป็นวิธีที่ถูกต้อง:

ในการรันโค้ดที่จะสามารถใช้ได้กับหน้าดัชนีเท่านั้นเราสามารถใช้ไวยากรณ์นี้:

$(document).on('pageinit', "#index",  function() {
    ...
});

10
คำตอบข้างต้นระบุไว้เหมือนกันคุณไม่คิดเหรอ? :)
โอมาร์

ขอบคุณสำหรับคำตอบสั้น ๆ แก้ไขด่วนที่ดี :-)
SharpC

1

ความแตกต่างง่ายๆระหว่างเอกสารพร้อมและเหตุการณ์หน้าใน jQuery-mobile คือ:

  1. เหตุการณ์พร้อมเอกสารจะใช้สำหรับหน้า HTML ทั้งหมด

    $(document).ready(function(e) {
        // Your code
    });
  2. เมื่อมีเหตุการณ์หน้าใช้สำหรับจัดการเหตุการณ์หน้าเฉพาะ:

    <div data-role="page" id="second">
        <div data-role="header">
            <h3>
                Page header
            </h3>
        </div>
        <div data-role="content">
            Page content
        </div> <!--content-->
        <div data-role="footer">
            Page footer
        </div> <!--footer-->
    </div><!--page-->

คุณยังสามารถใช้เอกสารสำหรับจัดการเหตุการณ์ pageinit:

$(document).on('pageinit', "#mypage", function() {

});

-1

ในขณะที่คุณใช้. on () เป็นพื้นแบบสอบถามที่คุณใช้

ในทางกลับกัน. Ready (เช่นในกรณีของคุณ) เป็นแบบสอบถามแบบคงที่ ในขณะที่ใช้งานคุณสามารถอัปเดตข้อมูลแบบไดนามิกและไม่ต้องรอให้หน้าโหลด คุณสามารถส่งผ่านค่าในฐานข้อมูลของคุณ (ถ้าจำเป็น) เมื่อป้อนค่าเฉพาะ

การใช้เคียวรีแบบสดเป็นเรื่องปกติในรูปแบบที่เราป้อนข้อมูล (บัญชีหรือโพสต์หรือแม้แต่ความคิดเห็น)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.