Multiple images depending on mouse location when hovering over div - javascript

I am trying to do an overview page on my website so that when I hover over a div on the overview page different sections of that div show different images. Essentially a slideshow but the image changes depending on where the cursor is.
I have managed to find some code that does what I want but it uses an a href to pull in the images which means if you click it, it goes to the link of the image.
Currently I just have placeholder images in but when finished each one will have specific project images in. As each div will just be one project the whole div should go to one html link and not just a specific image link of the image the user is hovering over.
All I want is the user to click and it go to a html link and not an img link.
Here is the code I am using:
The coding savvy people out there will probably have a much better solution for what I would like to achieve, I am interested to see any better solutions.
HTML
<div class="multi">
<ul class="rotator-nav fifth clearfix">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="imgcontent">
<ul class="rotator-icons fifth">
<span class="img1 active"></span>
<span class="img2"></span>
<span class="img3"></span>
<span class="img4"></span>
<span class="img5"></span>
</ul>
<img src="/img/FoI.jpg" class="currentimg">
</div>
</div>
CSS
.multi {
display: block;
float:left;
position: relative;
width: 30.8%;
height: 20%;
padding: 0px;
margin:0% 1% 2% 1%;
overflow: hidden;
}
.multi .imgcontent {
display: block;
position: absolute;
top: 0px;
}
.imgcontent img {
display:block;
width: 100%;
height: auto;
margin-left: auto;
margin-right: auto;
}
.rotator-nav {
display: block;
position: relative;
width: 100%;
height: 100%;
z-index: 9;
}
.rotator-nav li {
display: block;
float: left;
height: 100%;
}
.rotator-nav.fourth li {
width: 25%;
}
.rotator-nav.fifth li {
width: 20%;
}
.rotator-nav li a {
display: block;
float: left;
width: 100%;
height: 100%;
border-bottom:0px solid #fff
}
.clearfix:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }
.clearfix { display: inline-block; }
html[xmlns] .clearfix { display: block; }
* html .clearfix { height: 1%; }
JS
$(function(){
var $rotators = $('.multi');
var $imglinks = $('.rotator-nav a');
$imglinks.on('mouseenter', function(e){
var imgclass = '.'+$(this).attr('class');
var imglink = $(this).attr('href');
// update main image src
$(this).parent().parent().parent().find('.currentimg').attr('src',imglink);
// update current rotator icon
var $rotators = $(this).parent().parent().parent().find('.rotator-icons');
if($rotators.children(imgclass).hasClass('active')) {
// already active icon -- do nothing
} else {
// remove active class then add to new icon
$rotators.children('span').removeClass('active');
$rotators.children(imgclass).addClass('active');
}
});
});
Any help would be greatly appreciated!
Thanks,
Mark

I think you could best use a data attribute for this instead (if I understand the intention correctly) :
var imglink = $(this).data('image');
<div class="multi">
<ul class="rotator-nav fifth clearfix">
<li>
<a data-image="/img/FoI.jpg" href="#" class="img1"></a>
</li>
<li>
<a data-image="/images/card.jpg" href="#" class="img2"></a>
</li>
<li>
<a data-image="/images/amareal.jpg" href="#" class="img3"></a>
</li>
<li>
<a data-image="/images/edeva.jpg" href="#" class="img4"></a>
</li>
<li>
<a data-image="/images/amacover2.gif" href="#" class="img5"></a>
</li>
</ul>
...
If you'd still like to see the image over the original div, a pseudo element could be used. Advantage there is that they are not actual DOM elements and will not register clicks :
Demo
Now it would be great if the data attribute could be directly used for the content of the pseudo element as well but that doesn't seem possible. And you can't target them with JavaScript so each image would have to be defined with nth-of-type() in the stylesheet additionally.

You don't need to use .parent().parent()
Just use the parent's class to find the item.
Your $(this).parent() * 3 is the $(".multi")
So your $rotators can't find .rotator-icons,
you need to use one more parent or use siblings
And I suggest do not use class if there are no need to do one thing to lots of items.

Related

Add Trailing Ellipsis To Breadcrumb Depending On Device Width

