Dynamic Links and jQuery Lightbox issue : Loading image in lightbox...completely stumped! - javascript

I have a function that dynamically creates links for a photo gallery. The function also produces a larger image as a background image of a div when and thumbnail is clicked on. What I want to do is have a third event, where if the user clicks the enlarged image in the div, the jQuery Fancybox loads an even bigger version of the image being displayed in the div. The problem is that the link for the anchor tag I'm using is created dynamically, and I know that Fancybox parses the HTML when the DOM is ready...unfortunately my function changes the DOM by appending the anchor tag for the full sized image. The help I need is using the Fancybox's options to specify the href attribute for the plugin. I'm sorry that was so long-winded...here's the code.
jQuery:
function gallery(picid, picnum){
var ext = 'jpg';
var fullSize = 'imgs/'+picid+'_full.'+ext;
$('#photolarge').css("background", 'url(imgs/'+picid+'_large.'+ext+') no-repeat');
$('#photolarge a').attr(
{ href: fullSize
//rel: 'lightbox',
}
);
$("#lightboxlink").click(function(){
$('#lightboxlink').fancybox({
'autoDimensions' : false,
'width' : 'auto',
'height' : 'auto',
'href' : fullSize
});
});
return false;
}
HTML Snippet
<div id="photolarge">
<a id="lightboxlink" href="#"></a>
</div>
<div id="phototable">
<ul id="photorow1">
<li><a onclick="gallery('bigsun',1)"><img id="sun" src="imgs/bigsun.jpg" /></a></li>
</ul>
</div>
Subsequent CSS:
#photolarge {
width: 590px;
height: 400px;
margin-left: 7px;
border: 2px solid;
background: none;}
#phototable {
width: 590px;
height: 300px;
border: 2px solid;
margin: 10px 0 0 7px;}
#phototable img {
cursor: pointer;}
#phototable ul {
list-style: none;
display: inline;}
#phototable li {
padding-left: 10px;}
#lightboxlink {
display: block;
height: 100%;
width: 100%;}
Any help would be greatly appreciated!!!

You can use .live() for the event handler, and .triggerHandler() to immediately open the lightbox, like this:
$("#lightboxlink").live('click', function(e){
$(this).filter(':not(.fb)').fancybox({
'autoDimensions' : false,
'width' : 'auto',
'height' : 'auto',
'href' : fullSize
}).addClass('fb');
$(this).triggerHandler('click');
e.preventDefault(); //prevent opening in new window
});
This runs .fancybox() on the link, but only if we haven't already run it, which we're tracking with a .fb class addition. Whether it's a new or fresh bind, we need to trigger the click handler, which is what fancybox listens to in order to open.

Related

preventDefault() on first touch but still allow scrolling/touchmove

