jQuery Splide, responsive height based on image - php

We got this slide based on Splide, used as article's photo slider, with attached second instance that act as a thumbnail paginator.
At the moment, it doesn't take care of the height of the pics, but just use the height of the taller image, making the thumbnails remain down when a 16/9 image is displayed, leaving a big white space unused.
Even if it is an huge layout swift, we need thumbnails staying glued to the bottom of the image, sliding up or down when an image change, can we achieve this situation?
Currently, my code is:
<!-- Slideshow container -->
<section id="main-carousel" class="splide" role="group" style="margin-top: 30px" >
<div class="splide__track">
<ul class="splide__list">
<?php
$i = 0;
foreach(get_field('gallery') as $image ) {
if ($i == 0) { $active = 'active'; } else { $active = '';}
echo '<li class="splide__slide" data-splide-interval="3000">';
echo '<div class="splide__slide__container" style="max-height: fit-content>';
echo '<a href="' . $image .'" data-lightbox="image-' . ($i + 1) . '">';
echo '<img src="' . $image . '" style="width:100%" />';
echo '</a>';
echo '</div>';
echo '</li>';
$i++;
}
?>
</ul>
</div>
<br class="clear" />
</section>
<script>
var splide = new Splide( '.splide' );
splide.mount();
</script>
<section id="thumbnail-carousel" class="splide" style="margin-top: 10px; height: auto">
<div class="splide__track">
<ul class="splide__list" style="height:auto!important">
<?php
$i = 0;
foreach(get_field('gallery') as $image ) {
if ($i == 0) { $active = 'active'; } else { $active = '';}
echo '<li class="splide__slide" style="height:auto or 100%">';
echo '<img src="' . $image . '" style="width:100%; height: auto or 100%" />';
echo '</li>';
$i++;
}
?>
</ul>
</div>
</section>
<style>
.splide__list {
align-items: flex-start!important;
}
.clear { clear: both; }
</style>
<script>
document.addEventListener( 'DOMContentLoaded', function () {
var main = new Splide( '#main-carousel', {
type : 'loop',
rewind : true,
pagination: false,
arrows : false,
autoHeight: true,
autoWidth: true,
//autoplay : true,
autoStart : true,
lazyLoad: true,
perPage : 1,
perMove: 1,
autoScroll: {
speed: 1,
},
} );
var thumbnails = new Splide( '#thumbnail-carousel', {
fixedWidth : 100,
fixedHeight : 58,
gap : 8,
rewind : true,
pagination : false,
isNavigation: true,
//autoHeight: true,
breakpoints : {
600: {
fixedWidth : 60,
fixedHeight: 44,
},
},
} );
main.sync( thumbnails );
main.mount( window.splide.Extensions );
thumbnails.mount();
} );
</script>
<?php } ?>