On my user interface I have a breadcrumb of which shows on the top bar. Upon the device width being below a defined width, it'll drop below the top bar and be it's own bar, however what I do not know how to do is add a trailing ellipsis upon the breadcrumb length being larger than the device width.
Example Breadcrumb:
<nav>
<ul>
<li>Home</li>
<li>>></li>
<li>User</li>
<li>>></li>
<li>Inbox</li>
<li>>></li>
<li>Mail_ID</li>
</ul>
</nav>
Note: >> represents a FontAwesome icon in an i tag
Upon the breadcrumb being larger than the device width, the best I can describe what I would like to happen is demonstrated below:
Home >> User >> Inbox >> Mail_ID
... User >> Inbox >> Mail_ID
... Inbox >> Mail_ID
... Mail_ID
This is still a partial code but might help you.
Idea
On load, call a function that checks for with of ul and its parent container.
If ul has greater width, hide first 2 visible li. Also add an li for ellipsis and make it hidden initially and make it visible only if any of other divs are hidden.
Repeat this process recursively and you will get what you are looking for.
Sample
$(function() {
$(".content").resizable();
$(".content").on("resize", function() {
var ul = $(this).find('ul');
if (ul.width() > $(this).width()) {
var lis = ul.find('li:not(.hide):not(.ellipsis)');
for (var i = 0; i < 2; i++) {
$(lis[i]).addClass("hide");
}
if ($(".ellipsis").not(":visible"))
$(".ellipsis").removeClass("hide")
}
})
});
.content {
text-align: left;
border: 1px solid gray;
width: 300px;
height: 40px;
max-height: 40px;
}
.content ul {
padding: 0px;
position: fixed;
overflow: hidden;
white-space: nowrap;
}
.content ul li {
display: inline-block;
text-decoration: none;
}
.hide {
display: none!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="content">
<ul>
<li class="hide ellipsis">...</li>
<li>Home</li>
<li>>></li>
<li>User</li>
<li>>></li>
<li>Inbox</li>
<li>>></li>
<li>Mail_ID</li>
</ul>
</div>
You can try to use the CSS-only ellipsis, but I don't know if it also works with <ul><li>. For sure it works with simple strings:
Use this HTML:
<ul class="ellipsis">
And this CSS:
ul.ellipsis
{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

toggle on hover and click not working properly

I've created this little toggle, since i"m starting with javascript, but it's not working as I would like to. The brown box should appear and disappear both on hover and click (for ipad mostly).
Right now it's fine for hover, but not for clicking on ipad, it just appears once, and thats it.
I think it's also getting confused with my sharing icons.
Any help is appreciated.
jsfiddle
function toggleDisplay (toBlock, toNone) {
document.getElementById(toBlock).style.display = 'block';
document.getElementById(toNone).style.display = 'none';
}
#toggle_hero
{
float:left;
}
.leftHalf
{
display: block;
height: 100%;
width: 50%;
float: left;
position: absolute;
z-index: 2;
}
.leftHalf div
{
display:none;
}
.leftHalf:hover
{
}
.leftHalf:hover div
{
display:block;
width: 100%;
height: 23%;
overflow: auto;
margin: auto;
position: absolute;
left: 0;
bottom: 70px;
right: 0;
background: white;
color: #fff;
background-color:rgba(207,167,80,0.7);
padding:10px;
font-size: 0.8em;
font-weight: 200;
}
.leftHalf:hover div h3
{
font-weight: 500;
float:left;
}
.leftHalf:hover div span{
float:right;
text-align: center;
padding-bottom:5px;
color:black;
}
hover (on a pc) or click me (on ipad)
<div id="toggle_hero" onclick="toggleDisplay('comment', 'toggle_hero')">
<div class="leftHalf clearfix" id="comment">
<div>
<span>
<a target="_blank" class="icon-facebook fa fa-facebook" href="https://www.facebook.com/sharer/sharer.php?u=http://google.com" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;">facebook </a>
<a target="_blank" href="http://twitter.com/share?url=http://google.com" class="fa fa-twitter"> twitter</a>
</span>
<h3>this text should appear both on hover and click (for ipad)</h3>
</div>
</div>
</div>
You could just create an event listener that captures the current toggled state in a var.
var toggle = false;
var myDiv = document.getElementById('myDiv');
myDiv.addEventListener('click', function() {
if (toggle === false) {
this.getElementsByTagName('p')[0].style.display = 'none';
toggle = true;
} else {
this.getElementsByTagName('p')[0].style.display = 'initial';
toggle = false;
}
});
http://jsfiddle.net/scott88/bLkdt6mc/
You can add another listener for the 'mouseover'.
Your HTML structure is a bit weird. The text that you want to hover/click is actually outside of the target area for your click event. It happens to work for me locally because of the absolute positioning, but I wouldn't be surprised if the iPad browser behaves differently.
I would suggest defining a clear target for what is to be clicked/hovered, apply a class on click/hover, and handle the rest in CSS. I put together a sample of what I envision. You can remove the mouseenter and mouseleave events to simulate on a computer how it works with the touch events. I'm not sure exactly how you want it to behave, but hopefully this is enough to get you started.
function setHover(isHover) {
var element = document.getElementById("toggle_hero");
if (isHover)
element.className = "hovered";
else
element.className = "";
}
function toggleHover() {
var element = document.getElementById("toggle_hero");
setHover(element.className === "");
}
#toggle_hero {
float:left;
}
#comment {
display:none;
width: 100%;
height: 23%;
overflow: auto;
margin: auto;
position: absolute;
left: 0;
right: 0;
background: white;
color: #fff;
background-color:rgba(207,167,80,0.7);
padding:10px;
font-size: 0.8em;
font-weight: 200;
}
.hovered #comment {
display: block;
}
<div id="toggle_hero" onclick="toggleHover()" onmouseenter="setHover(true);" onmouseleave="setHover(false);">
hover (on a pc) or click me (on ipad)
<div id="comment">
<div>
<span>
<a target="_blank" class="icon-facebook fa fa-facebook" href="https://www.facebook.com/sharer/sharer.php?u=http://google.com" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;">facebook </a>
<a target="_blank" href="http://twitter.com/share?url=http://google.com" class="fa fa-twitter"> twitter</a>
</span>
<h3>this text should appear both on hover and click (for ipad)</h3>
</div>
</div>
</div>