I have a few elements on my site in which there is content that only appears when you hover on the element. A perfect example would be the Instagram feed grid. I'm pulling in the last 8 images from an Instagram account using their API and displaying them in a grid with flexbox. When you :hover over one of the images with a mouse, a semi-transparent black overlay fades in, containing the caption of the Instagram post.
On desktop you are able to click anywhere on the image/hovered caption overlay as they are both wrapped in an <a> element and doing so takes you to the post on Instagram's website. This works perfectly on desktop, but on touch devices does not.
Because you can't :hover on touch devices, I decided to implement some javascript on the touchstart event that uses e.preventDefault() to stop the link from being clicked when you tap the Instagram image and instead adds the CSS opacity: 1 and visibility: visible to the overlay element (which is what happens when you :hover on the element). Because the overlay element is then "on top" of the image when it's made visible, the link is clickable because the touchstart event is only listened for on the image.
This all works great and means that I can tap once on the image which fades in the overlay and doesn't take me to the image on Instagram, and I can then click for the second time on the overlay, taking me to the image on Instagram.
The problem
Because I am using e.preventDefault() in the touchstart event, if you touch the image and then start dragging your finger to scroll, the page doesn't scroll at all which results in a bad user experience.
So...
How can I only preventDefault() on a single touch event, or how can I prevent the link from being clicked on the first touch of the element but not on the second whilst still allowing the user to scroll/drag the page?
Slightly simplified version of my code
function toggleHoveredStateOn(e) {
e.preventDefault();
let hoverElem = this.querySelector('.js-touch-hover');
// remove all 'visible' classes from other "hovered" items first
document.querySelectorAll('.js-touch-trigger').forEach(touchTrigger => {
let hoverElem = touchTrigger.querySelector('.js-touch-hover');
Object.assign(hoverElem.style, {
visibility: 'hidden',
opacity: '0',
pointerEvents: 'none'
});
});
// add visible to the touched element's hover element
Object.assign(hoverElem.style, {
visibility: 'visible',
opacity: '1',
pointerEvents: 'all'
});
}
function initMobileTouchFunctionality() {
let touchTriggers = [...document.querySelectorAll('.js-touch-trigger')];
touchTriggers.forEach(touchTrigger => {
touchTrigger.addEventListener('touchstart', toggleHoveredStateOn, false);
touchTrigger.querySelector('.js-touch-hover').addEventListener('touchstart', function(e) {
e.stopPropagation();
}, false);
});
}
initMobileTouchFunctionality();
.flex-grid__item {
position: relative;
height: 263px;
border: 1px solid #FFF;
&:hover {
.flex-grid--social__hover {
opacity: 1;
visibility: visible;
pointer-events: auto;
}
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.flex-grid--social__hover {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
background-color: rgba(0, 0, 0, 0.8);
padding: 20px;
transition: opacity 0.2s ease-in-out;
opacity: 0;
visibility: hidden;
overflow: hidden;
pointer-events: none;
cursor: pointer;
}
<div class="flex-grid__item js-touch-trigger">
<a href="<?php // link to instagram. php code gets this ?>">
<img class="" src="<?php // instagram image. php code gets this ?>"/>
<div class="flex-grid--social__hover js-touch-hover">
<p><?php // instagram caption. php gets this ?></p>
</div>
</a>
</div>
You can decide whether to e.preventDefault or not using the e.target to see if the user tapped the image or the overlay.
You can read more at https://developer.mozilla.org/en-US/docs/Web/API/Event/target

JS: Resize div when an iframe was clicked?

I have an entire <iframe /> with a div as parent. That iframe came from different domain. How do you resize it bigger (add class in my case) the parent div when the iframe was click? and resize it back when a close button of the iframe is clicked?
I preferred if the button from iframe does the resize but apparently the div cannot be reached INSIDE the iframe, so I have to do it OUTSIDE the iframe.
I had the same problem and wrote a jquery plugin.
https://github.com/BergenSoft/iframeActivationListener
See example:
http://jsfiddle.net/56g7uLub/3/
How to use:
$(document).ready(function ()
{
$('iframe').iframeActivationListener();
$('iframe').on("activate", function(ev) {
$(ev.target).addClass("big");
});
});
This plugin don't use overlaying divs.
It checks if the mouse is on an inactive iframe and starts watching the activeElement of the document.
When it changes to another iframe, the custom event "activate" will be raised.
This is the best solution I found out.
You will have to create some kind of overlay to detect the initial focus event of the iframe. The close button can also be part of your website still if you show it based on class.
http://jsfiddle.net/cxtgn72g/4/
HTML
<div id="iframe">
<div id="overlay"></div>
<div id="close">X</div>
<iframe src="//www.youtube.com/embed/6PRq7CmiWhM?list=PLIOa6mDiSeismsV_7YFti-5XOGRzmofSZ"></iframe>
</div>
JS - Requires jQuery
$("#overlay").click(function() {
$("#iframe").addClass("big");
});
$("#close").click(function() {
$("#iframe").removeClass("big");
});
CSS
#iframe {
width : 500px;
height : 300px;
position : relative;
}
#iframe.big {
width : 600px;
height : 400px;
}
iframe {
width : 100%;
height : 100%;
border : none;
}
#overlay {
position : absolute;
left : 0;
top : 0;
width : 100%;
height : 100%;
}
#close {
display : none;
}
.big #close {
cursor : pointer;
display : block;
position : absolute;
right : 10px;
top : 10px;
content : "X";
background : red;
color : white;
border-radius : 25%;
padding : 8px;
}
.big #overlay {
display : none;
}
Try this:
document.getElementById("myIFrame").onclick = function(){
document.getElementById("myDiv").className = ""; //New Class Name
};
Good Luck!