You will need to dynamically change the slide height using the height of the next image before the carousel moves to keep the thumbnails 'glued' to the slider.
Use the Splide#on() method to listen to the ready event (to apply the first slide height) and the move event (to apply the slide height when the carousel moves).
To know which slide the carousel is moving to, use the instance property index. To change the slide height, use the property options.
var main = new Splide('#main-carousel');
main.on('ready', function() {
setHeightCarousel(0); // index = 0
})
main.mount();
main.on('move', function() {
const currentIndex = main.index;
setHeightCarousel(currentIndex);
})
And here's how setHeightCarousel(index) could look like. Note I added the class splide__img in the HTML on each <img> tag to target them.
function setHeightCarousel(index) {
const image = document.querySelectorAll('.splide__img')[index];
let imgHeight;
if (image.complete) {
imgHeight = image.naturalHeight;
main.options = {
height: imgHeight + 'px'
}
} else {
image.addEventListener('load', function() {
imgHeight = this.naturalHeight;
main.options = {
height: imgHeight + 'px'
}
})
}
}
Because the ready event fires before the image is loaded the function first checks whether the image is loaded, and if not adds a load event listener. A callback or promise is purposefully avoided here, but can be used to improve the code depending on the implementation.
The naturalHeight property is used to get the intrinsic height of the image, in the presumption you might want to (down)scale the image first.
Here's a working example in a JSFiddle using Splide V4.1.4.
Or view it in a snippet:
document.addEventListener('DOMContentLoaded', function() {
var main = new Splide('#main-carousel', {
type: 'fade',
rewind: true,
pagination: false,
arrows: false,
lazyLoad: 'sequential'
})
var thumbnails = new Splide('#thumbnail-carousel', {
fixedWidth: 100,
fixedHeight: 60,
gap: 10,
rewind: true,
pagination: false,
isNavigation: true,
breakpoints: {
600: {
fixedWidth: 60,
fixedHeight: 44,
},
}
})
main.on('ready', function() {
setHeightCarousel(0);
})
main.sync(thumbnails);
main.mount();
thumbnails.mount();
main.on('move', function() {
const currentIndex = main.index;
setHeightCarousel(currentIndex);
})
function setHeightCarousel(index) {
const image = document.querySelectorAll('.splide__img')[index];
let imgHeight;
if (image.complete) {
imgHeight = image.naturalHeight;
main.options = {
height: imgHeight + 'px'
}
} else {
image.addEventListener('load', function() {
imgHeight = this.naturalHeight;
main.options = {
height: imgHeight + 'px'
}
})
}
}
})
.container {
margin: 1rem 1rem;
}
#thumbnail-carousel .splide__track .splide__list .splide__slide img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Centers the image */
/*
.splide__slide img {
width: 100%;
height: 100%;
object-fit: scale-down;
}
*/
<script src="https://cdn.jsdelivr.net/npm/#splidejs/splide#4.1.4/dist/js/splide.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/#splidejs/splide#4.1.4/dist/css/splide.min.css">
<div class="container">
<section id="main-carousel" class="splide" aria-label="Beautiful Images">
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">
<div class="splide__slide__container">
<img data-splide-lazy="https://via.placeholder.com/250x140" alt="" class="splide__img">
</div>
</li>
<li class="splide__slide">
<div class="splide__slide__container">
<img data-splide-lazy="https://via.placeholder.com/140x250" alt="" class="splide__img">
</div>
</li>
<li class="splide__slide">
<div class="splide__slide__container">
<img data-splide-lazy="https://via.placeholder.com/250x140" alt="" class="splide__img">
</div>
</li>
</ul>
</div>
</section>
<section id="thumbnail-carousel" class="splide">
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">
<img src="https://via.placeholder.com/250x140" alt="">
</li>
<li class="splide__slide">
<img src="https://via.placeholder.com/140x250" alt="">
</li>
<li class="splide__slide">
<img src="https://via.placeholder.com/250x140" alt="">
</li>
</ul>
</div>
</section>
</div>
A few notes.
To make lazy load work, the img element in the slide must have the data-splide-lazy attribute that indicates the path or URL to the source file.
By changing the height of the slider and therefore the position of the thumbnails you are shifting the layout. This is generally considered poor UX and can be measured using the Cumulative Layout Shift. Alternatives are to position the thumbnails on top or aside the main carousel, or by centering the 16:9 image (leaving white-space around it versus just below it).

Related

Lazy Load for CSS Images

