Настроить последнюю строку в строке?
У меня есть простой список с элементами списка, которые не имеют каких-либо специальных классов.
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
etc..
</ul>
Похоже на передний край:
![enter image description here]()
Я хочу настроить таргетинг на последний li
в каждой строке (выделенные зеленым цветом). Тем не менее, я не уверен, что, поскольку эти li
не имеют классов и в зависимости от пользовательского экрана, это может быть другой li
, который заканчивается последним в строке. Есть ли способ настроить таргетинг на последний li
в строке?
Изменить: Я думаю, что была какая-то путаница. Все элементы li
находятся в ONE ul
.
Ответы
Ответ 1
function calculateLIsInRow() {
var lisInRow = 0;
$('ul li').each(function() {
$(this).removeClass("back");
if($(this).prev().length > 0) {
if($(this).position().top != $(this).prev().position().top) {
$(this).prev().addClass("back");
// return false;
}
lisInRow++;
} else {
lisInRow++;
}
if($(this).next().length > 0) {
}
else {
$(this).addClass("back");
}
});
}
calculateLIsInRow();
$(window).resize(calculateLIsInRow);
JSFIDDLE
Я думаю, что нашел ответ. Пожалуйста, проверьте, изменив размер окна.
Ответ 2
Проверьте эту функцию (у меня была одна и та же проблема, и я сделал эту функцию, вы можете ее отредактировать по своему усмотрению):
ИЗМЕНИТЬ РАБОТУ ПО РЕЗИЦИИ
DEMO (изменение размера)
var wrapDetector = function(element) {
var $elem = $(element);
var wrapper = $(element).parent();
var wrapperWidth = wrapper.outerWidth();
var expToggle = $('#main-menu-wrapper.main-menu-expanded #header-toggle-buttons');
wrapper.attr('data-width', wrapperWidth);
var elemTotalWidth = 0;
$elem.each(function() {
elemTotalWidth += $(this).outerWidth();
});
var wrapperWidthNew = wrapper.outerWidth();
var curWidth = 0;
$elem.removeClass('lastInRow last-row');
$elem.each(function() {
var that = $(this);
var elemWidth = that.outerWidth();
curWidth += elemWidth;
if (curWidth > wrapperWidthNew) {
that.prev().addClass('lastInRow');
curWidth = elemWidth;
}
that.attr('data-curWidth', curWidth);
});
var lastInRow = $(element + '.lastInRow');
if (lastInRow.length > 0) {
lastInRow.last().nextAll().addClass('last-row');
} else {
$elem.addClass('last-row');
}
}
wrapDetector('li');
ДОБАВИТЬ ЭТО
$(window).resize(function() {
wrapDetector('li');
});
Ответ 3
Как насчет решения PURE CSS:
Для достижения этой цели мы можем использовать ряд медиа-запросов. С помощью медиа-запросов мы можем настроить таргетинг на последний элемент в каждой строке и изменить его цвет.
Теперь это может показаться громоздкой задачей, но если вы используете препроцессор, такой как LESS - это не такая сложная или подверженная ошибкам задача.
Все, что нам нужно сделать, это настроить несколько переменных в LESS mixin в соответствии с нашими потребностями - и мы получим точный макет, который нам нужен. Взгляните...
CODEPEN (изменить размер, чтобы увидеть это в действии)
Использование прост - просто вызовите LESS mixin так:
.box-layout(boxItemList,li,100px,120px,2,7,20px);
Если mixin принимает 7 параметров:
1) Селектор списка
2) Селектор элементов
3) ширина элемента
4) высота элемента
5) min cols
6) max-cols
7) margin
Мы можем изменить эти параметры на все, что нам нужно, и мы получим требуемый макет
Здесь код CSS (LESS):
.box-layout(@list-selector,@item-selector, @item-width, @item-height, @min-cols, @max-cols, @margin)
{
@item-with-margin: (@item-width + @margin);
@layout-width: (@min-cols * @item-with-margin - @margin);
@next-layout-width: (@layout-width + @item-with-margin);
@layout-max-width: (@max-cols * @item-with-margin - @margin);
@layout-min-width: (@min-cols * @item-with-margin - @margin);
@list: ~" `'\n'`[email protected]{list-selector}";
@item: ~" `'\n'`@{item-selector}";
@{list} {
display: block;
margin: 0 auto;
list-style: none;
border: 5px solid aqua;
overflow: auto;
padding:0;
color: white;
min-width: @layout-min-width;
max-width: @layout-max-width;
}
@{item} {
height: @item-height;
width: @item-width;
margin: 0 @margin 32px 0;
background: tomato;
float:left;
}
@media (max-width:@layout-min-width) {
@{list} {
width: @item-width;
min-width: @item-width;
}
@{item} {
margin-right:0;
background: green;
}
}
.loopingClass (@layout-width, @next-layout-width, @min-cols);
}
.loopingClass (@layout-width, @next-layout-width, @iteration) when (@layout-width <= @layout-max-width) {
@media (min-width:@layout-width) {
@{list} {
width: @layout-width;
}
@{item} {
&:nth-child(n) {
margin-right: @margin;
background: tomato;
}
&:nth-child(@{iteration}n) {
margin-right: 0;
background: green;
}
&:last-child {
background: green;
}
}
}
.loopingClass(@next-layout-width, @next-layout-width + @item-with-margin, @iteration + 1);
}
.box-layout(boxItemList,li,100px,120px,2,7,20px);
Ответ 4
Здесь вы идете. Единственный способ, которым я это знаю, - использовать jQuery для вычисления размеров контейнера ul и размеров внутренних элементов.
Это решение предполагает следующее:
- Все элементы
<li>
расположены так, как если бы они находились в таблице, где все "ячейки" <li>
занимают одинаковое количество ширины (включая поля).
- Вы применили класс
.last-type
к любому <ul>
, который вы хотите сделать.
JQuery
$(function(){
resize();
$(window).resize(function(){
resize();
});
});
function resize()
{
var ul = $("ul.last-type");
ul.each(function(){
var ulWidth = $(this).width();
var liWidth = $($(this).find("li")[0]).outerWidth(true);
var lisPerLine = parseInt(ulWidth / liWidth);
$(this).find("li").removeClass("marked");
$(this).find("li:nth-child("+lisPerLine+"n)").addClass("marked");
});
}
CSS
ul
{
list-style: none;
margin: 0;
padding: 0;
font-size: 0;
}
ul li
{
display: inline-block;
width: 75px;
height: 75px;
background: blue;
margin: 15px;
font-size: 100%;
}
ul li.marked,
ul li:last-child
{
background: green;
}
Изменить:
Я узнал, почему было несколько размеров экрана, где элементы были бы не синхронизированы. Добавьте нулевой размер шрифта в родительский <ul>
и установите реальный размер шрифта в <li>
s.
ul
{
font-size: 0;
}
ul li
{
font-size: 100%;
}
И, наконец, я добавил селектор ul li:last-child
к тому же правилу ul li.marked
, чтобы последний элемент в последней строке всегда был отмечен также, даже если он не доходит до конца строки.
Ответ 5
Если мое понимание вашего вопроса верно, что каждый li имеет одинаковую ширину.
И это функция
function getLastItem(){
$('li').removeClass('hello');
var containerWidth = $('ul').eq(0).width();
var totalItem = $('li').length;
var itemWidth = $('li').eq(0).outerWidth(true); // plus margin
var itemPerRow = Math.floor(containerWidth/itemWidth);
var totalRows = Math.ceil(totalItem/itemPerRow);
$('li:nth-child(' + itemPerRow + 'n), li:last-child()').addClass('hello');
}
});
Надеюсь, мое демо поможет вам
http://jsfiddle.net/4n7drqcz/
Ответ 6
Вы могли бы сделать что-то с расстоянием пикселей каждого последнего li от границы. Смещение получает расстояние от верхнего и левого
var offset = $("#target").offset();
display("target is at " + offset.left + "," + offset.top + " of document");
Я уверен, что вы можете придумать какое-то разумное максимальное расстояние, последнее из которых будет когда-либо с границы, а затем сделайте
var screenWidth = $(document).width();
var distanceFromRightOfWindow = screenWidth - document.getelementsbyclassname("li").offset().left
if (distanceFromRightOfWindow < reasonableMaximumDistance)
/*Change the color to green*/
Ответ 7
Вот мой подход. Я подсчитываю, сколько столбцов занимает каждую строку, тогда я применяю цвета фона, используя для цикла.
JS
function calculateLIsInRow() {
var lisInRow = 0;
$('ul li').each(function() {
if($(this).prev().length > 0) {
if($(this).position().top != $(this).prev().position().top) return false;
lisInRow++;
}
else {
lisInRow++;
}
});
$("ul li").css("background","#ffffff");
for(i=lisInRow; i<=$('ul li').length; i=i+lisInRow)
{
$("ul li:nth-child("+i+")").css("background","green");
}
$("ul li:last-child").css("background","green");
}
calculateLIsInRow();
$(window).resize(calculateLIsInRow);
FIDDLE DEMO
Ответ 8
Здесь решение, которое смотрит на смещение слева для каждого элемента и сравнивается с исходным смещением и любым полем, применяемым к li
.
Если посмотреть на левое смещение, если оно соответствует родительскому (скорректированному для поля), то предыдущий элемент - конец строки, как и самый последний дочерний элемент UL.
Он добавляет класс к последнему в строке, который позволит вам делать все, что необходимо, используя CSS. Он также связан с изменением размера окна по мере его запуска.
Ширины в этом решении не имеют значения.
var resizeTimer;
function findLastInRow(){
var $list = $('ul'),
offsetLeft = $list.offset().left,
leftMargin = 5;
/* reset */
resetLastInRow($list);
/* find end of rows and add class */
$list.children().each(function (i) {
var $li = $(this);
if ($li.offset().left === offsetLeft+leftMargin) {
$li.prev().addClass('to-hide');
}
}).last().addClass('to-hide');
}
function resetLastInRow($parent){
$parent.children().removeClass('to-hide');
}
/* initiate using resize event and trigger resize on page load*/
$(window).resize(function(){
/* throttle resize event */
if(resizeTimer){
clearTimeout(resizeTimer);
}
resizeTimer=setTimeout(findLastInRow,50);
}).resize();
DEMO
Ответ 9
вы можете использовать этот
$("ul>li:last-child");
Ответ 10
Если вы знаете, сколько элементов есть в каждой строке, вы можете использовать этот
$('li:nth-child(Xn)')
Где X - количество элементов в каждой строке.
Для прикрепленного экрана вы можете использовать..
$('li:nth-child(10n)')
Ответ 11
Вы можете получить последний такой ребенок
$('ul li:last-child').css('color','red');
Ответ 12
попробуйте следующее:
function getLastelement(){
var lastLi=$("ul>li:last-child");
// do your stuff on this lastLi which contains the direct last li child of your ul tag.
}