Load Images only after mouseover on URL (using DIV Tag)

I'm using this method, to show a Picture only after a URL-mouseover:
TITLE<span><img src="IMAGE-URL"></span>
So the Picture only gets showed, after the mouseover. The problem is, while using this method, ALL Pictures are getting loading from the server after opening the site. They may not show, but they get loaded. So if you have 100 Links with a mouseover image, all 100 images gets loaded after opening the site, which creates big traffic.
Is there any code, that makes the pictures inside the Tag only get loaded from the server, >IF< there is a mouseover?
This is the CSS:
a.infotext{
text-decoration: none;
}
a:hover.infotext {
color: #E2E2E2;
text-decoration: none;
}
a.infotext span {
visibility: hidden;
position: absolute;
left: 2em;
margin-top: 2em;
padding: 1em;
text-decoration: none;
}
a:hover.infotext span {
visibility: visible;
border: 1px solid #292929;
color: #347BEE;
background: #040404;
text-decoration: none;
width: 432px
}
I know this isn't a css approach but I've create a quick (non-styled) demo using onmouseover to load the image conditionally, javascript will allow you to target specific images. Hope this could help!
Javascript
function loading()
{
var image = document.getElementById('image');
image.setAttribute('src', 'img/placeholder.png');
}
And here is the HTML
Load image
<img id="image" src="" alt="">
Remove the Image tag. give the span a data-imgsrc:
<span data-imgsrc="IMAGE-URL"> </span>
On hover append() the img-tag and remove it
$( "a" ).hover(
function() {
var that = $( this ).next("span[data-imgsrc='IMAGE-URL']");
that.append( '<img src='+ that..attr("data-imgsrc")+'/>' );
}, function() {
$( this ).removeit;
}
);
Written without testing but i hope you get the idea, and better then pseudo code.

jQuery hide() and show() not working as expected

I am trying to display a hidden div (with a class .details) whenever a mouse hover at an element .tags in a page. This is working but not as expected.
I want the mouse should be able to enter the displayed .details and should even be able to click on its contents as we have here in StackOverflow tags
but the moment the mouse leaves .tags everything disappears. How can I delay the appearance of .details and have it allow mouse to select
its content whenever a mouse hovers over .tags?
HTML code:
<div class = 'tags'>
<div class='details'>
<a href='a.html'> jQuery </a>
<a href='b.html'> PHP </a>
<a href='c.html'> MySQL </a>
<a href='d.html'> Ruby on Rails </a>
</div>
</div>
CSS code:
.details {
background-color: rgb(235,243,243);
border-radius: 7px;
padding: 3px;
width: 240px;
float: left;
position: relative;
margin-top: 5px;
font-weight: 400;
}
jQuery code:
$(document).ready(function(){
$('.details').hide();
$(document).on('mouseover', ".tags", function () {
var $this = $(this);
$this.find('.details').slideDown(100);
});
$(document).on('mouseleave', ".tags", function () {
var $this = $(this);
$this.find('.details').hide();
});
});
Thank you in advance.
Create jsfiddle for answer. The problem is in .parents('.tags'), because $this is already tabs element. And $this.parents('.tags') returns empty jQuery object.
Add this style to your page and see if this helps
.tags {
height: 100px;
width: 200px;
}
the reason is because the .tags div is so small. Even though the .details div populates the .tags div it doesn't force the size of the element to increase.
which is why it is so hard for you to navigate across the .details div
You are hiding the tag that you want to control the mouse over event for.
Also, look at this way of setting up the selector, it makes it far more readable:
$(".tags").on('mouseover', function () {
alert("hi");
});
http://jsfiddle.net/tVEkF/