I have the following lazy load function which works for <img>.
<script>
document.addEventListener("DOMContentLoaded", function() {
var lazyloadImages;
if ("IntersectionObserver" in window) {
lazyloadImages = document.querySelectorAll(".lazy");
var imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var image = entry.target;
image.src = image.dataset.src;
image.classList.remove("lazy");
imageObserver.unobserve(image);
}
});
});
lazyloadImages.forEach(function(image) {
imageObserver.observe(image);
});
} else {
var lazyloadThrottleTimeout;
lazyloadImages = document.querySelectorAll(".lazy");
function lazyload () {
if(lazyloadThrottleTimeout) {
clearTimeout(lazyloadThrottleTimeout);
}
lazyloadThrottleTimeout = setTimeout(function() {
var scrollTop = window.pageYOffset;
lazyloadImages.forEach(function(img) {
if(img.offsetTop < (window.innerHeight + scrollTop)) {
img.src = img.dataset.src;
img.classList.remove('lazy');
}
});
if(lazyloadImages.length == 0) {
document.removeEventListener("scroll", lazyload);
window.removeEventListener("resize", lazyload);
window.removeEventListener("orientationChange", lazyload);
}
}, 20);
}
document.addEventListener("scroll", lazyload);
window.addEventListener("resize", lazyload);
window.addEventListener("orientationChange", lazyload);
}
})
</script>
The function isn't mine and I need to know how to modify it to work for the next example which load images from CSS:
<div class="col-md-2 col-sm-3 col-xs-4 photo" style="padding: 2.5px">
<span onclick="window.location.href=\''.$link.'\';"
class="thumbnail"
role="img"
style="background-image: url(\''.$image.'\'); cursor: pointer; margin: 0; margin-top: 5px;"
aria-label="' . $row["topic_title"] . '"
title="'.$row['topic_title'].'">
</span>
<center>
<p class="name" style="margin 0 2px; color: white; margin-top: 5px;">
' . $title . '
</p>
</center>
</div>
On a page with 24 gifs, the page loads relatively slow and I'd like to change that.
I could load the images as normal using <img>, but I want the page to be more dynamic because using span I have different temathic.
Here is how I managed to do the script and it works correctly.
Hope someone will find it useful.
if (entry.isIntersecting) {
var image = entry.target;
image.src = image.dataset.src;
var imageUrl = "url" + "(" + "'" + image.src + "')";
entry.target.style.backgroundImage = imageUrl;
image.classList.remove("lazy");
imageObserver.unobserve(image);
}
On a page with 24 gifs, the page loads relatively slow and I'd like to
change that.
Images in general are really heavy on websites. That's most likely whats slowing the site down. If your website needs that many GIFs I would firstly look at compression techniques. Search for GIF to WebP converters and file compressors (ImageAlpha, ImageOptim, Handbrake to name a few).
Good luck!

Change container background color on slide change in Slick slideshow