How to stick two unrelated elements together?

I'm working on an interface and I require something that would stick two unrelated elements together. Well, the most important element will be the "boss" and the other element called "employee" will follow the "boss" around and will change it's position accordingly.
This is the markup:
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
This is the jQuery I wrote:
$('.boss').each(function( i, obj ){
var Pos = $(this).position();
var ModuleWidth = $(this).outerWidth();
$(this).next('.employee').position({
my: 'right top',
at: 'right top',
of: $(this)
});
});
So I'm iterating through all the .boss classes and aligning all .employees to the right top of boss. They are supposed to always stick. But if I edit the html from the boss within chrome Developer Tools the .boss element will become smaller and larger and the .employee will not re-position its self accordingly. I would like to make .employee always reposition its self.
Later Update:
This http://screencast.com/t/F0RO7ODF is the kind of behavior i'm looking for. The gray box is the BOSS and the orange box is the EMPLOYEE. These 2 element's have a wrapper and i'm actually moving the wrapper. But i'd like a solution without a wrapper. Note: The organge box's position is irelevant.
I know this has been answered already, but here is an alternative which does not use any hierarchy between the two elements (even though that might not be the best practice):
HTML:
<div class="boss"></div>
<div class="employee"></div>
<div class="boss"></div>
<div class="employee"></div>
JS:
$.fn.invisible = function() {
return this.css("visibility", "hidden");
};
$.fn.visible = function() {
return this.css("visibility", "visible");
};
$(".boss").draggable({
stop:function(e) {
var employee_horizontal_position= $(this).offset().left+$(this).width();
var employee_vertical_position= $(this).offset().top-$(this).height();
$(this).next().visible();
$(this).next().offset({top: employee_vertical_position, left: employee_horizontal_position});
}
});
$(".boss").on("drag", function(e){
$(this).next().invisible();
});
CSS:
.boss{
height: 100px;
width: 300px;
background-color: grey;
float:left;
margin-top:100px;
}
.boss:hover{
cursor:pointer;
}
.employee{
height: 300px;
width: 100px;
background-color: orange;
float:left;
}
JSFIDDLE EXAMPLE: http://jsfiddle.net/ktxo4f6s/2/
I tried to make the employee hidden while the boss is being dragged as shown in your screencast.
n general when wanting elements to be in relation with each other they should be grouped together within an element.
To represent hierarchies it is best to also develop your html to honor the hierarchy you wish to represent.
This will force the behavior as you displayed in the video when moving the boss element.
For this particular example it may also be expanded upon with departments or roles.
See JSFiddle for example: http://jsfiddle.net/9dw5dvqw/
Updated: http://jsfiddle.net/en85bm9h/
HTML
<ul class="bosses">
<li class="boss">
<span class="boss-name"></span>
<ul class="employees">
<li class="employee">
<span class="employee-name"></span>
</li>
<li class="employee">
<span class="employee-name"></span>
</li>
</ul>
</li>
<li class="boss">
<span class="boss-name"></span>
<ul class="employees">
<li class="employee">
<span class="employee-name"></span>
</li>
<li class="employee">
<span class="employee-name"></span>
</li>
</ul>
</li>
</ul>
CSS
*{ margin: 0; padding: 0; }
body,
html{ height: 100%; }
ul{ list-style: none; overflow: hidden; float: left; }
li{ overflow: hidden; }
.bosses{ width: 100%; height: 100%; }
.boss{ margin: 20px 5px 20px 0; float: left; }
.boss-name{ display: block; background-color: #eee; float: left; width: 120px; height: 80px; cursor: move; }
.employees{ float: left; width: 50px; height: 120px; background-color: red; }

jQuery Mobile listview, Adding vote buttons to a line item

I want to add 2 vote buttons to the left hand side of a jQuery mobile listview. The vote buttons should be centered in the list item, and should be on the left-hand side.
I have sort of gotten this to work using javascript, but what I really want to do is to get this to work without any additional javascript and use the standard jquery mobile data-role attributes and enhancement with pure HTML & CSS.
Here is the HTML markup that I would like to use:
<div data-role="page">
<div data-role="content">
<ul class="has-vote-btns" data-role="listview">
<li>
<a href="#">
<h3>Line Item</h3>
<p>Sub title</p>
</a>
</li>
</ul>
</div>
</div>
Here is the CSS:
.vote-btn {
position: absolute;
top: 50%;
left: 5px;
z-index: 2;
}
.vote-btn .ui-btn-inner {
padding: 0;
}
.like-btn {
margin-top: -30px;
}
.dislike-btn {
margin-top: 0px;
}
.has-vote-btns .ui-link-inherit {
padding-left: 40px !important;
}
.has-vote-btns .ui-li-has-thumb .ui-link-inherit {
padding-left: 118px !important;
}
This does not work (live example).
I was, however, able to get it to work but only by removing the 2 vote buttons in the HTML markup and then adding some javascript to add the buttons dynamically after the listview has already enhanced.
Here the javascript I added to make it work (live example):
$(function(){
$('.has-vote-btns').each(function() {
$(this).find('li').each(function(i, li){
$('').buttonMarkup({
icon: 'arrow-u',
iconpos: 'notext'
}).appendTo(li);
$('').buttonMarkup({
icon: 'arrow-d',
iconpos: 'notext'
}).appendTo(li);
});
});
});
But this second approach of adding the 2 vote buttons after the enhancement is inconvenient. It would be much better if I could do this with plain HTML and CSS rather than hacking in those buttons after the enhancement.
Is there any solution to this that does not use javascript to insert the vote buttons?
I have updated your first fiddle with a CSS only solution:
FIDDLE
It is not the only way to do this, but I believe it solves your issue.
The <ul> HTML is changed as follows:
<ul class="has-vote-btns" data-role="listview" data-split-icon="bars" data-split-theme="d">
<li>
<a href="#">
<h3>Line Item 1</h3>
<p>Sub title 1</p>
</a>
<div class="vote-btns">
</div>
</li>
</ul>
I set the data split icon and theme at the <ul> level (data-split-icon="bars" data-split-theme="d") and in the <li>, I put the voting buttons in their own container so it can be positioned at the left. Here is the CSS that positions the container and the 2 buttons within the container:
.has-vote-btns .ui-link-inherit {
margin-left: 40px !important;
}
.vote-btns {
position: absolute;
top: 0px;
width: 39px;
bottom: 0px;
}
.vote-btns a:first-child {
position: absolute;
bottom: 50%;
margin-bottom: 2px;
}
.vote-btns a:last-child {
position: absolute;
top: 50%;
margin-top: 2px;
}
Of course you don't have to use the :first-child and :last-child pseudo selectors; you could use your like-btn and dislike-btn classes...
Here is an updated FIDDLE for jQM 1.4.x

javascript: how do I make one element visible relative to an element I hover over?

http://jsfiddle.net/awfex/4/
HTML:
<div class="section-header section-header-on" id="section_header_289" style="left: 50px;">
<span class="collapse"></span>
<div class="section-name">
<span class="name">Testing Facebox suff</span></div>
<ul class="tools">
<li>
<a class="trash" href="#"></a>
</li>
<li>
</li>
</ul>
<div class="clear"></div>
</div>
js:
$j = jQuery.noConflict();
$j(".section-header").hover(function(){
$j(this).find("ul").show();
});
So, I need this to be relative, because there are multiple "section-header"s and the ID is generally unknown / generated by the app. But, basically, I want to be able to hover over the section-header, and then have ul.tools change from display: none; to display: block. So I figured .show() could do that. but.. I guess my selector is wrong. =\
Your css specifies:
.section-header ul.tools,
.section-content li.content ul.tools {
visibility: hidden;
position: absolute;
top: 0;
left: -40px;
z-index: 1002;
cursor: default;
width: 40px;
height: 35px;
list-style: none;
}
Most notably visibility: hidden; which is not affected by the show()/hide() functions. So you need to change the css visibility property so your list will show-up.
Change:
$j(this).find("ul").show();
To:
$j(this).find("ul").css({visibility: 'visible'});
Or set the CSS to display: none; rather than use the visibility property.
show() documentation: http://api.jquery.com/show/
Demo
just needed a little coercion ;)
$j = jQuery.noConflict();
$j(".section-header").hover(function(){
$j(this).find(".tools").css({visibility:"visible"});
},function(){
$j(this).find(".tools").css({visibility:"hidden"});
});
Just needed a little css.
.tools {
display: none;
}
div.section-header:hover ul {
display: block;
}

Categories

Resources