I'm working on a blog theme that uses the inview plugin to use J & K scrolling, and also to apply a class to an article that's in view. The only problem is, since I have a mac with a large resolution, there are more than 1 articles in view at a time, so the following script adds the class "inview" to (usually for me, 3 articles) several articles at a time. Is there a way to modify this so it only adds the class "inview" to the FIRST article on the users screen? This may not be the first article on the page, technically, just the first one out of the few in view. Any help is appreciated.
$('article').each(function(){
$(this).bind('inview', function (event, visible) {
if (visible == true) {
$(this).addClass("inview");
}
else {
$(this).removeClass("inview");
}
});
});
If I understood your question correctly, I think you can add an index argument to your .each function. Like this:
$('article').each(function(index){
if( index == 0 )
{
$(this).bind('inview', function (event, visible) {
if (visible == true) {
$(this).addClass("inview");
}
else {
$(this).removeClass("inview");
}
});
}
});
This will add class the class "inview" to the first article.
You can always go to jquery.inview.js line 97 where it says
$element.data('inview', visiblePartsMerged).trigger('inview', [true, visiblePartX, visiblePartY]);
Right before this, add
if ($element.prev(".inview").length < 1)
So that it checks whether there is an element with class 'inview' before the one for which it wants to trigger the event 'inview' with visible = true.
Related
I want to hide the clickable preview icons on an angular-modal-gallery running on an angular 5 SPA component. As the modal is going to be triggered through a bootstrap button.
I have the following in my component.html;
<ks-modal-gallery [id]="1" [modalImages]="images"></ks-modal-gallery>
From inspecting I can see that it generates a div with the class plain-container. I have tried overriding this class in the component.css;
.plain-container {
display:none !important; }
However, this isn't been applied (I assume because of the point of html is being generated).
Can anyone help find a solution to this?
You can add the CSS globally in your style.css file. It will surely work.
add boolean isGalleryOpen = false, and set attr hidden with it.
isGalleryOpen = false;
open method
openModalViaService(id: number | undefined, index: number) {
this.isGalleryOpen = true;
this.galleryService.openGallery(id, index);
}
In HTML turn boolean false on close event.
<ks-modal-gallery [attr.hidden]="isGalleryOpen === true ? null : 'true'"
(close)="isGalleryOpen=false;" [id]="1" [modalImages]="images"></ks-modal-gallery>
I'm creating component based Tab functionality. Please find the code here
deleteTab: function(selectedTab){
this.tabs = this.tabs.filter(function(tab){
return tab._uid != selectedTab._uid
});
}
In there I've added remove button, which needs to remove the tab and tab details block. Anyone know how to remove the tab details?
I will suggest you to follow this video laracasts for a better code.
To delete your tab and content, you will need to do:
deleteTab: function(tab){
tab.isActive=false;
index = this.tabs.indexOf(tab);
if (index > -1) {
this.tabs.splice(index, 1);
}
console.log(tab)
}
check fiddle
After some blood, sweat and luckily no tears I've managed to create a drag and drop system which fits my needs.
There are only 2 things that are almost triggering my tears...
Here's the jsfiddle
The problem is in these lines of code, but can't find it:
if (dropped === original) {
$("#dropzone").append('<li class="placeholder" data-id="" data-order="" data-content=""></li>');
init();
}
$(".remove").click(function() {
var removable = $(this).parent();
if (dropped > original) {
removable.remove();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
} else {
removable.empty();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
}
init();
});
So now the explanation and my goal:
There are 5 days and on default the placeholders will dynamicly increase with the number of days. If the max limit of placeholders is filled, another one will be appended. Now, after the not-default placeholder is appended and I delete a previous filled placeholder, I can't allow it to be droppable again.
Difficult to explain, but see the demo above ^
Extra: I would like to be able to drag items between those placeholders. But can't find a way either.
Thanks for the help!
You don't seem to reactivate the droppable on delete. And also, destroy them on drop might make you need to recreate them. You could use disable on drop and enable when deleting. Like this:
drop: function (event, ui) {
var dragging = ui.draggable.clone().find("img").remove();
$(this).append(dragging).addClass("dropped");
$(this).droppable('disable');
And later:
if (dropped > original) {
$(this).parent().droppable('enable')
removable.remove();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
} else {
$(this).parent().droppable('enable');
removable.empty();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
}
http://jsfiddle.net/opmd46t2/3/
I am trying to use 2 jQuery navigation scripts on one page (Superfish for desktops and FlexNav for mobile). I am currently using matchMedia along with the polyfill by Paul Irish to respond to CSS3 media query state changes within JavaScript.
The current code is only accomplishing 50% of the overall goal. If you access the web page initially with a window size equal to or greater than 999px wide then you get Superfish and if you initially access the web page with a window size less than 999px then you get FlexNav. The problem occurs when you resize the window above or below 999px as both scripts become active.
// media query event handler
if (matchMedia) {
var mq = window.matchMedia("(min-width: 999px)");
mq.addListener(WidthChange);
WidthChange(mq);
}
// media query change
function WidthChange(mq) {
if (mq.matches) {
$("ul.sf-menu").superfish({
delay: 350,
speed: 400,
});
} else {
$("ul.flexnav").flexNav({
'animationSpeed': '250',
'transitionOpacity': true,
'buttonSelector': '.menu-button',
'hoverIntent': false
});
}
}
As much as I would like to get this working with matchMedia, I am open to all suggestions.
Update: Thanks to Stephan's suggestion I now have the following code:
jQuery(document).ready(function () {
// add destroy function for FlexNav
flexNavDestroy = function () {
$('.touch-button').off('touchstart click').remove();
$('.item-with-ul *').off('focus');
}
// media query event handler
if (matchMedia) {
var mq = window.matchMedia("(min-width: 999px)");
mq.addListener(WidthChange);
WidthChange(mq);
}
// media query change
function WidthChange(mq) {
if (mq.matches) {
if (typeof (flexNav) != "undefined") {
flexNavDestroy();
}
superfish = $("ul.sf-menu").superfish({
delay: 350,
speed: 400,
});
} else {
if (typeof (superfish) != "undefined") {
superfish.superfish('destroy');
}
flexNav = $("ul.flexnav").flexNav({
'animationSpeed': '250',
'transitionOpacity': true,
'buttonSelector': '.menu-button',
'hoverIntent': false
});
}
}
});
Remaining Issue:
The destroy function for FlexNav is only partially destroying it.
The best way would probably be to destroy the other plugin when you're activating one.
If I look in the source of Superfish there is a destroy function which does this, but flexNav doesn't have such a function. You can create one though:
flexNavDestroy = function(){
$('.touch-button').off('touchstart click').remove();
$(('.item-with-ul *').off('focus');
}
Then you could do this:
function WidthChange(mq) {
if (mq.matches) {
if(typeof(flexNav) != "undefined") {
flexNavDestroy();
}
superfish = $("ul.sf-menu").superfish({
delay: 350,
speed: 400,
});
} else {
if(typeof(superfish) != "undefined") {
superfish.superfish('destroy');
}
flexNav = $("ul.flexnav").flexNav({
'animationSpeed': '250',
'transitionOpacity': true,
'buttonSelector': '.menu-button',
'hoverIntent': false
});
}
}
UPDATE
I've looked a little bit more into FlexNav, and there's a few things I missed.
I think the styles are colliding because FlexNav sets a lot of styles by default. We can easily prevent that by using two classes: One for flexnav styling (the default .flexnav) that we can remove to hide all it's styles, and one for binding the javascript function (that will always stay there, or we can't re-attach it).
I generally like to prepend any classes that are meant as JS hooks with js-, so in my example (below) I replaces the .flexnav class on the menu with .js-flexnav. Then to activate flexnav you have to add this line just before you call $('ul.flexnav').flexNav()
$('.js-flexnav').addClass('flexnav');
In the destroy function you will have to remove the class again, which I will show shortly.
In addition, I'm not sure how Superfish does the showing and hiding, but since FlexNav collapses all submenus, it's also safe to say you should re-show them so that Superfish can do it's own thing.
The updated destroy function to reflect this:
function flexNavDestroy(){
$('.touch-button').off('touchstart click').remove();
$('.item-with-ul *').off('focus');
$('.js-flexnav').removeClass('flexnav').find('ul').show(); // removes .flexnav for styling, then shows all children ul's
}
Here's a jsFiddle that shows activating/deactivating flexNav with the new code: http://jsfiddle.net/9HndJ/
Let me know if this does the trick for you!
here is an alternative path :
once page is loaded :
cache the menu in a jquery object, clone it & instantiate both plugin one on each clone
$menucontainer= $("#menu_container");
$memufish = $menucontainer.find(".menu");
$menuflex=$menufish.clone();
$menufish.superfish().detach();
$menuflex.prependTo($menucontainer).flexnav().detach();
(they are loaded anyway so it's no big deal even if most of the time one won't be needed, it will be there & ready just in case - however test if you can instantiate on the clone without appending it to the DOM)
depending on width append / prepend the required one
$menuflex.prependTo($menucontainer);
on change width detach one reattach the other
$menufish.detach();
$menuflex.prependTo($menucontainer);
you could also work your way checking if plugin was instantiated on a width change (in order to not instantiate uselessly onload) but in any way I believe the use of clone() and detach() are very much adapted to solve easily your problem. The destroy way seems to be a hassle, lots of work (for the script as well when some user is raving with window resize) loss of time & a risk of many bugs to me ( expect more and more lag at every destroy re instantiate - with detach() no worries)
cons : will use a bit more memory overhaul
pros :
script will work less & it will be real fast to switch from one to the other
you could make a plugin from this and add other menu plugin to your app very easily without worry about conflict and how to destroy
I asked this over at the jQuery Tools official forum last week, but it's definitely not as active as stackoverflow, so thought I would ask over here as well.
On our project detail pages, we're dynamically loading content in that uses a vertical scroller to navigate through. Problem is that the height of the vertical scroller always seems to be one item too tall. I cannot find any way to affect this programmatically.
If I set it circular to true, it seems to have the correct height, but we don't want it to be continuous/circular.
Example here:
http://www.centerline.net/projects/detail/?p=21
Unminified JS is here:
http://www.centerline.net/lib/js/site-unmin.js
Any ideas?
Here's the view of what it should look like when scrolled to the last item (down arrow disappears, and does not allow a blank area below the last thumbnail.
The solution above looked like it would have worked, but also found a solution here:
http://www.jasoncarr.com/technology/jquery-tools-scrollable-stop-scrolling-past-the-end
Actual code for my site was as such:
$(function() {
// Initialize the Scrollable control
$(".scroll").scrollable({vertical:true, mousewheel:true, keyboard:true });
// Get the Scrollable control
var scrollable = jQuery(".scroll").data("scrollable");
// Set to the number of visible items
var size = 2;
// Handle the Scrollable control's onSeek event
scrollable.onSeek(function(event, index) {
// Check to see if we're at the end
if (this.getIndex() >= this.getSize() - size) {
// Disable the Next link
jQuery("a.next").addClass("disabled");
}
});
// Handle the Scrollable control's onBeforeSeek event
scrollable.onBeforeSeek(function(event, index) {
// Check to see if we're at the end
if (this.getIndex() >= this.getSize() - size) {
// Check to see if we're trying to move forward
if (index > this.getIndex()) {
// Cancel navigation
return false;
}
}
});
});
Unfortunately the number of divs in the .items container should be divisible by the number of items you want to show at a time. So you have 3 divs but you are showing 2 items at a time. That is why the scrollable plugin malfunctions.
You can either open the nonminified source and change it a little bit which shoudn't be very difficult.
Or much simpler solution would be to either add a new div and make it 4 to 2.
Or Drop the number of items you show at a time to 1 and increase the height of your divs.
Using another plugin may work too.
Hope it helps
The problem is that jQuery tools srolls all images. And after the last images there just is some empty space.
Try to add this to the scrollable constructor
$('.scroll').scrollable({
onBeforeSeek: function(e, index) {
if (index == $('.items').size()) {
return false;
}
},
onSeek: function(e, index) {
if (index == $('.items').size()-1) {
$('.next').hide(0);
} else {
if ($('.next').is(':hidden')) {
$('.next').show();
}
}
}
});
OR
api = $('.scroll').scrollable({
//your setup code
});
api.onBeforeSeek: function(e, index) {
if (index == this.getSize()) {
return false;
}
}
api.onSeek: function(e, index) {
if (index == this.getSize()-1) {
$('.next').hide(0);
} else {
if ($('.next').is(':hidden')) {
$('.next').show();
}
}
}
Disclaimer: Im no expert. I have not tested this. Your code is minified, can't see it clearly. I hardly use jQuery tools. But I think this would be the way to go.