我有一堆包含文字的水平框。这些盒子都在一个水平滚动的容器中:
link: function (scope, elem, attrs, ctrl) {
var autocomplete;
var aaa=document.getElementById('address');
function initializeGoogleMaps() {
autocomplete = new google.maps.places.Autocomplete(
(aaa), {
types: ['geocode']
});
scope.$on('$destroy', function () {
$(".pac-container").remove();
autocomplete=null;
});
}
initializeGoogleMaps();
// some other code

// generate some random data
var model = {
leftEdge: ko.observable(0)
};
model.rows = populateArray(10 + randInt(20), randRow);
ko.applyBindings(model);
$(function() {
$('.slide').on('scroll', function() {
model.leftEdge(this.scrollLeft);
})
})
function randRow() {
var events = populateArray(50 + randInt(100), randEvent);
var left = randInt(1000);
events.forEach(function(event) {
event.left = left;
left += 10 + event.width + randInt(1000);
});
return {
events: events
}
}
function randEvent() {
var word = randWord()
var width = 50 + Math.max(8 * word.length, randInt(200));
var event = {
left: 0,
width: width,
label: word
};
event.offset = ko.computed(function() {
// reposition the text to stay
// * within its container
// * fully on-screen (if possible)
var leftEdge = model.leftEdge();
return Math.max(0, Math.min(
leftEdge - event.left,
event.width - 8 * event.label.length
));
});
return event;
}
function randWord() {
var n = 2 + randInt(5);
var ret = "";
while (n-- > 0) {
ret += randElt("rmhntsk");
ret += randElt("aeiou");
}
return ret;
}
function randElt(arr) {
return arr[randInt(arr.length)];
}
function populateArray(n, populate) {
var arr = new Array(n);
for (var i = 0; i < n; i++) {
arr[i] = populate();
}
return arr;
}
function randInt(n) {
return Math.floor(Math.random() * n);
}
&#13;
.slide {
max-width: 100%;
overflow: auto;
border: 5px solid black;
}
.row {
position: relative;
height: 25px;
}
.event {
position: absolute;
top: 2.5px;
border: 1px solid black;
padding: 2px;
background: #cdffff;
font-size: 14px;
font-family: monospace;
}
.event > span {
position: relative;
}
&#13;
我想做的是当用户从左向右滚动时,重新定位每个框中与可见窗口的左边界部分重叠的文本,以使文本尽可能可见。 / p>
目前,我通过手动重新定位每个文字项目来做到这一点。
使用CSS有更清晰的方法吗?
答案 0 :(得分:1)
一位朋友帮我提出了这个解决方案。
在英语中,我们的想法是为每个相对于滚动框框架而不是内容的行添加叠加层。
然后我们可以为在此叠加层中与左边缘重叠的任何框放置标签,当它下方的框滚动时,它将显示为平滑移动。
// generate some random data
var model = {
leftEdge: ko.observable(0),
};
model.rows = populateArray(10 + randInt(20), randRow);
model.width = Math.max.apply(Math, $.map(model.rows, function(row) {
return row.width
}));
ko.applyBindings(model);
$(function() {
$('.slide').on('scroll', function() {
model.leftEdge(this.scrollLeft);
})
})
function randRow() {
var events = populateArray(50 + randInt(100), randEvent);
var left = randInt(1000);
events.forEach(function(event) {
event.left = left;
left += 10 + event.width + randInt(1000);
});
return {
events: events,
width: left
}
}
function randEvent() {
var word = randWord()
var width = 50 + Math.max(8 * word.length, randInt(200));
var event = {
width: width,
label: word,
};
event.tense = ko.computed(function() {
// reposition the text to stay#
// * within its container
// * fully on-screen (if possible)
var leftEdge = model.leftEdge();
return ['future', 'present', 'past'][
(leftEdge >= event.left) +
(leftEdge > event.left + event.width - 8 * event.label.length)
];
});
return event;
}
function randWord() {
var n = 2 + randInt(5);
var ret = "";
while (n-- > 0) {
ret += randElt("rmhntsk");
ret += randElt("aeiou");
}
return ret;
}
function randElt(arr) {
return arr[randInt(arr.length)];
}
function populateArray(n, populate) {
var arr = new Array(n);
for (var i = 0; i < n; i++) {
arr[i] = populate();
}
return arr;
}
function randInt(n) {
return Math.floor(Math.random() * n);
}
.wrapper {
position: relative;
border: 5px solid black;
font-size: 14px;
font-family: monospace;
}
.slide {
max-width: 100%;
overflow: auto;
}
.slide > * {
height: 25px;
}
.overlay {
position: absolute;
width: 100%;
left: 0;
}
.overlay .past {
display: none
}
.overlay .present {
position: absolute;
z-index: 1;
top: 5.5px;
left 0;
}
.overlay .future {
display: none
}
.row {
position: relative;
}
.event {
position: absolute;
top: 2.5px;
border: 1px solid black;
padding: 2px;
background: #cdffff;
height: 14px;
}
.event .past {
float: right;
}
.event .present {
display: none;
}
.event .future {
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="wrapper">
<div class="slide" data-bind="foreach: rows, style: { width: width + 'px' }">
<div class="overlay" data-bind="foreach: events">
<span data-bind="text:label, css: tense"></span>
</div>
<div class="row" data-bind="foreach: events">
<div class="event" data-bind="style: { left: left+'px', width: width+'px' }"><span data-bind="text:label, css: tense"></div>
</div>
</div></div>
这不会导致 less javascript,但它确实会产生更高效的javascript,因为类更改的发生频率远低于偏移更改,因此需要更少的DOM元素更新。
您可以通过对水平空间进行一些预分区来处理每个“事件”(在上面的示例中),并且只更新相关分区中的事件。