Jquery previous object selector - javascript

I have an issue about prev object on jquery it doesnt give me position ...
I have divs with ".post-image"
$(".post-image").each(function(){
var div = $(this);
var index = div.index();
var odd = index % 2;
if(odd == 1){
var sibling = div.next();
sibling.css({
margin:"15px",
marginTop:"-165px"
})
var bElement= div.prev(".post-image");
console.log(bElement)
})
HTML:
<div class="post">
<div class="post-header"></div>
<div class="post-content"></div>
</div>
<div class="post-image">
<div class="post-header"></div>
<div class="post-content"></div>
</div>
I cant select prev as an object

As for the jQuery docs:
.prev( [selector ] ) Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector.
Reference
Your <div class="post-image"> element has no immediately preceding element with the same class. The element preceding it is <div class="post">
[EDIT]
You can go this way:
// declare bElement variable:
var bElement;
$(".post-image").each(function(){
var div = $(this);
var index = div.index();
var odd = index % 2;
if(odd == 1){
var sibling = div.next();
sibling.css({
margin:"15px",
marginTop:"-165px"
});
// make sure that previous element with class '.post-image' exists :
if(bElement !== undefined){
var prevElemPosition = bElement.position().top;
// do something ...
}
}
// set latest .post-image element (so that it will be the previous on next iteration):
bElement = div;
});

Related

On click slider next and previous button i get $curr[action] is not a function

I am following this Js fiddle
http://jsfiddle.net/ryt3nu1v/10/
My Result:
I am making a slider that display age as I have an array that following ages
15,25,35,45,55
I am trying to display them in slider
expected behavior is to see the next age when i click on next button
Code that I used from fiddle according to my need is
//Age slider
$('div.result-age:gt(0)').hide(); //Hide all but the first one
var $allSlides = $('div.result-age'),
traverseDefault = "first", //set the defaults
actionDefault ="arrow-next";
$('.arrow-next,.selected-arrow-left-pointer').click(function(){
var traverse = traverseDefault,
action = actionDefault;
if($(this).is('.selected-arrow-left-pointer')){ //if action is prev
traverse = "last"; //set traverse to last in case nothing is available
action = "selected-arrow-left-pointer"; //set action to prev
}
var $curr = $allSlides.filter(':visible'), //get the visible slide
$nxtTarget = $curr[action](".result-age"); //get the next target based on the action.
$curr.stop(true, true).fadeIn(1000).hide(); //hide current one
if (!$nxtTarget.length){ //if no next
$nxtTarget = $allSlides[traverse](); //based on traverse pick the next one
}
$nxtTarget.stop(true, true).fadeIn(1000); //show the target
});
//age slider end
And this is my HTML
<div class="result-box">
<div class="selected-arrow-left-pointer"></div>
<div class="result-age"><span><h4 v-for="(row,key,index) in ages">ALL ages here currently being display all at once</h4></span></div>
<div class="arrow-next"></div>
</div>
My current style is that age will be displayed in center with left and right sides having next and previous button
What am I missing?
Your v-for is creating mutliple h4 tag but you need create result div for each numbers so move your v-for inside your div tag .Then , you are using wrong values for actionDefault and action it should be next & prev where next refer to next slide and prev refer to previous slide not the classnames .
Demo Code :
$('div.result-age:gt(0)').hide();
var $allSlides = $('div.result-age'),
traverseDefault = "first",
actionDefault = "next"; //use next ..refer next node
$('.arrow-next,.selected-arrow-left-pointer').click(function() {
var traverse = traverseDefault,
action = actionDefault;
if ($(this).is('.selected-arrow-left-pointer')) {
traverse = "last";
action = "prev"; //use prev..refer prev..
}
var $curr = $allSlides.filter(':visible');
$nxtTarget = $curr[action](".result-age");
$curr.stop(true, true).fadeIn(1000).hide();
if (!$nxtTarget.length) {
$nxtTarget = $allSlides[traverse]();
}
$nxtTarget.stop(true, true).fadeIn(1000);
});
span.next,
span.prev {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="result-box">
<div class="selected-arrow-left-pointer">
<< </div>
<!--your div should have ` v-for="(row,key,index) in ages"`-->
<div class="result-age"><span><h4>1</h4></span></div>
<div class="result-age"><span><h4>2</h4></span></div>
<div class="result-age"><span><h4>3</h4></span></div>
<div class="arrow-next"> >> </div>
</div>
I found the issue, you were using arrow-next instead of next, and selected-arrow-left-pointer instead of prev. Check the below working snippet. The data can be provided dynamically as you wish, currently I have given static data.
The next and prev are reserved keywords and hence the $curr[action] was expecting a function in return, while in your case it was `$curr['arrow-next'] instead of $curr['next'], which was returning undefined, and hence the error occurred.
//Age slider
$("div.result-age:gt(0)").hide(); //Hide all but the first one
var $allSlides = $("div.result-age"),
traverseDefault = "first", //set the defaults
actionDefault = "next";
$(".next,.prev").click(function () {
var traverse = traverseDefault,
action = actionDefault;
if ($(this).is(".prev")) {
//if action is prev
traverse = "last"; //set traverse to last in case nothing is available
action = "prev"; //set action to prev
}
var currentData = $allSlides.filter(":visible"), //get the visible slide
$nxtTarget = currentData[action](".result-age"); //get the next target based on the action.
currentData.stop(true, true).fadeIn(1000).hide(); //hide current one
if (!$nxtTarget.length) {
//if no next
$nxtTarget = $allSlides[traverse](); //based on traverse pick the next one
}
$nxtTarget.stop(true, true).fadeIn(1000); //show the target
});
.next, .prev {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="result-box">
<div class="prev"><</div>
<div class="result-age">
<span><h4>ALL ages here currently being display all at once</h4></span>
</div>
<div class="result-age">
<span><h4>2</h4></span>
</div>
<div class="result-age">
<span><h4>3</h4></span>
</div>
<div class="result-age">
<span><h4>4</h4></span>
</div>
<div class="result-age">
<span><h4>5</h4></span>
</div>
<div class="next">></div>
</div>

How to remove wrapper of multiple elements without jquery?

I have a set of elements and want to remove its container wrapper in Javascript.
I've researched around (this, this, and this) but I need a solution that 1) doesn't involve jQuery. 2) and can work on multiple elements.
HTML:
<div class="global-container stacked">
<article class="global"></article>
<article class="global"></article>
</div>
I've tried:
var globalArticles = document.getElementsByClassName('global');
globalArticles.outerHTML = globalArticles.innerHTML;
But that doesn't work. How would one go about removing the wrapper from all article.global?
You could just create your own unwrap() method, something like this
function unwrap(elems) {
elems = 'length' in elems ? elems : [elems];
for (var i = 0; i < elems.length; i++) {
var elem = elems[i];
var parent = elem.parentNode;
var grandparent = parent.parentNode;
grandparent.insertBefore(elem, parent);
if (parent.children.length === 0)
grandparent.removeChild(parent);
}
}
var globalArticles = document.getElementsByClassName('global');
unwrap(globalArticles);
You can use .innerHTML, .removeChild(), .insertAdjacentHTML()
var container = document.querySelector(".global-container");
var html = container.innerHTML; // store `html` of `container`
container.parentElement.removeChild(container); // remove `container`
document.body.insertAdjacentHTML("beforeend", html); // append `html`
<div class="global-container stacked">
<article class="global">1</article>
<article class="global">2</article>
</div>
This should work:
var globalArticle = document.getElementsByClassName('global')[0];
if (globalArticle) {
globalArticle.parentElement.outerHTML = globalArticle.parentElement.innerHTML;
}

Javascript loop over getElementsByClassName

I try to iterate using getElementsByClassName, but the effect i try to achieve affect all the items at once.
How can I make it work 1 item per swipe?
HTML:
<div id="recog" class="cr-wrap">
<div id="slide">
<div class="card item"><img src="mc.svg"></div>
<div class="card item"><img src="paypal.svg"></div>
<div class="card item"><img src="visa.svg"></div>
</div>
</div>
js:
var wrap = document.getElementById('recog');
var swiper = new Hammer(wrap);
swiper.on('swipeleft', function(){
var items = document.getElementsByClassName('item');
for ( var i=0; i < items.length ; i++ ){
items[i].classList.add('gone');
}
});
Maybe this would be better, using querySelectorAll, where you can narrow the hit list even more.
var wrap = document.getElementById('recog');
var swiper = new Hammer(wrap);
swiper.on('swipeleft', function(){
var items = wrap.querySelectorAll('.item');
for ( var i=0; i < items.length ; i++ ){
items[i].classList.add('gone');
}
});
To be noted: By using wrap.querySelectorAll('.item');, it target only item's inside the recog element
Update
If you want only 1 item per swipe, do like this
var wrap = document.getElementById('recog');
var swiper = new Hammer(wrap);
swiper.on('swipeleft', function(){
var item = wrap.querySelector('.item');
item.classList.add('gone');
});
Update 2
If you want only the swiped item, you should be able to do like this but it depends on how hammer pass the target forward.
var wrap = document.getElementById('recog');
var swiper = new Hammer(wrap);
swiper.on('swipeleft', function(e){
e.target.classList.add('gone');
});
If this won't work, you likely need to add a swiper on each item.

How to find element of div from another div

I have the elements in the div as mentioned below:
<div id="container">
<div id="first_div">
<div id="comment-1" class="comment">Child 1 of first div</div>
<div id="comment-2" class="comment">Child 2 of first div</div>
<div id="comment-3" class="comment">Child 3 of first div</div>
<div id="comment-4" class="comment">Child 4 of first div</div>
</div>
<div id="second_div">
<div id="comment-5" class="comment">Child 1 of second div</div>
<div id="comment-6" class="comment">Child 2 of second div</div>
<div id="comment-7" class="comment">Child 3 of second div</div>
<div id="comment-8" class="comment">Child 4 of second div</div>
</div>
<div id="third_div">
<div id="comment-9" class="comment">Child 1 of third div</div>
<div id="comment-10" class="comment">Child 2 of third div</div>
<div id="comment-11" class="comment">Child 3 of third div</div>
<div id="comment-12" class="comment">Child 4 of third div</div>
</div>
I need to retrieve the next element from comment id comment-4.
$('#comment-4').next().attr('id') gives me result as undefined.I need the target div to be comment id - comment-5.How to retrieve the next element of div from another div using jquery?
Try this :
$(function(){
$('.comment').click(function(index){
var id;
if ( $(this).is(':last-child') )
id = $(this).parent().next().children(':first').attr('id');
else
id = $(this).next().attr('id');
alert(id);
});
});
Demo
Demo : http://jsfiddle.net/abdennour/PU54r/
function nextOf(id,cyclic){
var ids= $('div[id^=comment-]').toArray().map(function(e){return $(e).attr('id')}).sort();
var idx=ids.indexOf("comment-"+id);
if(idx!==-1){
if(ids.length> idx+1){
return $('div#'+ids[idx]);
}
else{
// it is the last div: if it is cyclic ,you may return the first
if(cyclic){
return $('div#'+ids[0]);
}
}
}else{
// no div with this id
}
}
Then :
var target=nextOf(4)
if(target){
target.html()
//--> Child 1 of second div
}
I think you can use $('.comment') to pick up all of your wanted, and save them in some variable such as var arrResult = $('.comment');.
So far, you can choose what you wanted use the arrResult variable.
Because your inner-most divs have different parents, I would first get all the divs you care about:
var comments = $('.comment');
Next, if we can assume your id's are all numbered sequentially, get the number in the id (assuming this references the element):
var index = parseInt($(this).attr('id').substr(8));
Now, the next div in the comment list is at that position in the comments:
var nextDiv = comments[index];
Just for good measure, I'd first make sure index is set:
var nextDiv;
if (index < comments.length) {
nextDiv = comments[index];
}
You could use an index in your case :
JS:
for (var index = 0; index <= 12; ++index) {
$("#comment-" + index).attr("id");
}
You can define a statement which checks the target id is the last child, than you can return a function according to value.
jsFiddle Demo
var target = 'comment-4';
$('.comment').each(function(i) {
if ( $(this).attr('id') == target ) {
if ( $(this).is(':last-child') ) {
$(this).parent().next().children().first().addClass('red');
}else{
$(this).next().addClass('red');
}
}
});
Here is one way - http://jsfiddle.net/jayblanchard/WLeSr/
$('a').click(function() {
var highlight = $('.highlight');
var currentIndex = $('.comment').index(highlight); // get the index of the currently highlighted item
$('.comment').removeClass('highlight');
var nextIndex = currentIndex + 1;
$('.comment').eq(nextIndex).addClass('highlight');
});
It is showing undefined because comment-4 and comment-5 are childrens of different parent elements. Means comment-4 is children of first_div and second_div parent of comment-5.
You can get the comment-5 using below code.
$('#comment-4').parent().next().children().attr('id');
Assuming jQuery-wrapped element is collected in $comment, there's one way to solve it:
function getNextComment($comment) {
var $nextComment = $comment.next();
if ($nextComment.length) {
return $nextComment;
}
var $nextParent = $comment.parent().next();
if ($nextParent.length) {
return $nextParent.children().first();
}
return null;
}
Demo. Click on one comment - and see the next one's highlighted. )
The base algorithm's very simple here. First, we attempt to retrieve the next sibling of the given element. If there's one, it's returned immediately. If not (and it's the case with #comment-4 in your question - it's the last element in its hierarchy), we go up the DOM chain for its parent (#first-div, in this case), and look for its next sibling (#second-div). If it exists, then its very first child element is returned. If it doesn't, null is returned (we can actually return an empty jQuery object - $(), but that depends on use cases.
Just one instruction : )
$('<div id="mock" />').append($('.comment').clone()).find('#comment-4').next().attr('id')//---> comment-5
Based on divs have the same Css class .comment
DEMO
Why not this will be undefined: $('#comment-4').next().attr('id') because there is no next element. as you mentioned that you want to target the #comment-5 in the next div's child then you can do this:
function giveId(el) {
var sel = el.id ? '#'+el.id : '.'+el.className;
var id = $(sel).next('div').length ? $(sel).next('div').attr('id') : $(sel).parent('div').next('div').find('> div:first').attr('id');
return id || "Either no next elem exist or next elem doesnot have any id/class.";
}
$(function () {
$('div').click(function (e) {
e.stopPropagation();
alert(giveId(this));
});
});
Updated Demo in action
Try this: JSFiddle (The easiest solution!)
$(document).ready(function(){
var currDiv = $("#comment-4"); // Try with different valies: "#comment-x"
currDivId = currDiv.prop('id');
lastDivId = currDiv.parent('div').find('.comment').last().prop('id');
if(currDivId == lastDivId){
var nextComment = currDiv.parent('div').next('div').find('.comment').prop('id');
}else{
var nextComment = currDiv.parent('div').find('.comment').next().prop('id');
}
alert(nextComment);
});

finding index of parent of a certain class

I have the following HTML:
<div class="Wrapper">
<div class="SomeOtherClass"></div>
<div class="SomeOtherClass"></div>
<div class="MyClass">
<div class="SomeElement" id="test"></div>
<div class="SomeElement"></div>
</div>
<div class="MyClass">
<div class="SomeElement" id="test2"></div>
<div class="SomeElement"></div>
</div>
</div>
And I have the following javascript:
$('.Wrapper').find('.SomeElement').each(function () {
if (SomeCondition) {
var TheElement = $(this);
var TheIndexOfParentClass = TheElement... //HERE
return;
}
});
As you can see, I loop through all the SomeElements and I pick one. Now I want to know the index of the parent's class (here "MyClass"). For instance, if I pick out "test" then the TheIndexOfParentClass should be 0 and if I pick out test2 then TheIndexOfParentClass should be 1. Note that the number of elements of SomeOtherClass can vary; I don't want the actual index of the parent, I want the index of the parent's class relative to all children of the Wrapper element. How do I do this?
Thanks.
I think you want this :
$('.Wrapper').find('.MyClass').each(function(TheIndexOfParentClass) {
$('.SomeElement', this).each(function(){
if (SomeCondition) {
var TheElement = $(this);
each pass to the callback the iteration index and so by decomposing the iteration you can ask jQuery to count for you.
If you want to stick with your flow, You could do this also by passing class to index method,
$('.Wrapper').find('.SomeElement').each(function () {
if (SomeCondition) {
var TheElement = $(this);
var TheIndexOfParentClass = TheElement.parent().index('.MyClass'); //HERE
return;
}
});
What we are avoiding here is double each loop.

Categories

Resources