mirror of
https://github.com/Hopiu/jquery-mobile.git
synced 2026-03-17 06:20:26 +00:00
Added fetchlink behavior on a per-link level, normalized incoming href/src.
This commit is contained in:
parent
4b416c65cc
commit
326f1df7c6
7 changed files with 271 additions and 72 deletions
|
|
@ -59,6 +59,8 @@ div.ui-mobile-viewport { overflow-x: hidden; }
|
|||
.ui-loading .ui-mobile-viewport { overflow: hidden !important; }
|
||||
.ui-loading .ui-loader { display: block; }
|
||||
.ui-loading .ui-page { overflow: hidden; }
|
||||
.ui-loading-inline { min-height: 35px; position: relative; }
|
||||
.ui-loader-inline .ui-icon-loading { display: block; margin: 0 auto; position: absolute; left: 50%; top: 50%; margin: -17px 0 0 -17px; width: 35px; height: 35px; background-color: rgba(0,0,0,.1); }
|
||||
.ui-loader { display: none; position: absolute; opacity: .85; z-index: 100; left: 50%; width: 200px; margin-left: -130px; margin-top: -35px; padding: 10px 30px; }
|
||||
.ui-loader h1 { font-size: 15px; text-align: center; }
|
||||
.ui-loader .ui-icon { position: static; display: block; opacity: .9; margin: 0 auto; width: 35px; height: 35px; background-color: transparent; }
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<div data-role="content" data-theme="c">
|
||||
<h1>Delete page?</h1>
|
||||
<p>This is a regular page, styled as a dialog. To create a dialog, just link to a normal page and include a transition and <code>data-rel="dialog"</code> attribute.</p>
|
||||
<p class="inner-content">This is a regular page, styled as a dialog. To create a dialog, just link to a normal page and include a transition and <code>data-rel="dialog"</code> attribute.</p>
|
||||
<a href="docs-dialogs.html" data-role="button" data-rel="back" data-theme="b">Sounds good</a>
|
||||
<a href="docs-dialogs.html" data-role="button" data-rel="back" data-theme="c">Cancel</a>
|
||||
</div>
|
||||
|
|
|
|||
87
docs/pages/fetchlinks.html
Normal file
87
docs/pages/fetchlinks.html
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>jQuery Mobile Framework - Dialog Example</title>
|
||||
<link rel="stylesheet" href="../../css/themes/default/" />
|
||||
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>
|
||||
<script src="../../js/jquery.js"></script>
|
||||
<script src="../../experiments/themeswitcher/jquery.mobile.themeswitcher.js"></script>
|
||||
<script src="../_assets/js/jqm-docs.js"></script>
|
||||
<script src="../../js/"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div data-role="page">
|
||||
<div data-role="content">
|
||||
|
||||
<h2>AJAX Fetch Links</h2>
|
||||
<p>A <a href="dialog.html">standard link</a> with a href pointing to a local anchor (#foo) or external page (foo.html) will trigger a full animated page change via the AJAX nav system with the default transition.</p>
|
||||
<pre><code><a href="dialog.html">Link</a>
|
||||
</code></pre>
|
||||
|
||||
<p>A <a href="dialog.html" data-rel="dialog">dialog</a> is made by adding <code>data-rel="dialog"</code> to a link to display the page with an inset appearance and the default dialog transition.</p>
|
||||
|
||||
<pre><code><a href="dialog.html" <strong>data-rel="dialog"</strong>>Link</a>
|
||||
</code></pre>
|
||||
<p>A <a data-role="fetchlink" data-target=".quote" href="../lists/lists-thumbnails.html">fetch link</a> is created by adding the <code>data-target</code> attribute to a link. This tells the framework to <strong>not</strong> change pages and instead load the <code>href</code> into the target DOM element on the current page when the link is clicked. The target can be any jQuery selector (or restrict to ID only?). </p>
|
||||
|
||||
<p><a data-role="fetchlink" data-target=".quote" href="dialog.html" data-fragment=".inner-content">Alternate Content</a></p>
|
||||
|
||||
|
||||
|
||||
<h2>Grouped Fetch Links</h2>
|
||||
|
||||
<div data-role="fetchlink" data-target=".quote" data-fragment=".inner-content">
|
||||
<p>A <a href="../lists/lists-thumbnails.html">fetch link</a> is created by adding the <code>data-target</code> attribute to a link. This tells the framework to <strong>not</strong> change pages and instead load the <code>href</code> into the target DOM element on the current page when the link is clicked. The target can be any jQuery selector (or restrict to ID only?). </p>
|
||||
<p><a href="dialog.html">Alternate Content</a></p>
|
||||
</div>
|
||||
|
||||
|
||||
<pre><code><a href="dialog.html" <strong>data-target=".quote"</strong>>
|
||||
</code></pre>
|
||||
|
||||
|
||||
<div class="quote">
|
||||
<p>To be replaced.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<p>The <a href="dialog.html" data-role="fetchlink" data-target=".quote" data-fragment="[data-role='content']">content fragment</a> from the loaded page can be specified. By default, the framework will load in the <strong>contents</strong> of the <code>data-role="page"</code> container (not the page wrapper itself), but it's possible to specify what content from the page to pull into the target by adding a <code>data-fragment</code> attribute to the link with any jQuery selector.</p>
|
||||
|
||||
<pre><code><a href="dialog.html" data-target=".quote" <strong>data-fragment="[data-role='content']"</strong>>
|
||||
</code></pre>
|
||||
|
||||
<p>The <a data-role="fetchlink" href="dialog.html" data-target=".quote" data-method="before">target method</a> for a link can be specified by adding the <code>data-method</code> attribute to a link. This specifies whether to <code>replace</code>, <code>append</code>, <code>prepend</code>, or insert the content <code>before</code> or <code>after</code> the target element. By default, an external href will replace the target.</p>
|
||||
|
||||
<pre><code><a href="dialog.html" data-target=".quote" <strong>data-method="after"</strong>>
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
<p>A <a href="dialog.html" data-role="fetchlink" data-target=".quote" data-breakpoint="500">breakpoint option</a> will automatically load the fetch link if the screen width is larger than the specified value instead of waiting for the link to be clicked. The <code>data-breakpoint</code> attribute on the link specifies the min-width pixel value to load the link.</p>
|
||||
|
||||
<pre><code><a href="dialog.html" data-target=".quote" <strong>data-breakpoint="500"</strong>>
|
||||
</code></pre>
|
||||
|
||||
|
||||
<h2>Local Fetch Links</h2>
|
||||
<p>Similar to above but examples use local hrefs (#foo) and there isn't a need for a <code>data-fragment</code> attribute since we're already specifying that in the href.</p>
|
||||
|
||||
|
||||
<blockquote class="bq">
|
||||
<p>“You will not apply my precept,” he said, shaking his head. “How often have I said to you that when you have eliminated the impossible, whatever remains, however improbable, must be the truth?”</p>
|
||||
<address>Arthur Conan Doyle</address>
|
||||
<cite>Sherlock Holmes: The Sign of the Four</cite>
|
||||
</blockquote>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -36,6 +36,7 @@ $files = array(
|
|||
'jquery.mobile.links.js',
|
||||
'jquery.mobile.fixHeaderFooter.js',
|
||||
'jquery.mobile.fixHeaderFooter.native.js',
|
||||
'jquery.mobile.fetchlinks.js',
|
||||
'jquery.mobile.init.js'
|
||||
);
|
||||
|
||||
|
|
|
|||
95
js/jquery.mobile.fetchlinks.js
Normal file
95
js/jquery.mobile.fetchlinks.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
(function( $, undefined ) {
|
||||
|
||||
$.widget( "mobile.fetchlink", $.mobile.widget, {
|
||||
options: {
|
||||
initSelector: ":jqmData(role='fetchlink')"
|
||||
},
|
||||
_create: function() {
|
||||
|
||||
|
||||
$( this.element )
|
||||
.click(function() {
|
||||
var el = $( this ),
|
||||
url = el.attr( "href" ),
|
||||
target = el.data( "target" ),
|
||||
targetEl = target && $( target ) || el,
|
||||
fragment = el.data( "fragment" ),
|
||||
load = fragment || ":jqmData(role='page')",
|
||||
threshold = screen.width > parseInt( el.data( "breakpoint" ) || 0 ),
|
||||
methods = [ "append", "prepend", "replace", "before", "after" ],
|
||||
method = "html",
|
||||
url;
|
||||
|
||||
if ( threshold ) {
|
||||
for( var ml = methods.length, i=0; i < ml; i++ ){
|
||||
if( el.is( "[data-include='" + methods[ i ] + "']" ) ){
|
||||
method = methods[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( method === "replace" ){
|
||||
method += "With";
|
||||
}
|
||||
|
||||
if ( url && method ) {
|
||||
|
||||
targetEl.ajaxStart(function(){
|
||||
var $el = $(this);
|
||||
|
||||
$el
|
||||
.addClass('ui-loading-inline')
|
||||
.trigger('inlineLoader')
|
||||
.height( $el.height() );
|
||||
});
|
||||
|
||||
$.get( url, function( resp ) {
|
||||
var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
||||
data = $( $("<div/>").append( resp.replace( rscript, "" ) ).find( load ) )
|
||||
responseEl = !fragment ? $( data.html() ) : data,
|
||||
normalizePath = function( sel, attr ) {
|
||||
responseEl.find( sel ).each(function() {
|
||||
var $el = $(this),
|
||||
oPath = $el.attr( attr );
|
||||
|
||||
$el.attr( attr, $.mobile.path.parseUrl( url ).directory + oPath );
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
normalizePath( 'img', 'src' );
|
||||
normalizePath( 'a', 'href');
|
||||
|
||||
setTimeout(function() {
|
||||
targetEl[ method ]( responseEl.addClass('fade in') );
|
||||
|
||||
responseEl
|
||||
.trigger( "create" )
|
||||
.trigger( "fetchlink", { target : targetEl, data: responseEl });
|
||||
|
||||
targetEl
|
||||
.removeClass('ui-loading-inline')
|
||||
.height('auto');
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$( document ).bind( "inlineLoader", function( e ){
|
||||
$( e.target ).children().removeClass('fade in').addClass('fade out');
|
||||
|
||||
setTimeout(function() {
|
||||
$( e.target ).html( "<div class='ui-loader-inline fade in'><span class='ui-icon ui-icon-loading spin'></span></div>" );
|
||||
}, 300);
|
||||
});
|
||||
|
||||
//auto self-init widgets
|
||||
$( document ).bind( "pagecreate create", function( e ){
|
||||
$( $.mobile.fetchlink.prototype.options.initSelector, e.target ).fetchlink();
|
||||
});
|
||||
|
||||
})( jQuery );
|
||||
|
|
@ -1211,7 +1211,7 @@
|
|||
}
|
||||
|
||||
// The base URL for any given element depends on the page it resides in.
|
||||
function getClosestBaseUrl( ele )
|
||||
$.mobile.getClosestBaseUrl = function( ele )
|
||||
{
|
||||
// Find the closest page and extract out its url.
|
||||
var url = $( ele ).closest( ".ui-page" ).jqmData( "url" ),
|
||||
|
|
|
|||
|
|
@ -4,84 +4,98 @@
|
|||
|
||||
(function( $, undefined ) {
|
||||
|
||||
$.mobile.page.prototype.options.backBtnText = "Back";
|
||||
$.mobile.page.prototype.options.addBackBtn = false;
|
||||
$.mobile.page.prototype.options.backBtnTheme = null;
|
||||
$.mobile.page.prototype.options.headerTheme = "a";
|
||||
$.mobile.page.prototype.options.footerTheme = "a";
|
||||
$.mobile.page.prototype.options.contentTheme = null;
|
||||
|
||||
$( document ).delegate( ":jqmData(role='page'), :jqmData(role='dialog')", "pagecreate", function( e ) {
|
||||
$.widget( "mobile.sections", $.mobile.widget, {
|
||||
options: {
|
||||
initSelector : ":jqmData(role='page'), :jqmData(role='dialog')",
|
||||
sectionSelector : ":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')",
|
||||
backBtnText : "top",
|
||||
addBackBtn : null,
|
||||
backBtnTheme : ":jqmData(role='navbar')",
|
||||
headerTheme : "a",
|
||||
footerTheme : "a",
|
||||
contentTheme : null
|
||||
},
|
||||
|
||||
var $page = $( this ),
|
||||
o = $page.data( "page" ).options,
|
||||
pageRole = $page.jqmData( "role" ),
|
||||
pageTheme = o.theme;
|
||||
|
||||
$( ":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')", this ).each(function() {
|
||||
var $this = $( this ),
|
||||
role = $this.jqmData( "role" ),
|
||||
theme = $this.jqmData( "theme" ),
|
||||
contentTheme = theme || o.contentTheme || ( pageRole === "dialog" && pageTheme ),
|
||||
$headeranchors,
|
||||
leftbtn,
|
||||
rightbtn,
|
||||
backBtn;
|
||||
|
||||
$this.addClass( "ui-" + role );
|
||||
_create: function() {
|
||||
var self = this;
|
||||
|
||||
//apply theming and markup modifications to page,header,content,footer
|
||||
if ( role === "header" || role === "footer" ) {
|
||||
|
||||
var thisTheme = theme || ( role === "header" ? o.headerTheme : o.footerTheme ) || pageTheme;
|
||||
$( self.options.initSelector ).each(function() {
|
||||
var $page = $( this ),
|
||||
o = self.options,
|
||||
pageRole = $page.jqmData( "role" ),
|
||||
pageTheme = o.theme;
|
||||
|
||||
$( o.sectionSelector, this ).each(function() {
|
||||
var $this = $( this ),
|
||||
role = $this.jqmData( "role" ),
|
||||
theme = $this.jqmData( "theme" ),
|
||||
contentTheme = theme || o.contentTheme || ( pageRole === "dialog" && pageTheme ),
|
||||
$headeranchors,
|
||||
leftbtn,
|
||||
rightbtn,
|
||||
backBtn;
|
||||
|
||||
$this.addClass( "ui-" + role );
|
||||
|
||||
$this
|
||||
//add theme class
|
||||
.addClass( "ui-bar-" + thisTheme )
|
||||
// Add ARIA role
|
||||
.attr( "role", role === "header" ? "banner" : "contentinfo" );
|
||||
//apply theming and markup modifications to page,header,content,footer
|
||||
if ( role === "header" || role === "footer" ) {
|
||||
var thisTheme = theme || ( role === "header" ? o.headerTheme : o.footerTheme ) || pageTheme;
|
||||
|
||||
// Right,left buttons
|
||||
$headeranchors = $this.children( "a" );
|
||||
leftbtn = $headeranchors.hasClass( "ui-btn-left" );
|
||||
rightbtn = $headeranchors.hasClass( "ui-btn-right" );
|
||||
$this
|
||||
//add theme class
|
||||
.addClass( "ui-bar-" + thisTheme )
|
||||
// Add ARIA role
|
||||
.attr( "role", role === "header" ? "banner" : "contentinfo" );
|
||||
|
||||
leftbtn = leftbtn || $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length;
|
||||
|
||||
rightbtn = rightbtn || $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length;
|
||||
|
||||
// Auto-add back btn on pages beyond first view
|
||||
if ( o.addBackBtn &&
|
||||
role === "header" &&
|
||||
$( ".ui-page" ).length > 1 &&
|
||||
$this.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) &&
|
||||
!leftbtn ) {
|
||||
// Right,left buttons
|
||||
$headeranchors = $this.children( "a" );
|
||||
leftbtn = $headeranchors.hasClass( "ui-btn-left" );
|
||||
rightbtn = $headeranchors.hasClass( "ui-btn-right" );
|
||||
|
||||
backBtn = $( "<a href='#' class='ui-btn-left' data-"+ $.mobile.ns +"rel='back' data-"+ $.mobile.ns +"icon='arrow-l'>"+ o.backBtnText +"</a>" )
|
||||
// If theme is provided, override default inheritance
|
||||
.attr( "data-"+ $.mobile.ns +"theme", o.backBtnTheme || thisTheme )
|
||||
.prependTo( $this );
|
||||
}
|
||||
leftbtn = leftbtn || $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length;
|
||||
|
||||
// Page title
|
||||
$this.children( "h1, h2, h3, h4, h5, h6" )
|
||||
.addClass( "ui-title" )
|
||||
// Regardless of h element number in src, it becomes h1 for the enhanced page
|
||||
.attr({
|
||||
"tabindex": "0",
|
||||
"role": "heading",
|
||||
"aria-level": "1"
|
||||
});
|
||||
rightbtn = rightbtn || $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length;
|
||||
|
||||
} else if ( role === "content" ) {
|
||||
if ( contentTheme ) {
|
||||
$this.addClass( "ui-body-" + ( contentTheme ) );
|
||||
}
|
||||
// Auto-add back btn on pages beyond first view
|
||||
if ( o.addBackBtn &&
|
||||
role === "header" &&
|
||||
$( ".ui-page" ).length > 1 &&
|
||||
$this.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) &&
|
||||
!leftbtn ) {
|
||||
|
||||
// Add ARIA role
|
||||
$this.attr( "role", "main" );
|
||||
}
|
||||
});
|
||||
backBtn = $( "<a href='#' class='ui-btn-left' data-"+ $.mobile.ns +"rel='back' data-"+ $.mobile.ns +"icon='arrow-l'>"+ o.backBtnText +"</a>" )
|
||||
// If theme is provided, override default inheritance
|
||||
.attr( "data-"+ $.mobile.ns +"theme", o.backBtnTheme || thisTheme )
|
||||
.prependTo( $this );
|
||||
}
|
||||
|
||||
// Page title
|
||||
$this.children( "h1, h2, h3, h4, h5, h6" )
|
||||
.addClass( "ui-title" )
|
||||
// Regardless of h element number in src, it becomes h1 for the enhanced page
|
||||
.attr({
|
||||
"tabindex": "0",
|
||||
"role": "heading",
|
||||
"aria-level": "1"
|
||||
});
|
||||
|
||||
} else if ( role === "content" ) {
|
||||
if ( contentTheme ) {
|
||||
$this.addClass( "ui-body-" + ( contentTheme ) );
|
||||
}
|
||||
|
||||
// Add ARIA role
|
||||
$this.attr( "role", "main" );
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
})( jQuery );
|
||||
$( document ).bind( "pagecreate create", function( e ) {
|
||||
$( e.target ).sections();
|
||||
});
|
||||
|
||||
})( jQuery );
|
||||
|
|
|
|||
Loading…
Reference in a new issue