html - 单击元素时如何实现popover的相同位置
问题描述
我正在使用一个monthpicker,它完全建立在bootstrap 和popover 之上。我在我的一个 MVC 项目中使用了这个控件。
当我尝试将其集成到纯基于 html 和 css 的 asp.net 项目中时,发现它不支持 popover。我收到控制台错误:未定义弹出框。由于它使用引导程序,因此我当前的设计也受到了影响。
我尝试了所有方法来修复它,但它们都不起作用,最后我决定喜欢用于弹出窗口的任何 html 和 css,我将在 asp.net 应用程序中使用同样的方法。我做了同样的事情,现在我能够实现与月份选择器控制相同的外观和感觉。
但唯一的问题是单击元素时弹出框的位置。
我的期望就像一旦用户点击元素,月份选择器弹出窗口应该显示在它的正下方。对于某些菜单,此元素位置也在发生变化,因此我无法在此处对顶部和左侧值进行硬编码。
我尝试了如下方法:
$('#sla-data-range').click(function (e) {
var dateControl = $(e.target);
var offset = dateControl.offset();
var relativeTop = (e.pageY - offset.top);
var relativeLeft = (e.pageX - offset.left);
$('#popover836038').offset({ top: relativeTop, left: relativeLeft }).fadeIn();
var waiter = setInterval(function () {
$("#mprMonthContent").append(content);
//Other codes to fill the months based on business requirement.
}, 50);
});
下面是完整的 html,您可以将其复制并粘贴到一些 html 文件中并运行以调试问题。
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Bootstrap Month Range Picker</title>
<!-- <link rel='stylesheet' href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/themes/smoothness/jquery-ui.css'> -->
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css'>
<style type="text/css">
.mrp-container{
margin-top:10px;
}
.mrp-icon{
border: solid 1px #ddd;
border-radius: 7px 0px 0px 5px;
color: #40667A;
background: #eee;
padding: 7px;
margin-right:0px;
}
.mrp-monthdisplay{
display:inline-block!important;
border: solid 1px #ddd;
padding: 5px 12px 5px 8px;
border-radius: 0px 5px 5px 0px;
background-color: #fff;
cursor:pointer;
margin-left: -5px;
}
.mrp-lowerMonth, .mrp-upperMonth{
color: #40667A;
font-weight:bold;
font-size: 11px;
text-transform:uppercase;
}
.mrp-to{
color: #aaa;
margin-right: 0px;
margin-left: 0px;
font-size: 11px;
text-transform: uppercase;
/* background-color: #eee; */
padding: 5px 3px 5px 3px;
}
.mpr-calendar{
display:inline-block;
padding: 3px 5px;
border-right: solid #999 1px;
}
.mpr-calendar::last-child{
border-right: none;
}
.mpr-month{
padding: 20px;
text-transform: uppercase;
font-size: 12px;
}
.mpr-calendar h5{
width:100%;
text-align:center;
font-weight:bold;
font-size:18px
}
.mpr-selected{
background: rgba(64, 102, 122, 0.75);;
color: #fff;
}
.mpr-month:hover{
border-radius: 5px;
box-shadow: 0 0 0 1px #ddd inset;
cursor:pointer;
}
.mpr-selected.mpr-month:hover{
border-radius: 0px;
box-shadow: none;
}
.mpr-calendarholder .col-xs-6 {
max-width: 250px;
min-width: 250px;
}
.mpr-calendarholder .col-xs-1 {
max-width: 150px;
min-width: 150px;
}
.mpr-calendarholder .btn-info{
background-color: #40667A;
border-color: #406670;
width:100%;
margin-bottom: 10px;
text-transform: uppercase;
font-size: 10px;
padding: 10px 0px;
}
.mpr-quickset{
color: #666;
text-transform: uppercase;
text-align: center;
}
.mpr-yeardown, .mpr-yearup{
margin-left: 5px;
cursor: pointer;
color: #666;
}
.mpr-yeardown{
float:left;
}
.mpr-yearup{
float:right;
}
.mpr-yeardown:hover,.mpr-yearup:hover{
color: #40667A;
}
.mpr-calendar:first .mpr-selected:first{
background-color: #40667A;
}
.mpr-calendar:last .mpr-selected:last{
background-color: #40667A;
}
.popover{
max-width: 1920px!important;
}
.mrp-disablemonth{
opacity:0.2;
pointer-events:none;
}
.popover-content {
padding: 0px 14px;
}
.row {
margin-right: -15px;
margin-left: -15px;
}
.col-xs-3 {
width: 25%;
float: left;
position: relative;
min-height: 1px;
}
.popover.bottom {
margin-top: 10px;
}
.fade.in {
opacity: 1;
}
.popover {
max-width: 1920px!important;
}
.search-holder * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.popover {
position: absolute;
top: 0;
left: 0;
z-index: 1060;
display: none;
max-width: 276px;
padding: 1px;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: left;
white-space: normal;
background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.2);
border-radius: 6px;
-webkit-box-shadow: 0 5px 10px rgb(0 0 0 / 20%);
box-shadow: 0 5px 10px rgb(0 0 0 / 20%);
}
.popover.bottom>.arrow {
top: -11px;
margin-left: -11px;
border-top-width: 0;
border-bottom-color: #999;
border-bottom-color: rgba(0,0,0,.25);
}
.popover>.arrow {
border-width: 11px;
}
.popover>.arrow:after {
content: "";
border-width: 10px;
}
.popover>.arrow, .popover>.arrow:after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.popover.bottom>.arrow:after {
top: 1px;
margin-left: -10px;
content: " ";
border-top-width: 0;
border-bottom-color: #fff;
}
.col-xs-6 {
width: 50%;
float:left;
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
.col-xs-12{
float: left;
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
h5{
font-family: inherit;
font-weight: 500;
line-height: 1.0;
color: inherit;
}
.row:after, .row:before {
display: table;
content: " ";
}
.row:after {
clear: both;
}
:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
button, select {
text-transform: none;
}
button {
overflow: visible;
}
button, input, optgroup, select, textarea {
margin: 0;
font: inherit;
color: inherit;
}
table {
border-collapse: separate;
text-indent: initial;
border-spacing: 2px;
}
</style>
</head>
<body>
<table width="100%">
<tr>
<td width="50%"></td>
<td width="50%">
<div id="sla-data-range" class="mrp-container">
<span class="mrp-icon"><i class="fa fa-calendar"></i></span>
<div class="mrp-monthdisplay" style="width:160px">
<span class="mrp-lowerMonth"></span>
<span class="mrp-to"> - </span>
<span class="mrp-upperMonth"></span>
</div>
<input type="hidden" value="" id="mrp-lowerDate" />
<input type="hidden" value="" id="mrp-upperDate" />
</div>
<div class="popover fade bottom in" role="tooltip" id="popover836038" style="display: none">
<div class="arrow" style="left: 50%;"></div>
<h3 class="popover-title" style="display: none;"></h3>
<div id="mprMonthContent" class="popover-content">
<div class="row mpr-calendarholder"><div class="col-xs-6"><div class="mpr-calendar row" id="mpr-calendar-1"><h5 class="col-xs-12"><i class="mpr-yeardown fa fa-chevron-circle-left"></i><span>2020</span><i class="mpr-yearup fa fa-chevron-circle-right" style="display: none;"></i></h5><div class="mpr-monthsContainer"><div class="mpr-MonthsWrapper"><span data-month="01" class="col-xs-3 mpr-month">Jan</span><span data-month="02" class="col-xs-3 mpr-month">Feb</span><span data-month="03" class="col-xs-3 mpr-month">Mar</span><span data-month="04" class="col-xs-3 mpr-month">Apr</span><span data-month="05" class="col-xs-3 mpr-month">May</span><span data-month="06" class="col-xs-3 mpr-month">Jun</span><span data-month="07" class="col-xs-3 mpr-month mpr-selected" style="background: rgb(64, 102, 122);">Jul</span><span data-month="08" class="col-xs-3 mpr-month mpr-selected">Aug</span><span data-month="09" class="col-xs-3 mpr-month mpr-selected">Sep</span><span data-month="10" class="col-xs-3 mpr-month mpr-selected">Oct</span><span data-month="11" class="col-xs-3 mpr-month mpr-selected">Nov</span><span data-month="12" class="col-xs-3 mpr-month mpr-selected" style="background: rgb(64, 102, 122);">Dec</span></div></div></div></div><div class="col-xs-6"><div class="mpr-calendar row" id="mpr-calendar-2" style="border: none;"><h5 class="col-xs-12"><i class="mpr-yeardown fa fa-chevron-circle-left" style="display: none;"></i><span>2021</span><i class="mpr-yearup fa fa-chevron-circle-right" style="display: none;"></i></h5><div class="mpr-monthsContainer"><div class="mpr-MonthsWrapper"><span data-month="01" class="col-xs-3 mpr-month">Jan</span><span data-month="02" class="col-xs-3 mpr-month">Feb</span><span data-month="03" class="col-xs-3 mpr-month">Mar</span><span data-month="04" class="col-xs-3 mpr-month">Apr</span><span data-month="05" class="col-xs-3 mpr-month">May</span><span data-month="06" class="col-xs-3 mpr-month">Jun</span><span data-month="07" class="col-xs-3 mpr-month mrp-disablemonth">Jul</span><span data-month="08" class="col-xs-3 mpr-month mrp-disablemonth">Aug</span><span data-month="09" class="col-xs-3 mpr-month mrp-disablemonth">Sep</span><span data-month="10" class="col-xs-3 mpr-month mrp-disablemonth">Oct</span><span data-month="11" class="col-xs-3 mpr-month mrp-disablemonth">Nov</span><span data-month="12" class="col-xs-3 mpr-month mrp-disablemonth">Dec</span></div></div></div></div><div style="width:100%; text-align:center"><button type="button" id="btnClear" class="btn btn-primary">Clear</button></div></div></div>
</div>
</td>
</tr>
</table>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script type="text/javascript">
$(function () {
$('#sla-data-range').click(function (e) {
var dateControl = $(e.target);
var offset = dateControl.offset();
var relativeTop = (e.pageY - offset.top);
var relativeLeft = (e.pageX - offset.left);
$('#popover836038').offset({ top: relativeTop, left: relativeLeft }).fadeIn();
});
$(document).on('click', function (e) {
if ($(e.target).closest("#sla-data-range").length === 0) {
$("#popover836038").offset({ left: 0, top: 0 }).css({
'display': 'none'
});
}
})
});
</script>
</body>
</html>
使用上面之后它有点对齐但不多。
从戴尔兰德里得到解决方案后,它仍然没有对齐。以下是相同的屏幕截图。 请提出一些解决方案,因此它应该始终填充在单击元素的正下方。
解决方案
您可以将JS 中的弹出框偏移量设置为, 这$(this).position()
基本上是#sla-data-range
元素。从那里进行一点按摩,将其直接放置在您想要的位置。
我刚刚调整了JQuery偏移函数中的左侧和顶部 位置
重要说明--> 小心使用在 Javascript 和/或 Javascript 库(如 JQuery 等)中保留的变量名 -->偏移量
$('#popover836038').offset({
top: $(this).position().top + 30,
left: e.pageX - $('.popover').width() / 2
}).fadeIn()
e.pageX ==> 点击鼠标x位置 -弹出框 宽度除以 2,这将使弹出框居中@您点击的位置。
$(function() {
$('#sla-data-range').click(function(e) {
const dateControl = $(e.target)
// Naming a variable offset -->
// !!!CAREFUL DEFINING A VARIABLE A RESERVED NAME IN JQUERY LIBRARY
const offset = dateControl.offset()
let relativeTop = (e.pageY - offset.top)
let relativeLeft = (e.pageX - offset.left)
$('#popover836038').offset({
top: $(this).position().top + 30,
left: e.pageX - $('.popover').width() / 2
}).fadeIn()
})
$(document).on('click', function(e) {
if ($(e.target).closest("#sla-data-range").length === 0) {
$("#popover836038").offset({
left: 0,
top: 0
}).css({
'display': 'none'
})
}
})
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.mrp-container {
margin-top: 10px;
}
.mrp-icon {
border: solid 1px #ddd;
border-radius: 7px 0px 0px 5px;
color: #40667A;
background: #eee;
padding: 7px;
margin-right: 0px;
}
.mrp-monthdisplay {
display: inline-block!important;
border: solid 1px #ddd;
padding: 5px 12px 5px 8px;
border-radius: 0px 5px 5px 0px;
background-color: #fff;
cursor: pointer;
margin-left: -5px;
}
.mrp-lowerMonth,
.mrp-upperMonth {
color: #40667A;
font-weight: bold;
font-size: 11px;
text-transform: uppercase;
}
.mrp-to {
color: #aaa;
margin-right: 0px;
margin-left: 0px;
font-size: 11px;
text-transform: uppercase;
/* background-color: #eee; */
padding: 5px 3px 5px 3px;
}
.mpr-calendar {
display: inline-block;
padding: 3px 5px;
border-right: solid #999 1px;
}
.mpr-calendar::last-child {
border-right: none;
}
.mpr-month {
padding: 20px;
text-transform: uppercase;
font-size: 12px;
}
.mpr-calendar h5 {
width: 100%;
text-align: center;
font-weight: bold;
font-size: 18px
}
.mpr-selected {
background: rgba(64, 102, 122, 0.75);
;
color: #fff;
}
.mpr-month:hover {
border-radius: 5px;
box-shadow: 0 0 0 1px #ddd inset;
cursor: pointer;
}
.mpr-selected.mpr-month:hover {
border-radius: 0px;
box-shadow: none;
}
.mpr-calendarholder .col-xs-6 {
max-width: 250px;
min-width: 250px;
}
.mpr-calendarholder .col-xs-1 {
max-width: 150px;
min-width: 150px;
}
.mpr-calendarholder .btn-info {
background-color: #40667A;
border-color: #406670;
width: 100%;
margin-bottom: 10px;
text-transform: uppercase;
font-size: 10px;
padding: 10px 0px;
}
.mpr-quickset {
color: #666;
text-transform: uppercase;
text-align: center;
}
.mpr-yeardown,
.mpr-yearup {
margin-left: 5px;
cursor: pointer;
color: #666;
}
.mpr-yeardown {
float: left;
}
.mpr-yearup {
float: right;
}
.mpr-yeardown:hover,
.mpr-yearup:hover {
color: #40667A;
}
.mpr-calendar:first .mpr-selected:first {
background-color: #40667A;
}
.mpr-calendar:last .mpr-selected:last {
background-color: #40667A;
}
.popover {
max-width: 1920px!important;
}
.mrp-disablemonth {
opacity: 0.2;
pointer-events: none;
}
.popover-content {
padding: 0px 14px;
}
.row {
margin-right: -15px;
margin-left: -15px;
}
.col-xs-3 {
width: 25%;
float: left;
position: relative;
min-height: 1px;
}
.popover.bottom {
margin-top: 10px;
}
.fade.in {
opacity: 1;
}
.popover {
max-width: 1920px!important;
}
.search-holder * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.popover {
position: absolute;
top: 0;
left: 0;
z-index: 1060;
display: none;
max-width: 276px;
padding: 1px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: left;
white-space: normal;
background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 6px;
-webkit-box-shadow: 0 5px 10px rgb(0 0 0 / 20%);
box-shadow: 0 5px 10px rgb(0 0 0 / 20%);
}
.popover.bottom>.arrow {
top: -11px;
margin-left: -11px;
border-top-width: 0;
border-bottom-color: #999;
border-bottom-color: rgba(0, 0, 0, .25);
}
.popover>.arrow {
border-width: 11px;
}
.popover>.arrow:after {
content: "";
border-width: 10px;
}
.popover>.arrow,
.popover>.arrow:after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.popover.bottom>.arrow:after {
top: 1px;
margin-left: -10px;
content: " ";
border-top-width: 0;
border-bottom-color: #fff;
}
.col-xs-6 {
width: 50%;
float: left;
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
.col-xs-12 {
float: left;
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
h5 {
font-family: inherit;
font-weight: 500;
line-height: 1.0;
color: inherit;
}
.row:after,
.row:before {
display: table;
content: " ";
}
.row:after {
clear: both;
}
:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
button,
select {
text-transform: none;
}
button {
overflow: visible;
}
button,
input,
optgroup,
select,
textarea {
margin: 0;
font: inherit;
color: inherit;
}
table {
border-collapse: separate;
text-indent: initial;
border-spacing: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CodePen - Bootstrap Month Range Picker</title>
<!-- <link rel='stylesheet' href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/themes/smoothness/jquery-ui.css'> -->
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css'>
</head>
<body>
<table width="100%">
<tr>
<td width="50%"></td>
<td width="50%" class="parent">
<div id="sla-data-range" class="mrp-container">
<span class="mrp-icon"><i class="fa fa-calendar"></i></span>
<div class="mrp-monthdisplay" style="width:160px">
<span class="mrp-lowerMonth"></span>
<span class="mrp-to"> - </span>
<span class="mrp-upperMonth"></span>
</div>
<input type="hidden" value="" id="mrp-lowerDate" />
<input type="hidden" value="" id="mrp-upperDate" />
</div>
<div class="popover fade bottom in" role="tooltip" id="popover836038" style="display: none">
<div class="arrow" style="left: 50%;"></div>
<h3 class="popover-title" style="display: none;"></h3>
<div id="mprMonthContent" class="popover-content">
<div class="row mpr-calendarholder">
<div class="col-xs-6">
<div class="mpr-calendar row" id="mpr-calendar-1">
<h5 class="col-xs-12"><i class="mpr-yeardown fa fa-chevron-circle-left"></i><span>2020</span><i class="mpr-yearup fa fa-chevron-circle-right" style="display: none;"></i></h5>
<div class="mpr-monthsContainer">
<div class="mpr-MonthsWrapper"><span data-month="01" class="col-xs-3 mpr-month">Jan</span><span data-month="02" class="col-xs-3 mpr-month">Feb</span><span data-month="03" class="col-xs-3 mpr-month">Mar</span><span data-month="04" class="col-xs-3 mpr-month">Apr</span>
<span data-month="05" class="col-xs-3 mpr-month">May</span><span data-month="06" class="col-xs-3 mpr-month">Jun</span><span data-month="07" class="col-xs-3 mpr-month mpr-selected" style="background: rgb(64, 102, 122);">Jul</span>
<span data-month="08" class="col-xs-3 mpr-month mpr-selected">Aug</span>
<span data-month="09" class="col-xs-3 mpr-month mpr-selected">Sep</span><span data-month="10" class="col-xs-3 mpr-month mpr-selected">Oct</span><span data-month="11" class="col-xs-3 mpr-month mpr-selected">Nov</span><span data-month="12"
class="col-xs-3 mpr-month mpr-selected" style="background: rgb(64, 102, 122);">Dec</span></div>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="mpr-calendar row" id="mpr-calendar-2" style="border: none;">
<h5 class="col-xs-12"><i class="mpr-yeardown fa fa-chevron-circle-left" style="display: none;"></i><span>2021</span><i class="mpr-yearup fa fa-chevron-circle-right" style="display: none;"></i></h5>
<div class="mpr-monthsContainer">
<div class="mpr-MonthsWrapper"><span data-month="01" class="col-xs-3 mpr-month">Jan</span><span data-month="02" class="col-xs-3 mpr-month">Feb</span><span data-month="03" class="col-xs-3 mpr-month">Mar</span><span data-month="04" class="col-xs-3 mpr-month">Apr</span>
<span data-month="05" class="col-xs-3 mpr-month">May</span><span data-month="06" class="col-xs-3 mpr-month">Jun</span><span data-month="07" class="col-xs-3 mpr-month mrp-disablemonth">Jul</span><span data-month="08" class="col-xs-3 mpr-month mrp-disablemonth">Aug</span>
<span data-month="09" class="col-xs-3 mpr-month mrp-disablemonth">Sep</span><span data-month="10" class="col-xs-3 mpr-month mrp-disablemonth">Oct</span><span data-month="11" class="col-xs-3 mpr-month mrp-disablemonth">Nov</span>
<span
data-month="12" class="col-xs-3 mpr-month mrp-disablemonth">Dec</span>
</div>
</div>
</div>
</div>
<div style="width:100%; text-align:center"><button type="button" id="btnClear" class="btn btn-primary">Clear</button></div>
</div>
</div>
</div>
</td>
</tr>
</table>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
</body>
</html>
推荐阅读
- apache - 如何生成 SSLCertificateChainFile、SSLCertificateFile、SSLCertificateKeyFile?
- php - GoDaddy 发送电子邮件的 PHPMailer 设置应该是什么?
- php - 无法在 apache 2.4.38 上执行 php 7.3
- r - 在 R 中计算置信区间
- list - 在 TiddlyWiki (5) 中,我的宏在 tiddlers 中有效,除了作为侧边栏出现时
- c# - 如何修复\更新 SharePoint 2013 中列表中的默认值
- jquery - 如何将画布图像存储到mysql并使用nodejs检索它
- javascript - 如何处理[.map不是函数]
- angularjs - 编译 AngularJS 页面并移除 ng-* 指令
- scala - toSeq.toDS() 给出 java.lang.NullPointerException