JQuery 移动面板小部件 - 打开可折叠列表会导致在展开超过页面高度后跳转滚动到页面底部 div。为什么?
JQuery Mobile Panel Widget – opening collapsible lists causes jump scroll to bottom of page div once expanded beyond page height. Why?
尝试使用 JQuery Mobile (v 1.4.5) 面板小部件构建可折叠的多级菜单。我添加了一些 slideUp/Down 动画以使子菜单的打开更加明显。
<div data-role="page">
<div data-role="panel" id="mainmenu" role="navigation" data-display="overlay">
<ul data-role="listview" class="ui-listview-outer">
<li><a href="#">Home Page</a></li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 1 OF 6</h3>
<ul data-role="listview" data-theme="b">
<li><a href="#">1.1</a></li>
<li><a href="#">1.2</a></li>
<li><a href="#">1.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>List 2 OF 6</h3>
<ul data-role="listview" data-theme="c">
<li role="menuitem"><a href="#">2.1</a></li>
<li role="menuitem"><a href="#">2.2</a></li>
<li role="menuitem"><a href="#">2.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>List 3 OF 6</h3>
<ul data-role="listview">
<li><a href="#">3.1</a></li>
<li><a href="#">3.2</a></li>
<li><a href="#">3.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 4 OF 6</h3>
<ul data-role="listview">
<li><a href="#">4.1</a></li>
<li><a href="#">4.2</a></li>
<li><a href="#">4.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 5 of 6</h3>
<ul data-role="listview">
<li><a href="#">5.1</a></li>
<li><a href="#">5.2</a></li>
<li><a href="#">5.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 6 OF 6</h3>
<ul data-role="listview">
<li><a href="#">6.1</a></li>
<li><a href="#">6.2</a></li>
<li><a href="#">6.3</a></li>
<!-- etc. -->
</ul>
</li>
</ul>
</div>
<div data-role="header" class="header">
<a href="#mainmenu" data-icon="bars" data-iconpos="notext">Menu</a><h1>This is the header
</h1>
</div>
<div data-role="content" class="content">
This is the content
<br>
<br>
<br>
<br>
<!-- <br>'s etc. to increase page length for illustrative purposes -->
</div>
<div data-role="footer" class="footer">
This is the footer
</div>
</div>
问题:当菜单的高度超过页面的高度时 div(这种情况很快发生,因为最上面的子菜单很长),然后 另一个再往下是子菜单 expanded/collapsed,视口跳转,页面底部在视口底部,将新打开的子菜单推到视口下方,无疑会使用户对刚刚发生的事情感到困惑。
理想情况下,刚刚单击的子菜单保持在视图中,slideDown 动画可见并且用户了解子菜单已打开。 JQuery 似乎是根据菜单高度动态改变页面高度,这是有道理的,但是视口的突然移动……不太如此。
不管有没有幻灯片动画,该行为仍然存在,包括如下:
$(document).ready(function () {
$(document).on("collapsibleexpand", ".ui-collapsible", function (event) {
var contentDiv = $(this).children(".ui-collapsible-content");
contentDiv.hide();
contentDiv.slideDown(300);
event.stopPropagation(); // don't bubble up
});
$(document).on("collapsiblecollapse", ".ui-collapsible", function (event) {
var contentDiv = $(this).children('.ui-collapsible-content');
contentDiv.slideUp(300);
event.stopPropagation(); // don't bubble up
});
});
Working fiddle to show the issue
我远不是 JQuery/JS/JQM 专家,我在这里做的事情很可能是不推荐的(例如,我没有在面板中看到太多关于嵌套列表的内容导航)。如果是这样,我很乐意听到它。
这是我对这种导航系统的建议。恕我直言,应该有两个可滚动元素,页面内容和菜单子系统(侧面板)。
我无法完全理解你的句子“...视口跳转使得页面底部位于视口底部”但无论如何,我喜欢你的滑动子菜单的想法,所以我认为这里的难点是:如何计算将当前菜单项移动到顶部所需的滚动量。
请注意,我没有在所有情况下测试这段代码,但乍一看,它似乎没问题——至少在浏览器中是这样。
$(document).ready(function() {
$(document).on("collapsibleexpand", ".ui-collapsible", function(e) {
var self = $(this),
menu = $("#mainmenu"),
pageY = $(document).scrollTop(),
content = $(this).children(".ui-collapsible-content");
content.hide();
content.slideDown({
duration: 300,
step: function(now, fx) {
if (fx.prop == "height") {
var pct = ((100 * now) / fx.end),
itemTop = $(self).offset().top,
menuScrollTop = $(menu).scrollTop(),
amt = (itemTop - pageY) / 100 * pct;
menu.scrollTop(menuScrollTop + amt);
}
}
}
);
e.stopPropagation(); // don't bubble up
});
$(document).on("collapsiblecollapse", ".ui-collapsible", function(e) {
var content = $(this).children('.ui-collapsible-content');
content.slideUp(300);
e.stopPropagation(); // don't bubble up
});
});
.content {
text-align: center;
}
#mainmenu {
position: fixed;
overflow-y: scroll;
height: 100%;
}
.ui-page-active {
overflow-y: scroll;
min-height: 100% !important;
}
li,
ul {
padding: 0 !important;
}
h3 {
margin: 0 !important;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="panel" id="mainmenu" role="navigation" data-display="overlay">
<ul data-role="listview" class="ui-listview-outer">
<li><a href="#">Home Page</a></li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 1 OF 6</h3>
<ul data-role="listview" data-theme="b">
<li><a href="#">1.1</a></li>
<li><a href="#">1.2</a></li>
<li><a href="#">1.3</a></li>
<li><a href="#">1.4</a></li>
<li><a href="#">1.5</a></li>
<li><a href="#">1.6</a></li>
<li><a href="#">1.7</a></li>
<li><a href="#">1.8</a></li>
<li><a href="#">1.9</a></li>
<li><a href="#">1.10</a></li>
<li><a href="#">1.11</a></li>
<li><a href="#">1.12</a></li>
<li><a href="#">1.13</a></li>
<li><a href="#">1.14</a></li>
<li><a href="#">1.15</a></li>
<li><a href="#">1.16</a></li>
<li><a href="#">1.17</a></li>
<li><a href="#">1.18</a></li>
<li><a href="#">1.19</a></li>
<li><a href="#">1.20</a></li>
<li><a href="#">1.21</a></li>
<li><a href="#">1.22</a></li>
<li><a href="#">1.23</a></li>
<li><a href="#">1.24</a></li>
<li><a href="#">1.25</a></li>
<li><a href="#">1.26</a></li>
<li><a href="#">1.27</a></li>
<li><a href="#">1.28</a></li>
<li><a href="#">1.29</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>List 2 OF 6</h3>
<ul data-role="listview" data-theme="c">
<li><a href="#">2.1</a></li>
<li><a href="#">2.2</a></li>
<li><a href="#">2.3</a></li>
<li><a href="#">2.4</a></li>
<li><a href="#">2.5</a></li>
<li><a href="#">2.6</a></li>
<li><a href="#">2.7</a></li>
<li><a href="#">2.8</a></li>
<li><a href="#">2.9</a></li>
<li><a href="#">2.10</a></li>
<li><a href="#">2.11</a></li>
<li><a href="#">2.12</a></li>
<li><a href="#">2.13</a></li>
<li><a href="#">2.14</a></li>
<li><a href="#">2.15</a></li>
<li><a href="#">2.16</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>List 3 OF 6</h3>
<ul data-role="listview">
<li><a href="#">3.1</a></li>
<li><a href="#">3.2</a></li>
<li><a href="#">3.3</a></li>
<li><a href="#">3.4</a></li>
<li><a href="#">3.5</a></li>
<li><a href="#">3.6</a></li>
<li><a href="#">3.7</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 4 OF 6</h3>
<ul data-role="listview">
<li><a href="#">4.1</a></li>
<li><a href="#">4.2</a></li>
<li><a href="#">4.3</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 5 of 6</h3>
<ul data-role="listview">
<li><a href="#">5.1</a></li>
<li><a href="#">5.2</a></li>
<li><a href="#">5.3</a></li>
<li><a href="#">5.4</a></li>
<li><a href="#">5.5</a></li>
<li><a href="#">5.6</a></li>
<li><a href="#">5.7</a></li>
<li><a href="#">5.8</a></li>
<li><a href="#">5.9</a></li>
<li><a href="#">5.10</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 6 OF 6</h3>
<ul data-role="listview">
<li><a href="#">6.1</a></li>
<li><a href="#">6.2</a></li>
<li><a href="#">6.3</a></li>
<li><a href="#">6.4</a></li>
<li><a href="#">6.5</a></li>
<li><a href="#">6.6</a></li>
<li><a href="#">6.7</a></li>
<li><a href="#">6.8</a></li>
<li><a href="#">6.9</a></li>
<li><a href="#">6.10</a></li>
</ul>
</li>
</ul>
</div>
<div data-role="header" class="header">
<a href="#mainmenu" data-icon="bars" data-iconpos="notext">Menu</a>
<h1>This is the header</h1>
</div>
<div data-role="content" class="content">
This is the content
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
<div data-role="footer" class="footer">
<h1>This is the footer</h1>
</div>
</div>
</body>
</html>
请在您所有可用的设备上测试上述方法并给我反馈。
尝试使用 JQuery Mobile (v 1.4.5) 面板小部件构建可折叠的多级菜单。我添加了一些 slideUp/Down 动画以使子菜单的打开更加明显。
<div data-role="page">
<div data-role="panel" id="mainmenu" role="navigation" data-display="overlay">
<ul data-role="listview" class="ui-listview-outer">
<li><a href="#">Home Page</a></li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 1 OF 6</h3>
<ul data-role="listview" data-theme="b">
<li><a href="#">1.1</a></li>
<li><a href="#">1.2</a></li>
<li><a href="#">1.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>List 2 OF 6</h3>
<ul data-role="listview" data-theme="c">
<li role="menuitem"><a href="#">2.1</a></li>
<li role="menuitem"><a href="#">2.2</a></li>
<li role="menuitem"><a href="#">2.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>List 3 OF 6</h3>
<ul data-role="listview">
<li><a href="#">3.1</a></li>
<li><a href="#">3.2</a></li>
<li><a href="#">3.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 4 OF 6</h3>
<ul data-role="listview">
<li><a href="#">4.1</a></li>
<li><a href="#">4.2</a></li>
<li><a href="#">4.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 5 of 6</h3>
<ul data-role="listview">
<li><a href="#">5.1</a></li>
<li><a href="#">5.2</a></li>
<li><a href="#">5.3</a></li>
<!-- etc. -->
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 6 OF 6</h3>
<ul data-role="listview">
<li><a href="#">6.1</a></li>
<li><a href="#">6.2</a></li>
<li><a href="#">6.3</a></li>
<!-- etc. -->
</ul>
</li>
</ul>
</div>
<div data-role="header" class="header">
<a href="#mainmenu" data-icon="bars" data-iconpos="notext">Menu</a><h1>This is the header
</h1>
</div>
<div data-role="content" class="content">
This is the content
<br>
<br>
<br>
<br>
<!-- <br>'s etc. to increase page length for illustrative purposes -->
</div>
<div data-role="footer" class="footer">
This is the footer
</div>
</div>
问题:当菜单的高度超过页面的高度时 div(这种情况很快发生,因为最上面的子菜单很长),然后 另一个再往下是子菜单 expanded/collapsed,视口跳转,页面底部在视口底部,将新打开的子菜单推到视口下方,无疑会使用户对刚刚发生的事情感到困惑。
理想情况下,刚刚单击的子菜单保持在视图中,slideDown 动画可见并且用户了解子菜单已打开。 JQuery 似乎是根据菜单高度动态改变页面高度,这是有道理的,但是视口的突然移动……不太如此。
不管有没有幻灯片动画,该行为仍然存在,包括如下:
$(document).ready(function () {
$(document).on("collapsibleexpand", ".ui-collapsible", function (event) {
var contentDiv = $(this).children(".ui-collapsible-content");
contentDiv.hide();
contentDiv.slideDown(300);
event.stopPropagation(); // don't bubble up
});
$(document).on("collapsiblecollapse", ".ui-collapsible", function (event) {
var contentDiv = $(this).children('.ui-collapsible-content');
contentDiv.slideUp(300);
event.stopPropagation(); // don't bubble up
});
});
Working fiddle to show the issue
我远不是 JQuery/JS/JQM 专家,我在这里做的事情很可能是不推荐的(例如,我没有在面板中看到太多关于嵌套列表的内容导航)。如果是这样,我很乐意听到它。
这是我对这种导航系统的建议。恕我直言,应该有两个可滚动元素,页面内容和菜单子系统(侧面板)。
我无法完全理解你的句子“...视口跳转使得页面底部位于视口底部”但无论如何,我喜欢你的滑动子菜单的想法,所以我认为这里的难点是:如何计算将当前菜单项移动到顶部所需的滚动量。
请注意,我没有在所有情况下测试这段代码,但乍一看,它似乎没问题——至少在浏览器中是这样。
$(document).ready(function() {
$(document).on("collapsibleexpand", ".ui-collapsible", function(e) {
var self = $(this),
menu = $("#mainmenu"),
pageY = $(document).scrollTop(),
content = $(this).children(".ui-collapsible-content");
content.hide();
content.slideDown({
duration: 300,
step: function(now, fx) {
if (fx.prop == "height") {
var pct = ((100 * now) / fx.end),
itemTop = $(self).offset().top,
menuScrollTop = $(menu).scrollTop(),
amt = (itemTop - pageY) / 100 * pct;
menu.scrollTop(menuScrollTop + amt);
}
}
}
);
e.stopPropagation(); // don't bubble up
});
$(document).on("collapsiblecollapse", ".ui-collapsible", function(e) {
var content = $(this).children('.ui-collapsible-content');
content.slideUp(300);
e.stopPropagation(); // don't bubble up
});
});
.content {
text-align: center;
}
#mainmenu {
position: fixed;
overflow-y: scroll;
height: 100%;
}
.ui-page-active {
overflow-y: scroll;
min-height: 100% !important;
}
li,
ul {
padding: 0 !important;
}
h3 {
margin: 0 !important;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="panel" id="mainmenu" role="navigation" data-display="overlay">
<ul data-role="listview" class="ui-listview-outer">
<li><a href="#">Home Page</a></li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 1 OF 6</h3>
<ul data-role="listview" data-theme="b">
<li><a href="#">1.1</a></li>
<li><a href="#">1.2</a></li>
<li><a href="#">1.3</a></li>
<li><a href="#">1.4</a></li>
<li><a href="#">1.5</a></li>
<li><a href="#">1.6</a></li>
<li><a href="#">1.7</a></li>
<li><a href="#">1.8</a></li>
<li><a href="#">1.9</a></li>
<li><a href="#">1.10</a></li>
<li><a href="#">1.11</a></li>
<li><a href="#">1.12</a></li>
<li><a href="#">1.13</a></li>
<li><a href="#">1.14</a></li>
<li><a href="#">1.15</a></li>
<li><a href="#">1.16</a></li>
<li><a href="#">1.17</a></li>
<li><a href="#">1.18</a></li>
<li><a href="#">1.19</a></li>
<li><a href="#">1.20</a></li>
<li><a href="#">1.21</a></li>
<li><a href="#">1.22</a></li>
<li><a href="#">1.23</a></li>
<li><a href="#">1.24</a></li>
<li><a href="#">1.25</a></li>
<li><a href="#">1.26</a></li>
<li><a href="#">1.27</a></li>
<li><a href="#">1.28</a></li>
<li><a href="#">1.29</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>List 2 OF 6</h3>
<ul data-role="listview" data-theme="c">
<li><a href="#">2.1</a></li>
<li><a href="#">2.2</a></li>
<li><a href="#">2.3</a></li>
<li><a href="#">2.4</a></li>
<li><a href="#">2.5</a></li>
<li><a href="#">2.6</a></li>
<li><a href="#">2.7</a></li>
<li><a href="#">2.8</a></li>
<li><a href="#">2.9</a></li>
<li><a href="#">2.10</a></li>
<li><a href="#">2.11</a></li>
<li><a href="#">2.12</a></li>
<li><a href="#">2.13</a></li>
<li><a href="#">2.14</a></li>
<li><a href="#">2.15</a></li>
<li><a href="#">2.16</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>List 3 OF 6</h3>
<ul data-role="listview">
<li><a href="#">3.1</a></li>
<li><a href="#">3.2</a></li>
<li><a href="#">3.3</a></li>
<li><a href="#">3.4</a></li>
<li><a href="#">3.5</a></li>
<li><a href="#">3.6</a></li>
<li><a href="#">3.7</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 4 OF 6</h3>
<ul data-role="listview">
<li><a href="#">4.1</a></li>
<li><a href="#">4.2</a></li>
<li><a href="#">4.3</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 5 of 6</h3>
<ul data-role="listview">
<li><a href="#">5.1</a></li>
<li><a href="#">5.2</a></li>
<li><a href="#">5.3</a></li>
<li><a href="#">5.4</a></li>
<li><a href="#">5.5</a></li>
<li><a href="#">5.6</a></li>
<li><a href="#">5.7</a></li>
<li><a href="#">5.8</a></li>
<li><a href="#">5.9</a></li>
<li><a href="#">5.10</a></li>
</ul>
</li>
<li data-role="collapsible" data-inset="false">
<h3>LIST 6 OF 6</h3>
<ul data-role="listview">
<li><a href="#">6.1</a></li>
<li><a href="#">6.2</a></li>
<li><a href="#">6.3</a></li>
<li><a href="#">6.4</a></li>
<li><a href="#">6.5</a></li>
<li><a href="#">6.6</a></li>
<li><a href="#">6.7</a></li>
<li><a href="#">6.8</a></li>
<li><a href="#">6.9</a></li>
<li><a href="#">6.10</a></li>
</ul>
</li>
</ul>
</div>
<div data-role="header" class="header">
<a href="#mainmenu" data-icon="bars" data-iconpos="notext">Menu</a>
<h1>This is the header</h1>
</div>
<div data-role="content" class="content">
This is the content
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
<div data-role="footer" class="footer">
<h1>This is the footer</h1>
</div>
</div>
</body>
</html>
请在您所有可用的设备上测试上述方法并给我反馈。