My accordion is working properly, but I'm having a JS issue that are prohibiting it from displaying correctly.
http://jsfiddle.net/frEWQ/4/
The JS is not applying .ui-corners-all to the H3 after the "kwick" div below it has finished collapsing, giving an odd cut-off border after the animation
Any suggestions?
Thanks
// find elements to show and hide
var toShow = clicked.next(),
toHide = this.active.next(),
data = {
options: o,
newHeader: clickedIsActive && o.collapsible ? $([]) : clicked,
oldHeader: this.active,
newContent: clickedIsActive && o.collapsible ? $([]) : toShow,
oldContent: toHide
},
down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
this.active = clickedIsActive ? $([]) : clicked;
this._toggle(toShow, toHide, data, clickedIsActive, down);
// switch classes
this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all")
.find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header);
if (!clickedIsActive) {
clicked.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top")
.find(".ui-icon").removeClass(o.icons.header).addClass(o.icons.headerSelected);
clicked.next().addClass('ui-accordion-content-active');
}
return;
Updated:
You could modify the source, but that isn't generally a good idea.
Because it's expecting that specific format you may need to do something tricky with CSS to avoid that flicker.
How about have full 20px border-radius on all corners of the h3 at all times, even when the element is expanded.
Have the content use some styles like the following:
padding-top:20px; position:relative; top:-20px; or something similar that will pad 20px and then correct the position by pulling it back up. That way, when it expands it's actually overlapping the h3 bottom corners. If that didn't work padding-top:20px; margin-top:-20px; might.
In my mind this works. I'd try it on your jfiddle post but you haven't put the css source into the css frame.
Related
I have a custom icon element that is only displayed when its specific row in the table is hovered over, but when I scroll down without moving my mouse it doesn't update the hover and maintains the button on the screen and over my table's header. How can I make sure this doesn't happen?
export const StyleTr = styled.tr`
z-index: ${({ theme }) => theme.zIndex.userMenu};
&:hover {
background-color: ${({ theme, isData }) =>
isData ? theme.colors.primary.lighter : theme.colors.white};
div {
visibility: visible;
}
svg[icon] {
display: initial;
}
}
`;
I was just working on something similar to this for a web scraper recently.
Something like this should work:
function checkIfIconInViewport() {
// define current viewport (maximum browser compatability use both calls)
const viewportHeight =
window.innerHeight || document.documentElement.clientHeight;
//Get our Icon
let icon = document.getElementById('icon');
let iPos = icon.getBoundingClientRect();
//Show if any part of icon is visible:
if (viewportHeight - iPos.top > 0 && iPos.bottom > 0) {
icon.style.visibility = visibile;
}
else { icon.style.visibility = hidden; }
//Show only if all of icon is visible:
if (iPos.bottom > 0 && iPos.top >= 0) {
{
icon.style.visibility = visibile;
}
else { icon.style.visibility = hidden; }
//Add && iPos.bottom <= viewportHeight to the if check above for very large elements.
{
//Run function everytime that the window is scrolled.
document.addEventListener('scroll', checkIfIconInViewport);
Basically, every time a scroll event happens, we just check to see if the top & bottom of our element (the icon in your case) are within the bounds of the viewport.
Negative values, or values greater than the viewport's height mean that the respective portion of the element is outside the viewport's boundary.
Hopefully this helps! If you are dealing with a large quantity of objects, it may make sense to bundle the objects you are tracking together into an array and check each of them in a single function call to avoid saving function definitions for each individual object.
Edit: I just realized that I misunderstood your issue a bit. I think you can get by with just the bottom part of the code, and when a scroll event happens, set the icon's visibility to hidden. Assuming you want to hide it whenever the user scrolls?
Have you tried getting the scroll position of the DOM, then disabling (removing) the element once a certain scroll position is reached?
I have been trying to make a fullscreen menu toggle with smooth fade in and out.
That works fine with all elements except for svg elements and picture.
Basically when you click on the menu burger you can clearly see the image and the svg icons not fading out, everything else does, but not these elements.
At first I thought it could be a z-index related problem and changed the numbers around but nothing worked.
I have been trying to find information about this for days but can't find anything on it.
I would highly appreciate your help on this, thank you.
Heres my fiddle
And code:
(function () {
"use strict";
var toggles = document.querySelectorAll(".c-hamburger");
for (var i = toggles.length - 1; i >= 0; i--) {
var toggle = toggles[i];
toggleHandler(toggle);
};
function toggleHandler(toggle) {
toggle.addEventListener("click", function (e) {
e.preventDefault();
(this.classList.contains("is-active") === true) ? this.classList.remove("is-active") || $("#testMenu").fadeOut(300) : this.classList.add("is-active") || $("#testMenu").fadeIn(300);
});
}
})();
It happens because menu container is listed before image in source so it has lower index in z axis. Make #testMenu on the top with z-index and position:relative
<nav id="testMenu" style="display: none; z-index: 1000; position: relative;">
To control the z-index, the element must have a stacking order, like declaring a position.
When you introduce the position property into the mix, any positioned elements (and their children) are displayed in front of any non-positioned elements.
Try for example, changing this:
#contact {
z-index: -1;
position: relative;
...
}
Here is the working fiddle
I'm customizing the following script: http://tympanus.net/Tutorials/ExpandingImageMenu/index_3.html
But instead of 6 divs (or the 6 guys in this case), I have 11 where the 4 last divs are opened with a custom navigation.
But I want to make the last 4 divs wider in size, if possible a variable size to fill up the right side of the content div.
How should I do this?
Thanks in advance!
/* get the item for the current */
var $item = $menuItems.eq(current);
var $item2 = $menuItems + 7; /* i added this line */
&
/* if not just show it */
$item.css({width : '400px'})
$item2.css({width : '700px'}) /* and this one */
.find('.ei_image')
.css({left:'0px', opacity:1,});
Iv'e tried the + + + + + css thingie but no luck for me, but I've uploaded the site...
http://www.vernietig.be/depandoering/index2.html
There are a couple of things wrong at the moment. Firstly, the second line of code you added is actually part of some chained methods.
You don't need the first line of code you added.
After examining the script it looks like the current variable holds a zero based array index of the items in the trigger list. If it is not zero based you may need to change 6 to 7 in the code below (or to whatever is appropriate).
What I would suggest is:
/* if not just show it */
var itemWidth = current < 6 ? '400px' : '700px';
$item.css({width : itemWidth})
.find('.ei_image')
.css({left:'0px', opacity:1,});
EDIT: Update to include another line of code to change
Ok, You can also try changing this line:
itemParam = (dir) ? {width : '400px'} : {width : '75px'},
to
itemParam = (dir) ? current < 7 ? {width : '400px'} : {width : '700px'} : {width : '75px'},
EDIT 2: Update found a css change
In your css for .ei_menu ul remove width: 1300px;
And if you don't want the scrollbar to appear you can also remove overflow: scroll; from .ei_descr2.
EDIT 3: Update for last 4 divs to have variable width.
You can just change .ei_descr2 where you tried width: 100%; to be min-width: 300px; that will cause the divs to have min-width of 300px and they will expand for more content if required. NOTE: you can change the min-width value to be whatever you like.
You can try to use the css nth-child, check example in jsfiddle below
div{
width:20px;
height:100px;
float:left;
margin:1px;
background:blue;
}
div:nth-child(n+7){
width:100px;
}
http://jsfiddle.net/k39B7/1/
Pleasantries
I've been playing around with this idea for a couple of days but can't seem to get a good grasp of it. I feel I'm almost there, but could use some help. I'm probably going to slap myself right in the head when I get an answer.
Actual Problem
I have a series of <articles> in my <section>, they are generated with php (and TWIG). The <article> tags have an image and a paragraph within them. On the page, only the image is visible. Once the user clicks on the image, the article expands horizontally and the paragraph is revealed. The article also animates left, thus taking up the entire width of the section and leaving all other articles hidden behind it.
I have accomplished this portion of the effect without problem. The real issue is getting the article back to where it originally was. Within the article is a "Close" <button>. Once the button is clicked, the effect needs to be reversed (ie. The article returns to original size, only showing the image, and returns to its original position.)
Current Theory
I think I need to retrieve the offset().left information from each article per section, and make sure it's associated with its respective article, so that the article knows where to go once the "Close" button is clicked. I'm of course open to different interpretations.
I've been trying to use the $.each, each(), $.map, map() and toArray() functions to know avail.
Actual Code
/*CSS*/
section > article.window {
width:170px;
height:200px;
padding:0;
margin:4px 0 0 4px;
position:relative;
float:left;
overflow:hidden;
}
section > article.window:nth-child(1) {margin-left:0;}
<!--HTML-->
<article class="window">
<img alt="Title-1" />
<p><!-- I'm a paragraph filled with text --></p>
<button class="sClose">Close</button>
</article>
<article class="window">
<!-- Ditto + 2 more -->
</article>
Failed Attempt Example
function winSlide() {
var aO = $(this).parent().offset()
var aOL = aO.left
var dO = $(this).offset()
var dOL = dO.left
var dOT = dO.top
var adTravel = dOL-aOL
$(this).addClass('windowOP');
$(this).children('div').animate({left:-(adTravel-3)+'px', width:'740px'},250)
$(this).children('div').append('<button class="sClose">Close</button>');
$(this).unbind('click', winSlide);
}
$('.window').on('click', winSlide)
$('.window').on('click', 'button.sClose', function() {
var wW = $(this).parents('.window').width()
var aO = $(this).parents('section').offset()
var aOL = aO.left
var pOL = $(this).parents('.window').offset().left
var apTravel = pOL - aOL
$(this).parent('div').animate({left:'+='+apTravel+'px'},250).delay(250, function() {$(this).animate({width:wW+'px'},250); $('.window').removeClass('windowOP');})
$('.window').bind('click', winSlide)
})
Before you go scratching your head, I have to make a note that this attempt involved an extra div within the article. The idea was to have the article's overflow set to visible (.addclass('windowOP')) with the div moving around freely. This method actually did work... almost. The animation would fail after it fired off a second time. Also for some reason when closing the first article, the left margin was property was ignored.
ie.
First time a window is clicked: Performs open animation flawlessly
First time window's close button is clicked: Performs close animation flawlessly, returns original position
Second time SAME window is clicked: Animation fails, but opens to correct size
Second time window's close button is clicked (if visible): Nothing happens
Thank you for your patience. If you need anymore information, just ask.
EDIT
Added a jsfiddle after tinkering with Flambino's code.
http://jsfiddle.net/6RV88/66/
The articles that are not clicked need to remain where they are. Having problems achieving that now.
If you want to go for storing the offsets, you can use jQuery's .data method to store data "on" the elements and retrieve it later:
// Store offset before any animations
// (using .each here, but it could also be done in a click handler,
// before starting the animation)
$(".window").each(function () {
$(this).data("closedOffset", $(this).position());
});
// Retrieve the offsets later
$('.window').on('click', 'button.sClose', function() {
var originalOffset = $(this).data("originalOffset");
// ...
});
Here's a (very) simple jsfiddle example
Update: And here's a more fleshed-out one
Big thanks to Flambino
I was able to create the effect desired. You can see it here: http://jsfiddle.net/gck2Y/ or you can look below to see the code and some explanations.
Rather than having each article's offset be remembered, I used margins on the clicked article's siblings. It's not exactly pretty, but it works exceptionally well.
<!-- HTML -->
<section>
<article>Click!</article>
<article>Me Too</article>
<article>Me Three</article>
<article>I Aswell</article>
</section>
/* CSS */
section {
position: relative;
width: 404px;
border: 1px solid #000;
height: 100px;
overflow:hidden
}
article {
height:100px;
width:100px;
position: relative;
float:left;
background: green;
border-right:1px solid orange;
}
.expanded {z-index:2;}
//Javascript
var element = $("article");
element.on("click", function () {
if( !$(this).hasClass("expanded") ) {
$(this).addClass("expanded");
$(this).data("originalOffset", $(this).offset().left);
element.data("originalSize", {
width: element.width(),
height: element.height()
});
var aOffset = $(this).data("originalOffset");
var aOuterWidth = $(this).outerWidth();
if(!$(this).is('article:first-child')){
$(this).prev().css('margin-right',aOuterWidth)
} else {
$(this).next().css('margin-left',aOuterWidth)
}
$(this).css({'position':'absolute','left':aOffset});
$(this).animate({
left: 0,
width: "100%"
}, 500);
} else {
var offset = $(this).data("originalOffset");
var size = $(this).data("originalSize");
$(this).animate({
left: offset + "px",
width: size.width + "px"
}, 500, function () {
$(this).removeClass("expanded");
$(this).prev().css('margin-right','0')
$(this).next().css('margin-left','0')
element.css({'position':'relative','left':0});
});
}
});
I need to fit text in div box with exact width.
Is there a way (for example with javascript) to make the text look the same size in all major browsers?
For example strip some letters if text does not fit 'div' box.
Just add the following properties to the CSS rule for your div:
overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
You can see this in action here (JSFiddle).
First of, set your font face and size with css. Then you will almost always have the same width.
Then you can add overflow: hidden; to your div so it won't show anything that goes past the end.
Depending on how you're doing this, you could use padding and margins without setting a width, that way it will always fit in the div. Although this may not be what you want.
You can truncate your text with CSS or with JavaScript. Here's an example of a simple JQuery truncation plugin I wrote which allows for a "show more" link if the text is truncated:
$.fn.trunc = function(_break_at) {
var _article = jQuery(this).text();
var _leader = [];
var _trailer = [];
var _substr = _article.split(' ');
$(this).wrapInner('<div class="long"></div>');
$.each(_substr, function(i, data) {
if (i < _break_at) {
_leader.push(data);
}
});
if (_substr.length > _break_at) {
$('<div/>').addClass('short').html(_leader.join(' ')).prependTo(this);
$('<span/>').appendTo('.long').addClass('toggle').html(' << Show less');
$('<span/>').appendTo('.short').addClass('toggle').html('... Show more >>');
}
$('.toggle').click(function() {
$('.short, .long').toggle('show');
});
};
$(function() {
// This is how you use it
$('#article_body').trunc(2);
});
http://jsfiddle.net/AlienWebguy/7ZamJ