Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

javascript - Restrict JQM Panel to only 1 instance on page

I'm developing a JQM theme using single pages. I also have a side bar / panel that is built as a seperate html file. This panel is imported into the JQM page using the following JS;

/* Creates the functionality to open the left side panel with a swipe */
$(document).one("pagebeforecreate", function () {
  $.get('left-panel.html', function(data){ 
    $.mobile.pageContainer.prepend(data);
    $("[data-role=panel]").panel().enhanceWithin(); // initialize panel
  }, "html");
});   

Ive got this script in a js file that is loaded at the foot of every page, since users of the 'mobile site' could enter via any page.

Ive noticed via Firebug that an instance of the panel seems to be added with every page I navigate to. So if I visit 3 pages, the panel will be loaded 3 times, 4pages = 4 panels, etc.

It's fair to say I'm fairly novice at JQ & JQM, but I was under the impression that the use of

$(document).one

meant the event only occurred once per page, and would therefore prevent the issue I have.

IF you can help me work out how I can prevent this issue, I'd really appreciate it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The pagebeforecreate event will emit on each and every page, but only ONCE. If you have 5 pages in one HTML file (Multi-Page Model), that event will fire 5 times before creating/showing the target page.

This event can't be delegated to a specific page, e.g. the below code won't work.

$(document).on("pagebeforecreate", "#pageX", function (event) {
  /* do something to pageX */
});

unlike pagecreate which can be delegated to a specific page.

$(document).on("pagecreate", "#pageX", function (event) {
  /* use it to add listeners */
});

However, you can obtain an object of that page which is being created.

$(document).on("pagebeforecreate", function (event) {
  var page = event.target.id;
  if ( page == "pageX") {
    /* do something to pageX */
  }
});

Why .one()?

Since pagebeforecreate can't be delegated and it fires on each page, using .one() will run code once only. However, if you repeat the same code using .one() that code will be executed it again.

Altenative approaches:

  1. Check whether panel is added before adding it.

    $(document).one('pagebeforecreate', function () {
        var panelDOM = $("[data-role=panel]").length;
        if (panelDOM === 0) {
            /* add panel */
        } else {
            /* nothing */
        }
    });
    

    Demo

  2. Use mobileinit as it fires once per document/framework. This event fires before loading jQM, so you will need to enhance/_initialize_ panel after loading jQM.

    <script src="jquery-1.9.1.min.js"></script>
    <script>
        /* inject panel */
        $(document).on("mobileinit", function() {
            var panel = '<div>panel</div>';
            $("body").prepend(panel);
        });
    </script>
    <script src="jquery.mobile-1.4.2.min.js"></script>
    <script>
        /* initialize it */
        $(function() {
            $("[data-role=panel]").panel().enhanceWithin();
        });
    </script>
    

    Demo


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...