I have a Slick slider where each slide has its own background color. My container color is white, but I want to use a container color that's the same as the slide if swiping or changing slides.
My JS:
if ($("#main-slider").length) {
if (!$("body").hasClass("ie-browser")) {
$("#main-slider .slide").each(function(){
var thisSlide = $(this),
thisImg = thisSlide.find(".slide-img").attr("style");
$("#next-slides").append('<div class="item" style="'+thisImg+'"></div>');
});
}
$("#next-slides .item:first-child").addClass("active");
$("#next-slides .item:nth-child(2)").addClass("next");
$("#next-slides .item:last-child").addClass("prev");
$('#main-slider').on('init', function(slick){
var slides = $('#main-slider .slide').length;
$(".main_slider .count .all").text(pad((slides), 2));
});
$('#main-slider').slick({
arrows: true,
dots: false,
slidesToShow: 1,
slidesToScroll: 1,
infinite: true,
swipe: true,
fade: true,
touchMove: true,
draggable: true,
autoplay: false,
speed: 1500,
autoplaySpeed: 20000,
prevArrow: $('.main_slider .arrows .arrow.prev'),
nextArrow: $('.main_slider .arrows .arrow.next'),
responsive: [
{
breakpoint: 1000,
settings: {
speed: 800
}
}
]
});
$('#main-slider').on('afterChange', function(slick, currentSlide){
changeBackground();
}).on('init', function(){
changeBackground();
});
function changeBackground(){
$('.container').css('background-color', $('.slick-active').css('background-color'));
}
$('#main-slider').on('beforeChange', function(event,
slick, currentSlide, nextSlide){
var slides = $('#main-slider .slide').length;
var activeItem = $(".next-slides .item").eq($(slick.$slides[currentSlide]).index());
var nextItem = $(".next-slides .item").eq($(slick.$slides[nextSlide]).index());
changeBackground();
$(".next-slides .item").removeClass("prev");
$(".next-slides .item").removeClass("next");
$(".next-slides .item").removeClass("active");
nextItem.addClass("active");
setTimeout(function () {
nextItem.next().addClass("next");
if (nextItem.is(":last-child")) {
$(".next-slides .item:first-child").addClass("next");
}
}, 300);
activeItem.addClass("prev");
var nextSlide = $(slick.$slides[nextSlide]),
nextSlideIndex = nextSlide.index();
$(".main_slider .count .current").text(pad((nextSlideIndex+1), 2));
});
$(".main_slider .next-slides").on("click", ".next", function(){
$("#main-slider").slick('slickNext');
});
}
At the moment it works, but the container background color changes about 1.5 seconds later. How I can get it to change instantly?
My HTML (Its Fat-Free framework):
<div class="container" style="background-color: {{#first_color}}">
<include href="layout/top_panel.html">
<div class="mainpage">
<div class="main_slider">
<div class="slider" id="main-slider">
<repeat group="{{#PRODUCTS }}" value="{{#PRODUCT}}">
<div class="slide" style="background-color: {{#PRODUCT.color}}">
<div class="wrap">
<div class="wrap_float">
<div class="slide_left">
<div class="slide_content">
<div class="category">{{#PRODUCT.producer}} | {{#PRODUCT.category_name}}</div>
<h2 class="title">
{{ #PRODUCT.name | raw}}
</h2>
<a href="/product/{{#PRODUCT.id}}" class="link">
<span>{{#LANG_79}}</span>
</a>
</div>
</div>
<check if="{{#PRODUCT.image}}">
<true>
<div class="slide_right" data-slide="{{#PRODUCT.thumb}}">
<div class="slide-img" style="background-image: url({{#PRODUCT.thumb}})"></div>
<div class="read_more">
Buy now
</div>
</div>
</true>
<false>
<div class="slide_right" data-slide="{{#NOIMG}}">
<div class="slide-img" style="background-image: url({{#NOIMG}})"></div>
<div class="read_more">
Buy now
</div>
</div>
</false>
</check>
</div>
</div>
</div>
</repeat>
</div>
<div class="controls">
<div class="arrows">
<div class="arrow prev"></div>
<div class="arrow next"></div>
</div>
<div class="count">
<span class="current">01</span> <span class="all">06</span>
</div>
</div>
<div class="next-slides" id="next-slides"></div>
</div>
</div>
</div>
I can share my PHP function also where it gives color for each slide.
MY PHP:
function GET_Home() {
if($this->f3->exists("SESSION.MESSAGE")){
$this->f3->set('MESSAGE',$this->f3->get('SESSION.MESSAGE'));
$this->f3->clear('SESSION.MESSAGE');
}
$this->_pluginRun('before_product_list');
$this->f3->set('NOIMG', $this->f3->get('SITE.url') . '/static/no-img.png');
$this->getProducts(true, 6);
$products = $this->f3->get('PRODUCTS_PLAIN');
$colors = array('#F5FCFE', '#FCEFEF', '#FFF7EC', '#EBECF4', '#E8FFF2', '#FFE1BB');
$k = 0;
foreach($products as $key => &$product){
$product['color'] = $colors[$k];
$k++;
}
$this->f3->set('PRODUCTS', $products);
$this->f3->set('first_color', $colors[0]);
echo \Template::instance()->render('home.html');
}
You need to use "beforeChange" event and inside its callback function use 4th argument to detect the next slide.
$('.slick-slider').slick().on("beforeChange", (event, slick, currentSlide, nextSlide) => {
const nextSlideElelemnt = slick.$slider.find(`[data-slick-index=${nextSlide}]`));
});
Codepen demo: https://codepen.io/rohitutekar/pen/BaKgPVK
Your Delay of 1.5 seconds comes from your speed property in the slick options with 1500ms. You can use the event "beforeChange" instead of "afterChange" and control your timing with css transitions if the change is too fast
Please try this code,To Change containe background color on slide change
That color option have option to change the overall slider background and the slider text and link color. But it doesn’t have option to change the slider content background color. So, to change that to #888888, you can add the following css in
“Appearance => Customize => Theme Options => Custom CSS Options” box:
#feature-slider .entry-container {
background: #555; /* Solid Color for old Browser */
background: rgba(85,85,85,0.7);
}
I hope this information will be useful.
Thank you.

How to change the colour of an SVG when at the start/end of slick slider

Sorry if the title sucks, I didn't really know how to word it...
How would I change the colour of the svg arrows if I'm at the start of the slides or at the end of the slides? Maybe I could add class if value equals 0? not sure how to approach adding a class if there are no slides remaining?
The Image below is what I'm trying to achieve.. atm I have two white arrows on both sides. I want to change the colour to that grey when at the start (on the left) and if I'm at the end (on the right).
$(".image_carousel-wrapper").each(function () {
var _this = $(this);
var $status = _this.find('.slide-number');
var $slickElement = _this.find('.image_carousel');
$slickElement.on('init reInit afterChange', function (event, slick, currentSlide, nextSlide) {
//currentSlide is undefined on init -- set it to 0 in this case (currentSlide is 0 based)
if (!slick.$dots) {
return;
}
var i = (currentSlide ? currentSlide : 0) + 1;
$status.text(i + '/' + (slick.$dots[0].children.length));
});
var _this = $(this);
_this.find('.image_carousel').slick({
arrows: true,
dots: true,
pauseOnHover: false,
pauseOnFocus: false,
autoplay: false,
swipeToSlide: true,
fade: true,
draggable: true,
prevArrow: _this.find('.prev-slide'),
nextArrow: _this.find('.next-slide'),
});
});
<div class="image_carousel-wrapper">
<div class="image_carousel">
<?php foreach( $images as $image ): ?>
<div class="slide">
<img class="full-width <?php if($module_alignment == 'left') : ?>left-image<?php endif; ?>" src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt']; ?>">
<?php if( get_sub_field('artists_impression') ): ?>
<p class="artistimp ">Artist Impression</p>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<div class="slider-directions">
<div class="arrow-wrap">
<div class="prev-slide"></div>
<div class="next-slide"></div>
</div>
<div class="slide-number"></div>
</div>
</div>
Add infinite: false to the carousel options to disable infinite looping.
If you want to further tweak the look of the disabled nav item, you can target .slick-disabled

How to put the HTML output with overlay inside the OwlCarousel

I have a slider in my page and every slider has it's own overlay descriptions and this descriptions are in the HTML format.
In my admin module there is a setting there that the user can create their own slider images with custom message using CKEditor.
And my problem is when I try to display the descriptions in the slider it's just plain HTML code.
Here's a bit of my code:
Controller Part
foreach($results as $result) {
if ($result['banner_image'] && file_exists(DIR_IMAGE . $result['banner_image'])) {
$image = $this->model_tool_image->resize($result['banner_image'], 40, 40);
$banner_image_large = HTTP_IMAGE . $result['banner_image'];
} else {
$image = $this->model_tool_image->resize('no_image.jpg', 40, 40);
}
$url = '&banner_id=' . (int)$result['banner_id'];
$this->data['banners'][] = array(
'banner_id' => $result['banner_id'],
'banner_image' => $image,
'banner_image_large' => $banner_image_large, // here's the image to be use in the slider
'code_description' => $result['banner_description'], //here's the raw HTML formatted description
'description' => strip_tags(html_entity_decode($result['banner_description'])),
'banner_link' => $result['banner_link'],
'action' => $this->url->link('project/banner_slider/update', 'token=' . $this->session->data['token'] . $url, 'SSL')
);
}
In my View
<h1>Carousel Demo</h1>
<div id="owl-demo" class="owl-carousel owl-theme">
<?php foreach($banners as $banner) { ?>
<div class="item">
<div class="textoverlay"><?php echo $banner['code_description']; ?></div> <!-- overlay the decription -->
<img src="<?php echo $banner['banner_image_large']; ?>" />
</div>
<?php } ?>
</div>
Here's some CSS
#owl-demo .item img{
display: block;
width: 100%;
height: auto;
}
.textoverlay{
position: absolute;
display:block;
}
And JS:
$('#owl-demo').owlCarousel({
autoPlay : 3000,
stopOnHover : true,
navigation : false, // Show next and prev buttons
slideSpeed : 300,
paginationSpeed : 400,
singleItem:true,
autoHeight : true,
transitionStyle:"fade"
});
surround the raw html with $.parseHTML("your html here");
Ok I solved it by using html_entity_decode() function

drag multiple elements at the same time to the drop area

I'm new to jQueryUI and I'm not able to drag multiple <li> elements to the drop area. However I managed to drag one and drop it on the drop area. Please can anyone help me with this.
JavaScript
$(function() {
$trash= $( "#trash" );
$("a", ".polaroids").draggable({
zIndex: 999,
revert: "invalid" ,
helper: function(){
$copy = $(this).clone();
return $copy;},
appendTo: 'body',
scroll: false
});
$("a", ".polaroids").selectable();
$trash.droppable({
accept: ".polaroids a",
activeClass: "custom-state-active",
drop: function( event, ui ) {
$(this).append(ui.draggable);
}
});
});
Here is the <div> in which the <li> elements are dragged but one by one
<div class="st_view_container">
<div class="st_view">
<?php
foreach($gpID as $k => $v) {
?>
<div id="stv_content_<?php echo $v;?>" class="st_tab_view st_first_tab_view">
<ul class="polaroids" id ="polaroids">
<?php
$sql2=mysql_query("select * from user_group WHERE group_id='$v' AND user_id=3");
$i=1;
while($row=mysql_fetch_array($sql2)) {
$memid=$row['member_id'];
$sql1=mysql_query("select * from users_profile WHERE uid='$memid'");
while($row1=mysql_fetch_array($sql1)) {
$ufname=$row1['fname'];
$ulname=$row1['lname'];
$upic=$row1['profile_pic'];
?>
<li>
<a href="#" title="<?php echo $ufname; ?>">
<img src="../<?php echo $upic; ?>" rel="<?php echo $row1['uid']?>" width="65px" height="65px" />
</a>
</li>
<?php
if($i%6==0) {;}
$i++;
}
?>
</ul>
</div>
<?php } ?>
</div> <!-- /.st_view -->
</div> <!-- /.st_view_container -->
and here is the <div> in which i want the multiple elements to be dropped, but not one by one.
<div id="trash" style="width:200px; height:200px; border:1px solid;">
<h4 class="ui-widget-header"><span class="ui-icon ui-icon-trash">Trash</span> Trash</h4>
</div>
Here is a demo based on some research…
Is it possible to link two jquery.ui draggables together?
grouping draggable objects with jquery-ui draggable
Can't drop jquery ui helper on droppable
How to reimplement jQuery's default helper in a custom helper
and me playing with the jQueryUI droppable photo manager demo which is what you are using as a template.
Functionality includes single click and drag (as is the default behaviour) or use Ctrl+left click to select multiple items and then drag. The drag helper function is used to select all the items with class="selected" and the drop function is customised to extract the img elements from the container the drag helper added them to. The other function simple enables the Ctrl+click behaviour.
The following code is duplicated below from the demo but does require jQuery, jQueryUI and one of the jQueryUI themes.
HTML
<ul id="draggable">
<li><img src="nature-q-c-50-50-1.jpg" alt="" /></li>
<li><img src="nature-q-c-50-50-2.jpg" alt="" /></li>
<li><img src="nature-q-c-50-50-3.jpg" alt="" /></li>
<li><img src="nature-q-c-50-50-4.jpg" alt="" /></li>
<li><img src="nature-q-c-50-50-5.jpg" alt="" /></li>
<li><img src="nature-q-c-50-50-6.jpg" alt="" /></li>
</ul>
<div id="trash">
<h4 class="ui-widget-header">Trash<span class="ui-icon ui-icon-trash"></span></h4>
</div>
CSS
body {
font-family:"Trebuchet MS";
}
#draggable {
margin:0;
padding:10px;
width:300px;
list-style-type:none;
background-color:#000;
}
li {
display:inline;
}
img {
border:5px solid white;
}
.image-group img {
margin-right:5px;
}
#trash {
margin-top:10px;
width:200px;
height:200px;
border:1px dotted #000;
}
.selected {
border-color:#aed0ea
}
#trash h4 {
margin:0;
padding:0 5px;
}
.ui-icon {
display:inline-block;
}
JavaScript
$('#draggable li').draggable({
revertDuration:100,
helper:function() {
var selected = $('#draggable img.selected');
if (selected.length === 0) {
selected = $('img', $(this)).addClass('selected');
}
console.log('selected', selected);
var container = $('<div class="image-group"/>');
container.append(selected.clone());
console.log('container', container);
return container;
},
cursorAt:{ left:25,top:25 }
});
$('#trash').droppable({
drop: function(event, ui) {
var newItems = $(ui.helper).find('img').clone(false)
.removeClass('selected');
$(this).append(newItems);
console.log('ui.draggable', ui.draggable);
$('#draggable img.selected').parent().remove();
}
});
$('#draggable li').click(function(event) {
if (event.ctrlKey) {
$('img', $(this)).toggleClass('selected');
}
});

Categories