What I need:
Show 'article_footer' by default
When I pass 'article_footer_base' > 'article_footer' hides
When I then scroll back up passed 'article_footer_base' > 'article_footer' then becomes visible again.
Tried a million things - cant get it to work :( Help!? The below just doesn't really work at all. I've just been trying to nab stuff of SO
My HTML:
<div class="d3-d10">
<div class="article_header">
<h1>{{ title }}</h1>
<ul class="center">
<li><a href="/profile/{{ username }}" class="user_avatar">{{ gravatamatic:quicky
email = "{email}"
size = "32"
}}</a></li>
<li>{{ username }} on {{ current_date format="M jS, Y" }}</li>
</ul>
</div>
</div>
<div class="d3-d10 article_content">
{{ copy }}
</div>
<div class="d3-d10 source_link article_block_element">
{{ if source_link }}
<p class="center">Article originally published at {{ source_link }}</p>
{{ /if }}
<span class="icon-emblem"></span>
</div>
<div class="d3-d10 article_block_element article_footer_base">
<ul class="left">
<li><button class="global_btn_red"><span class="icon-upvote"></span>upvote</button> <span class="bold">23 people</span> have upvoted this</li>
</ul>
</div>
My footer (being called in a partial):
</section> <!-- Ending full width section -->
<div class="article_footer">
<ul class="left">
<li><button class="global_btn_red"><span class="icon-upvote"></span>upvote</button> <span class="bold">23 people</span> have upvoted this</li>
</ul>
<ul class="right">
<li><button class="global_btn_white"><span class="icon-saved"></span> save for later</button></li>
<li><span class="icon-twitter"></span></li>
<li><span class="icon-facebook"></span></li>
<li><span class="icon-flag"></span></li>
</ul>
</div>
My JS:
/**
* Article more dropdown
*/
$('.article_footer').show();
var entryheight = $('.article_footer_base').height();
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 350 && y < entryheight) {
$('.article_footer').fadeOut();
} else {
$('.article_footer').fadeIn();
}
});
TL;DR
The jQuery that will work is the following:
/**
* Article more dropdown
*/
$('.article_footer').show();
var entryheight = $('.article_footer_base').offset().top;
$(document).scroll(function () {
var y = $(window).scrollTop() + $(window).height();
if (y > entryheight) {
$('.article_footer').fadeOut();
} else {
$('.article_footer').fadeIn();
}
});
TS;WM
(too short, want more)
First, we remove magic numbers. I don't know what 350 stands for, and neither will anyone else.
Then, we check what we need. In this case, it's the offset of the item. The offset, in short, is the distance the item is from the top. We put it in the variable entryheight, as shown above. Now, on scroll ($(document).scroll()), all we need to do is compare the scrollTop() from the window to the offset from the item. If y (the scroll position of the window + the height of the window) is bigger than entryheight, we know we've passed .article_footer_base. Else, we want .article_footer visible.
Here you can see it working: http://jsfiddle.net/m7kjzbmv/4/
Related
When a user clicks on a link. I am trying to find the closest span value by class and then get that classes text. Currently it is just returning empty text:
Here is the HTML:
<div class="plan recommended">
<div class="recommended-badge"><span>DOUBLE DATA</span></div>
<div data-equalizer-listener="plan-heading" class="plan-header">
<div class="prices">
<div class="col total">
<div class="price"><sup>$</sup> <span class="amount">85</span> <span class="caption">per month</span></div>
</div>
<p class="min-payment">Min. Total Cost is $2,040 over 24 months.</p>
</div>
</div>
<div class="features">
<div class="feature included_data PO_Included_Data standard first" data-equalizer-selector="PO_Included_Data" style="height: 247px;">
<div class="description"><span class="highlight-text">28GB TOTAL DATA</span><br>
<span class="legal">Includes 14GB + 14GB bonus data for 24 mths<br>
New and recontracting services only<br>
Offer ends 15/04/18<br>
$10 per extra 1GB</span></div>
<div class="more-data-info hide" data-information="included-data"><strong>Data Pool -</strong> Combine any of our latest My Plan Plus (including SIM Only) and My Mobile Broadband Plus plans on the one bill to pool and share the data.</div>
<div>more</div>
</div>
</div>
</div>
and my javascript
So when someone clicks on the a href with the class="more-data-link" I want to find the span with the class="amount" and get its text
$(".more-data-link").on("click", function(event) {
event.preventDefault();
var x = $(this).closest('plan-header').find('.price').find('.amount').text();
console.log(x);
});
Please use this fiddle
$(".more-data-link").on("click", function(event) {
event.preventDefault();
var x = $(this).closest('.plan.recommended').find('.plan-header .price .amount').text();
console.log(x);
});
<div class="plan recommended">
<div class="recommended-badge"><span>DOUBLE DATA</span></div>
<div data-equalizer-listener="plan-heading" class="plan-header">
<div class="prices">
<div class="col total">
<div class="price"><sup>$</sup>
<span class="amount">85</span>
<span class="caption">per month</span></div>
</div>
<p class="min-payment">Min. Total Cost is $2,040 over 24 months.</p>
</div>
</div>
<div class="features">
<div class="feature included_data PO_Included_Data standard first" data-equalizer-selector="PO_Included_Data" style="height: 247px;">
<div class="description"><span class="highlight-text">28GB TOTAL DATA</span><br>
<span class="legal">Includes 14GB + 14GB bonus data for 24 mths<br>New and recontracting services only<br>Offer ends 15/04/18<br>$10 per extra 1GB</span>
</div>
<div class="more-data-info hide" data-information="included-data">
<strong>Data Pool -</strong> Combine any of our latest My Plan Plus (including SIM Only) and My Mobile Broadband Plus plans on the one bill to pool and share the data.
</div>
<div>
more
</div>
</div>
</div>
</div>
You need to select parent (plan recommended) class and then find its child...
For those seeking a solution without jquery (the logic inside the click event is the same as described by Sarvan Kumar):
window.onload = function(){
for(var tL=document.querySelectorAll('.more-data-link'), i=0, j=tL.length; i<j; i++){
tL[i].onclick = function(){
var tE = function fA(e){return !e || (e.className && e.className.indexOf('plan') !== -1 && e.className.indexOf('recommended') !== -1) ? e && e.querySelector('.amount') : fA(e.parentNode)}(this);
console.log(tE ? tE.textContent : '404')
}
}
}
I check your script and find some error in it, use innerHtml in place of text() and closest('plan-header') should be closest('.plan-header'). but may be you not get the proper result because it will search in parents div not subling check link https://www.w3schools.com/jquery/traversing_closest.asp
you can use the simplest and best way to do same by creating the attribute of the more-data-link and save value of amount in it and use the following code.
$(".more-data-link").on("click", function(event) {
event.preventDefault();
var x = $(this).attr('amount');
console.log(x);
});
$(".more-data-link").on("click", function(event) {
event.preventDefault();
var x = $(this).closest('.plan-header').find('.amount').text();
console.log(x);
});
Fixed it. You don't need to use the second find and you missed a dot
I recently created a simple image slider here: http://americanbitcoinacademy.com/test2/
Which has basically a next and prev buttons and slides the image. You can check the codes of that here: https://jsfiddle.net/mmytscuz/
And now I am trying to apply these codes to my new element but this time instead of images I am trying to apply it using div elements.
You can check my current progress work here: https://jsfiddle.net/7808uLpv/
So basically when you click the next button it must slide up on the next list item element. For some reason it won't hide the other elements now also it doesn't slide either.
So far here's how I layout my elements:
<ul class="slider">
<li>
<div class="box center">
<h1>What is your name?</h1>
<input type="text" name="name" placeholder="Your Name.."/>
<div id="slider-nav">
<button data-dir="next" >Next »</button>
</div>
</div>
</li>
<li>
<div class="box center">
<h1>How much money do you have?</h1>
<input type="text" name="money" placeholder="Your Money.."/>
<div id="slider-nav">
<button data-dir="next" >Next »</button>
</div>
</div>
</li>
<li>
<div class="box center">
<h1>Your Birthday?</h1>
<input type="text" name="bday" placeholder="Your Birthday.."/>
<div id="slider-nav">
<button data-dir="next" >Next »</button>
</div>
</div>
</li>
</ul>
And here's my javascript:
(function() {
var container = $('div.slider').css('overflow', 'hidden').children('ul'),
slider = new Slider( container, $('#slider-nav') );
slider.nav.find('button').on('click', function() {
slider.setCurrent( $(this).data('dir') );
slider.transition();
});
})();
function Slider( container, nav ) {
this.container = container;
this.nav = nav.show();
this.imgs = this.container.find('img');
this.imgWidth = this.imgs[0].width; // 600
this.imgsLen = this.imgs.length;
this.current = 0;
}
Slider.prototype.transition = function( coords ) {
this.container.animate({
'margin-left': coords || -( this.current * this.imgWidth )
});
};
Slider.prototype.setCurrent = function( dir ) {
var pos = this.current;
pos += ( ~~( dir === 'next' ) || -1 );
this.current = ( pos < 0 ) ? this.imgsLen - 1 : pos % this.imgsLen;
return pos;
};
Any idea what am I doing wrong when I click the 'NEXT' button why the elements are not sliding as well why are they all showing up at once?
There's a lot wrong with your fiddle.
No jQuery loaded.
No div.slider that you refer to for plugin initialization.
You use id slider-nav like a class. Id must be unique.
In css li.slider needs to be .slider li
You're looking for images within js but there are none in the markup.
Consequently, your plugin is throwing errors, trying to detect width of these images that don't exist: this.imgs[0].width;
Imo, just start over, get a solid html and css base and only then try to write the js plugin.
Just add jQuery because without not working.See the Demo here
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
I have a relatively complex list used as a product comparison table and need the list to be sortable by each of the list-items various attributes. Seems like this should be simple, but I haven't been able to get anything to work.
So I have something like this:
<ul id="myList">
<li id="item1">
<div class="myListTitle">Item 1</div>
<div class="myListPrice">
<span class="currency">£</span><span class="digits">12.45</span></div>
<div class="myListFirstFeature">456</div>
<div class="myListLastFeature"><span class="digits">36</span> options</div>
</li>
<li id="item2">
<div class="myListTitle">Item 2</div>
<div class="myListPrice">
<span class="currency">£</span><span class="digits">9.30</span></div>
<div class="myListFirstFeature">241</div>
<div class="myListLastFeature"><span class="digits">12</span> options</div>
</li>
<li id="item3">
<div class="myListTitle">Item 3</div>
<div class="myListPrice">
<span class="currency">£</span><span class="digits">17.25</span></div>
<div class="myListFirstFeature">842</div>
<div class="myListLastFeature"><span class="digits">64</span> options</div>
</li> </ul>
etc.
And then I want to have buttons that will order the list by the various attributes, ie
<button id="orderByPrice">Price</button>
<button id="orderByFirstFeature">1st Feature</button>
<button id="orderByLastFeature">Last Feature</button>
I hope that makes sense. Any help much appreciated.
Thanks
You can use sort() to achieve this. By providing a function to that method you can define the logic you want to sort by. If you include a data-* attribute on the button to determine what you are attempting to sort by, you can use a switch statement within that function to find the value to sort by. Try this:
$('.sort').click(function() {
sortLi($(this).data('order'));
});
function sortLi(order) {
var fieldClass = order == 'price' ? '.myListPrice .digits' : order == 'first-feature' ? '.myListFirstFeature' : '.myListLastFeature .digits';
$('#myList li').sort(function(a, b) {
var aValue = parseFloat($(a).find(fieldClass).text());
var bValue = parseFloat($(b).find(fieldClass).text());
if (aValue > bValue)
return 1;
if (aValue < bValue)
return -1;
return 0;
}).appendTo('#myList');
}
Example fiddle
More information on sort() at MDN
I have an issue with a partial that is rendered almost instantly for the first time navigating to that page, however if navigate away from that page and sometime later i come back it is rendered noticeably slow. It contains an ng-repeat on a list of about 140 items.
e.g: home (initialize) --> spells (instant) --> home --> spells (slow)
GitHub Repository
Why does this happen and how do i fix it?
Steps i've already taken to try and improve:
Add bind-once in the repeater
Use etags in my API so i don't get back a full list of the items i already have each time i load a partial.
Added track by to ng-repeat.
Code
<div ng-repeat="color in ::colors">
<div>
<span data-target="#{{$index + 'col'}}">
<header>
<label>{{color.name}}</label>
</header>
</span>
</div>
<ul id="{{$index + 'col'}}">
<li ng-repeat="spell in ::spells track by spell.name"
ng-if="spell.color.name === color.name"
ng-dblclick="addToCharacter(spell, 'spell')"
on-long-press="addToCharacter(spell, 'spell')">
<div>
<label ng-hide="isSpell(spell)">Ability</label>
<label ng-show="isSpell(spell)">{{spell.cost}} mana</label>
</div>
<div data-target="#{{$index + 'sp'}}">
<a>{{spell.name}}</a>
</div>
<div id="{{$index + 'sp'}}">
{{spell.description}}
</div>
</li>
</ul>
</div>
IsSpell()
$rootScope.isSpell = function (spell) {
return spell.type != null && spell.cost != null;
};
I have implement a little mechanism to only load the items when they are needed, so the page loads instantaneous and when the user clicks on a category (which is animated) it loads the items it needs. This all works very smoothly and i am quite happy with it.
See the first div (colors) and the ng-if on the li
<div ng-repeat="color in ::colors" ng-init="loadItems = false" ng-click="loadItems = true">
<div>
<span data-target="#{{$index + 'col'}}">
<header>
<label>{{color.name}}</label>
</header>
</span>
</div>
<ul id="{{$index + 'col'}}">
<li ng-repeat="spell in ::spells track by spell.name"
ng-if="(spell.color.name === color.name) && (loadItems = true)"
ng-dblclick="addToCharacter(spell, 'spell')"
on-long-press="addToCharacter(spell, 'spell')">
<div>
<label ng-hide="isSpell(spell)">Ability</label>
<label ng-show="isSpell(spell)">{{spell.cost}} mana</label>
</div>
<div data-target="#{{$index + 'sp'}}">
<a>{{spell.name}}</a>
</div>
<div id="{{$index + 'sp'}}">
{{spell.description}}
</div>
</li>
</ul>
</div>
I am trying to decrement a counter within a nested AnguarJs ng-repeat. I know it is a problem of scope, because the increment in the outer ng-repeat works fine, but in the inner ng-repeat is where I have to decrement and that is where I run into the problem (nothing happens). Is there any way to get an inner scope to increment/decrement/affect an outer scope? Here is the code I am working with.
<div class = "col-md-12 section-bg-conversations" ng-repeat="o in form.question | filter:searchText | orderBy:predicate" ng-show="$index<5 || form.showMoreQuestions" >
<!--section for question and option to answer-->
<span class="pull-left" style="margin-bottom:5px">
<ul style="color:#107A77; margin-left: -10px; list-style-type:none">
<li >
<!--below is only to toggle form view-->
<h7><strong><a style="color:#107A77;" ng-click="o.Answer = true" ng-show="!o.Answer">Comment</a></strong></h7>
</li>
<li>
<h7 ng-init="replyCounter=o.replyCounter">Replies ({{replyCounter}}) </h7>
</li>
<li>
<h7>
<a style="color:#107A77;text-size: 6px"
ng-init="followCounter=o.followCounter" ng-click="followConversation(o.id); o.isFollowing=true;
followCounter=followCounter+1" ng-show="!o.isFollowing">
Follow ({{followCounter}})
</a>
<span ng-show="o.isFollowing">
Following ({{followCounter}})
</span>
</h7>
</li>
</ul>
</span>
<span ng-show="o.isFollowing">
<a style='color:gold' ng-init="followCounter = o.followCounter" ng-click="unfollowConversation(o.followId); o.isFollowing = false;
followCounter = followCounter-1 " ng-hide="o.unfollowValue">Unfollow</a>
</span>
<!--form div below showing only submit and cancel-->
<div style="margin-top:5px">
<button class="btn btn-xs btn-primary" ng-init="replyCounter=o.replyCounter" style='background:#107A77'
ng-click="submitAnswer(o.id); replyCounter = replyCounter+1;">Submit</button>
<button class="btn btn-xs btn-primary" style='background:red' ng-click="o.Answer = false" ng-show="o.Answer">Cancel</button>
</div>
<div class = "col-md-offset-1" style="padding:5px"ng-repeat="a in o.replies" ng-show="$index<3 || o.showMoreReplies">
<span ng-show="a.isAuthor">
<a ng-init="replyCounter=o.replyCounter"style='color:red' ng-click="doDelete(a.id); a.deleteValue = true;
replyCounter = replyCounter-1">Delete</a>
</span>
</div>
I also included the followCounter as an exmaple of a counter that is working. Pretty much the main problem is in the last inner div that does ng-repeat="a in o.replies" and I'm not sure how to solve the problem of incrementing/decremeting the counter in the overall scope.