grow/shrink image gallery with jquery WITHOUT affecting the layout

I got an image gallery organized as an <ul>. all images are in <li> elements and when I move my mouse over one of those pictures, it should grow to give the user a visual feedback. thing is, when I just change the size of the image using animate(), the other pictures will be pushed to the side as the resized image uses more space.
therefore I went with cloning the image element, float it right over the original image and then calling animate. this comes with the problem that onMouseOut() is called as soon as the cloned images pops up. so I need a nested hover() function and this is where things got complicated.
I got two errors and I can't find out whats causing them. the first one is, that animate() won't let the cloned image grow beyond the right border of its original, the second is, that I get weird grow/shrink behavior, when moving my mouse quickly over the gallery.
html:
<ul id="gallery1" class="gallery_container">
<li class="frame">
<img src="pic1.jpg" class="picture" /></li><li class="frame">
<img src="pic2.jpg" class="picture" /></li><li class="frame">
<img src="pic3.jpg" class="picture" /></li>
</ul>
css:
.picture
{
height: 200px;
border: 0px;
margin: 0px;
padding: 0px;
}
.frame
{
display: inline-block;
position: relative;
margin: 0px;
margin-right:8px;
padding: 0px;
}
.frame a
{
padding: 0px;
margin: 0px;
}
.gallery_container
{
height: 200px;
width: 150%;
position: relative;
top: 4px;
padding: 0px;
margin: 0px;
}
and finally the code that is giving me those headaches:
$(document).ready(function()
{
var zooming = false;
var zoom = 4;
var speed_zoom = 100;
$('.gallery_container li a').hover(function(element)
{
// disable zooming to prevent unwanted behavior
if(zooming) return;
zooming = true;
$(this).after( $(this).clone(false) );
$(this).next().attr('id', 'focus_frame');
},
function(element) // when the new element pops up, onmouseout is triggered, since the focus_frame is in front of the image
{
$(this).next().hover(function(element)
{
// we need to re-position the element in the dom-tree, since it needs to grow out of a container with overflow: hidden
$('#focus_frame img').animate({'left' : zoom * -1, 'top' : zoom * -1, 'height' : 200+(zoom*2), 'width' : $('#focus_frame img').outerWidth() + (zoom*2)}, speed_zoom);
},
function(element)
{
$(this).remove();
zooming = false;
});
});
});
var $doc=$(document.body)
$doc.on({
"mouseenter" : function (e) {
$doc.find("> .gallery_clone").remove();
var $i=$(this).parent();
$i.pos = $i.offset();
$i.clone()
.addClass("gallery_clone "+$i.parent().parent().attr("class"))
.css({
top:(Math.round($i.pos.top)-3)+"px"
,left:(Math.round($i.pos.left)-3)+"px"
,width:$i.width()
}).appendTo($doc);
}
},
" ul > li > img"
).on ({
"mouseleave" : function (e) {
$(this).remove();
},"> .gallery_clone");
in css .gallery_clone is position:absolute
then i animate .gallery_clone:hover through css but you can do it in the jquery as well i guess, adding a mouseenter event on .gallery_clone
edit : i've literally copy/pasted from my script so you'll have to adapt this code to your html
nb: give css anim a go, it's worth it even if older ie will not animate; (i also made lightbox effect almost pure css for that same gallery - will publish later, not ready for plugin release just now sorry)
nb2: that part "+$i.parent().parent().attr("class") is because in the cms they can chose gallery background color so adding that class forward the background color & other gallery style to the clone (ie you should not need it)

Categories

Resources