Jquery Scroll to elements without Ids, only by data attributes - javascript

I want the page to scroll down to my "container"-li which wraps my current elements. The li doesn't have an id attribute and it can't have for HTML validation purposes. Each li has a data attribute named: data-commentid This attribute contains a GUID and is what i want to use when binding the scroll.
How do i scroll to a element only by using it's data-attribute?
var container = $("body").find(".roomWall.commentBox.publicListing:first");
var targets = $(container).find("li.commentInList.topLevelComment");
if ($.cookie('scrollTarget')) {
var cookieValue = $.cookie("scrollTarget").split('"');
var splittedStr = cookieValue[1];
$(targets).each(function () {
var $self = $(this);
if ($($self).attr("data-commentid") === splittedStr) {
var target = $("#" + splittedStr);
$($self).fadeOut("slow").hide().delay(500).queue(function (next) {
next();
}).delay(1000).queue(function (next) {
var $container = $("html,body");
$($container).animate({
scrollTop: $self.offset().top
}, 1000);
next();
}).delay(1000).queue(function () {
$($self).fadeIn(1000);
$(target).focus();
});
$.removeCookie("scrollTarget", { path: "/" });
}
});
}
The cookie contains the GUID I want. Inside my li ($self) there's a textarea with id={Some Guid} which, in this case refers to my $target variable. Since I didn't managed to get it working with $self.offset().top I added $scrollTo and tried with that one, which didn't work either.
Regarding to the Markup, It's pretty complex so I will only show you the parts we need, to prevent confusion. A wrapping li with the data-commentId:
Further down the hierarchy we have:
Hope someone can find out where my code breaks.

I would recommend using jQuery's filter() instead of trying to concatenate it in. I also think the $("html,body") part is where it's bugging out for you. Otherwise your code is actually correct:
var someGuid = "0003";
var $scrollTo = $("li.commentInList.topLevelComment").filter(function(i){
return $(this).data('commentid') === someGuid;
});
$(document.body).animate({
scrollTop: $scrollTo.offset().top
}, 1000);
li {
height: 10em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="commentInList topLevelComment" data-commentid="0001">Comment 1</li>
<li class="commentInList topLevelComment" data-commentid="0002">Comment 2</li>
<li class="commentInList topLevelComment" data-commentid="0003">Comment 3</li>
<li class="commentInList topLevelComment" data-commentid="0004">Comment 4</li>
<li class="commentInList topLevelComment" data-commentid="0005">Comment 5</li>
</ul>

How was it supposed to scrolldown to something that's faded out? Removed the fading effects and it ( scrollTop: $self.offset().top) worked like a charm.

Related

Each function triggers only once

I'm trying to triggers a function on several owl-carousel sliders having the same class. If i do a console.log, it logs twice, but works only on the first slider.
Here's my function:
function setActiveItem(){
var item = $('.owl-item');
var itemLink = $('.owl-item a');
var pos = $('.is-active').parent().parent().index();
$('.slider-mobile').each(function() {
if($(this).find(itemLink).is('.is-active')) {
item.removeClass('active');
$(this).trigger('to.owl.carousel', [pos, 1, true]);
}
})
}
setActiveItem();
And here's a simplified version of my markup:
<ul class="list-container slider-mobile" data-stage-padding-items="200">
<li class="list-item">
item
</li>
</ul>
<ul class="slider-mobile" data-stage-padding-items="200">
<li class="list-item">
item
</li>
</ul>
I'm not sure if i'm using the each() function right, or if it fits my need at all.
Ok i figured it out.
#Reinder Wit you were right i was referencing the item of the first slider only, so both of my sliders were getting the same datas.
I did this:
function setActiveItem(){
$('.slider-mobile').each(function() {
var item = $(this).find('.owl-item');
var itemLink = $(this).find('.owl-item a');
var pos = $(this).find('.is-active').parent().parent().index();
if($(this).find(itemLink).is('.is-active')) {
item.removeClass('active');
$(this).trigger('to.owl.carousel', [pos, 1, true]);
console.log(pos);
}
})
}
setActiveItem();
And it is working now. Thanks for the clue.
You should activate your listener in the document ready like this:
$(document).ready(function(){
setActiveItem();
});

How to access list items within ul that get added via a jquery function

I am basically working on a responsive navigation bar where if the current window width doesn't accommodate the number of items, last item of the list will get appended to another un-ordered list.
My problem is I need to target menu items within the hidden list which is empty when the width of the window is 100%. I could access the un-ordered list for visible list but not for the hidden list as per below jQuery. I understand that I am trying to access items that doesn't exist yet, but there must be a way.
Snippet:
var $vlinks = $('#hrmenu .visible-links');
var $hlinks = $('#hrmenu .hidden-links');
availableSpace = $vlinks.width() - 30;
var
break = [];
areaAvail += w + 20;
break.push(areaAvail);
visibleItems = $vlinks.children().length;
requiredSpace =
break [visibleItems - 1];
if (requiredSpace > availableSpace) {
$vlinks.children().last().prependTo($hlinks);
}
$(document).ready(function() {
//Visible list
$('#shuffle-btn > li > a').click(function(event) {
$item = $(event.currentTarget).parent('li');
console.log($item.index());
});
//Hidden list list
$('#hidshuffle-btn > li > a').click(function(event) {
$item = $(event.currentTarget).parent('li');
console.log($item.index());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="hrmenu" class="prdct-hrmenu">
<ul id="shuffle-btn" class="visible-links">
<li>item-1
<ul>
<li>Item-1-a</li>
</ul>
</li>
<li>item-2
<ul>
<li>Item-1-a</li>
</ul>
</li>
<li>item-3
<ul>
<li>Item-3-a</li>
</ul>
</li>
<li>item-4
<ul>
<li>Item-4-a</li>
</ul>
</li>
</ul>
<ul id="hidshuffle-btn" class="hidden-links">
</ul>
</nav>
As the elements in the hidden list are not available during DOM ready, you need to define a click handler that can delegate to these elements when they are available. You can use JQuery's on function for this like below.
$(document).ready(function(){
//Hidden list list
$('#hidshuffle-btn').on('click', ' li > a', function(event){
var $item = $(event.currentTarget).parent('li');
console.log($item.index());
});
});
Here's a sample Pen in action :)
For dynamically added elements, you just need to change your line from:
$('#shuffle-btn > li > a').click(function(event) {
to
$(document).on('click', '#shuffle-btn > li > a', function(event) {
Similarly for the hidden list:
$('#hidshuffle-btn > li > a').click(function(event) {
to
$(document).on('click', '#hidshuffle-btn > li > a', function(event) {
**#Arkantos's answer is more correct in terms of performance.

Cant get the value of <li data-*> element. Tried Javascript as well as Jquery

The following is my dropdown list.
<ul id="navBar" data-value="">
<li data-city-value="blore">Bangalore
<ul>
<li data-city-value="delhi">Delhi</li>
<li data-city-value="che">Chennai</li>
<li data-city-value="jaipur">Jaipur</li>
<li data-city-value="hyd">Hyderabad</li>
<li data-city-value="mum">Mumbai</li>
<li data-city-value="pune">Pune</li>
</ul>
</li>
</ul>
And the following are my methods I tried to access the data-city-value attribute.
Method 1)
var cityName = document.getElementById('navBar');
var city = cityName.getAttribute('data-city-value');
alert(city);
It alerts "null"
Method 2)
var cityName = document.getElementById('navBar');
var city = cityName.dataset.cityValue;
alert(city);
It alerts "undefined".
Method 3)
$('#navBar li').click(function() {
$(this).parent().data('value', $(this).data('cityValue'));
});
alert($('#city').data('value'));
It alerts "undefined".
I checked the syntax to get data value here
It would be of great help if you can help me find where I am doing mistake.
Thanks. :)
IN your first two methods you target the top ul with id navBar. In the third method you do $(this).parent() which again takes you to the ul element.
That element does not have the data-city-value attribute.
The jquery method should be
$('#navBar').on('click','li', function(e) {
var city = $(this).data('city-value');
alert(city);
return false;
});
Demo at http://jsfiddle.net/gaby/Mb7KS/
As pointed out by Gaby, you need to reach the element firts. Try this:
$('#navBar:first-child')
This is how you can iterate through your data-city-value attributes:
$('li[data-city-value]').each(function(index,element){
alert($(element).data('city-value'));
});
You can also check my jsFiddle example.
For click events:
$(document).ready(function()
{
$('li').click(function() {
alert($(this).data('city-value'));
return false;
});
});
You should return false because the top li element has inner elements and it was triggering inner li element click event.
My second jsFiddle demo.

Sort <li> with jQuery

Currently I have a language select which is a simple <ul> with <li>s and <a>s inside.
Every <li> has a class - lang-inactive or lang-active. It depends on what language the user is using right now.
The <li>s with .lang-inactive are hidden by default. When you .hover() the ul the other options are showed.
Here is a simple example.
But as you can see the first <li> is French, and when I'm using English and I hover the language bar the French appears over the english.
Is there a way I can sort the <li> depending on whether they are lang-active or lang-inactive. The inactive ones should appear below the active one.
My current code is:
var ul = $('#languages-iv');
ul.css('position', 'absolute');
ul.css('top', 5);
li = ul.children('li');
li.detach().sort(function(a,b) {
//how do I sort
});
ul.append(li);
$("#languages-iv").hover(function(){
$('.lang-inactive').slideToggle();
}, function() {
$('.lang-inactive').stop().slideToggle();
});
This executed on page-load (or whenever your language selector gets created) should push the active language up to first child.
$('.lang-active').prependTo('#languages-iv');
Demo:
http://jsfiddle.net/gqfPV/
<ul>
<li>English</li>
<li>French</li>
<li>German</li>
</ul>
<script>
$(document).ready(function(){
$('ul li').live('click',function(){
$('li a').removeClass('lang-active');
var elem = $(this);
$(this).remove();
$('ul').prepend(elem);
$(this).children('a').addClass('lang-active');
});
});
<script>
Here's your sort:
var listItems = myList.children('li').get();
listItems.sort(function(a,b){
return $(a).hasClass('lang-inactive') ? -1 : $(b).hasClass('lang-inactive') ? 1 : 0;
});

Jquery addClass with delay

I have a basic menu like this:
<ul>
<li>item 1</li>
<li>item2</li>
</ul>
How can I add the class "current" for each one of my <li> elements every 800 ms, and of course delete the old current element?
This'll loop forever through any number of list items:
$(document).ready(function() {
var $lis = $("li"), i = -1;
function nextCurrent() {
$lis.eq(i).removeClass("current");
$lis.eq(i=(i+1)%$lis.length).addClass("current");
setTimeout(nextCurrent, 800);
}
nextCurrent();
});
Demo: http://jsfiddle.net/nnnnnn/4skLV/
And may I suggest that before you next post a question you read this article: What have you tried?
$('li').each(function(i){
var $that = $(this);
setTimeout(function(){
$that.addClass('current').siblings().removeClass('current');
}, i *800);
});
Live DEMO

Categories

Resources