Keep hover inside containing div - javascript

I'm working on a treemap with d3.js and I need help to code some JS to change the hover behavior so that it doesn't overflow outside a containing div#graphic-treemap.
Simplifying the HTML structure, it looks like this:
<div id="graphics">
<div class="treemap">
<div id="graphic-treemap">
<div class="node">
<a href="#">
<span class="name">Name</span>
<strong class="value">R$ 3 Bi</strong>
<span class="more-info">
<span class="name-inside">Name</span>
<span class="year-and-amount">R$ 3 Bi</span>
<span class="percent">15% valor total do orçamento</span>
</span>
</a>
</div>
</div>
</div>
</div>
This is part of the CSS to clarify the hover thing:
#graphics .treemap .node a .more-info {
display: none;
position: absolute;
top: 20%;
left: 15%;
background-color: #FFF;
padding: 10px 20px;
text-align: center;
box-shadow: 1px 1px 2px #444;
z-index: 10;
}
#graphics .treemap .node a:hover .more-info {
display: block;
}
The final output of the treemap looks like this:
http://jsfiddle.net/tatianeps/GYsEa/
See that on the bottom right corner when the mouse is over some div.node without text inside the span.more-info inside that node overflows the div#graphic-treemap.
Below the JS that generates the treemap and some code I've been working on without success.
I was trying something with the function adjustHoverPosition at the end of the code. Also with node.on('mouseover',function(d){ });, but removed the code inside it because it didn't work either.
Any help will be appreciated.
var graphics =
{
debug: true,
init: function() {
graphics.load();
},
load: function() {
if ( typeof graphics_at_page != 'undefined' ) {
if ( typeof graphics_at_page[ 'map' ] != 'undefined' ) {
graphics.map.init( graphics_at_page[ 'map' ], 0 );
}
if ( typeof graphics_at_page[ 'treemap' ] != 'undefined' ) {
graphics.treemap.init( graphics_at_page[ 'treemap' ] );
}
if ( typeof graphics_at_page[ 'bar' ] != 'undefined' ) {
graphics.bar.init( graphics_at_page[ 'bar' ], 0 );
}
}
},
load_script: function( url, callback )
{
$.getScript( url, callback );
},
load_json: function( url, callback )
{
$.get(
url,
'json',
function(data) {
callback( data );
}
);
},
log: function( object ) {
if ( graphics.debug ) console.log( object );
},
treemap:
{
url: [],
data: [],
started: false,
title: 'title',
init: function( url ) {
graphics.treemap.url = url;
graphics.treemap.load();
},
load: function() {
if ( typeof d3 != 'undefined' ) {
graphics.treemap.create();
} else {
if ( typeof d3 === 'undefined' ) {
graphics.load_script( 'js/d3.min.js', graphics.treemap.create );
}
}
},
create: function() {
if ( typeof d3 === 'undefined' || graphics.treemap.started ) {
return false;
} else {
graphics.treemap.started = true;
}
$( '#graphics .treemap' ).prepend( '<div id="graphic-treemap"></div>' );
addLoader($('#graphics .treemap'));
graphics.treemap.graphic = d3.layout.treemap().size([665, 445]).sort(function(a,b) { return a.size - b.size; }).sticky(true).value( function( d ){ return d.size; });
graphics.treemap.div = d3.select( '#graphics .treemap #graphic-treemap' );
d3.json (
graphics.treemap.url[ 0 ],
function( error, root ) {
var node = graphics.treemap.div.datum( root ).selectAll( '.node' )
.data( graphics.treemap.graphic.nodes )
.enter().append( 'div' )
.attr( 'class', 'node' )
.call( graphics.treemap.position )
.style( 'background', function( d ) { return d.color; } )
.html( function( d ) {
return '<a href="' + d.link + '"><span class="name">' + d.name + '</span>' +
'<strong class="value" style="' + ( graphics.treemap.adjustFontSize(d.size) ) + '">' + d.amount + '</strong>' +
'<span class="more-info" style="border:8px solid '+ d.color +';">' +
'<span class="name-inside" style="color:'+ d.color +';">' + d.name + '</span>' +
'<span class="year-and-amount">' + d.totalAmount + '</span>' +
'<span class="percent">' + d.percent + ' valor total do orçamento' + '</span>' +
'</span>' +
'</a>';
})
.call( graphics.treemap.adjustTreemapText )
.call( graphics.treemap.adjustHoverPosition );
/*node.on('mouseover',function(d){
});*/
removeLoader($('#graphics .treemap'));
});
},
position: function() {
this.style( 'left', function(d) { return d.x + "px"; })
.style( 'top', function(d) { return d.y + "px"; })
.style( 'width', function(d) { return d.dx + "px"; })
.style( 'height', function(d) { return d.dy + "px"; });
},
adjustFontSize: function(size){
if(size < 1){ return ' display:none;'; }
else if(size>=1 && size <=12){ return ' font-size:24px;'; }
else if(size> 12 && size <=50) { return ' font-size:'+ size*2 +'px;'; }
else if(size> 50 && size <=100) { return ' font-size:'+ size*1.5 +'px;'; }
else return ' font-size:150px;';
},
adjustTreemapText: function(){
$('.treemap .node').each(function(){
if($(this).width() == 0) { $(this).attr('style','display:none;'); }
});
$('.treemap .node a .name, .treemap .node a .value').each(function(){
var thisHeight = $(this).height()+20;
var thisParentHeight = $(this).parents('a').innerHeight();
if(thisHeight >= thisParentHeight){ $(this).attr('style','display:none;'); }
});
$('.treemap .node a .name').each(function(){
var text = $(this).text();
$(this).append('<em class="temporary" style="display:inline;">'+text+'<em/>');
var thisHeight = $(this).height()+30;
var thisParentHeight = $(this).parents('a').innerHeight();
if(thisHeight >= thisParentHeight){
var temporaryWidth = $(this).find('.temporary').width()+10;
var thisParentWidth = $(this).parents('a').innerWidth();
if(temporaryWidth >= thisParentWidth){ $(this).attr('style','display:none;'); }
}
$(this).find('.temporary').remove();
});
},
adjustHoverPosition: function(){
$('.treemap .node').each(function(index){
if(index > 0){
var leftStr = $(this).css('left');
var left = parseInt(leftStr.replace('px',''));
var topStr = $(this).css('top');
var top = parseInt(topStr.replace('px',''));
if(left > 332) { $(this).find('.more-info').css('left','').css({right:'15%'}); }
if(top > 222) { $(this).find('.more-info').css('top','').css({bottom:'20%'}); }
}
});
}
}
};
function addLoader(loaderContainer) {
loaderContainer.prepend('<div class="loader"><span class="loading"></span></div>');
}
function removeLoader(loaderContainer) {
loaderContainer.find('.loader').remove();
}
$(document).ready(
function() {
graphics.init();
}
);
Edit:
I'm trying to use jQuery UI .position(), but it doesn't seem to work.
adjustHoverPosition: function(){
$('.treemap .node a span.more-info').position({
collision: "flip",
within: "#graphic-treemap"
});
}

Related

I can't display temperature on my website

I'm new to Javascript and I followed a tutorial that is pretty easy to display open weather data on my website with javascript.
https://codepen.io/mattfroese/pen/WaeYQV
https://bytemaster.io/fetch-weather-openweathermap-api-javascript
It's very odd but it works on codepen and not my website...
Maybe you can help me ? Here is the code...
const key = '';
if(key=='') document.getElementById('temp').innerHTML = ('Remember to add your api key!');
function weatherBallon( cityID ) {
fetch('http://api.openweathermap.org/data/2.5/weather?lat=47.204530&lon=-1.563377&appid=OPENWEATHER_APP_ID')
.then(function(resp) { return resp.json() }) // Convert data to json
.then(function(data) {
drawWeather(data);
})
.catch(function() {
// catch any errors
});
}
function drawWeather( d ) {
var celcius = Math.round(parseFloat(d.main.temp)-273.15);
var fahrenheit = Math.round(((parseFloat(d.main.temp)-273.15)*1.8)+32);
var description = d.weather[0].description;
document.getElementById('description').innerHTML = description;
document.getElementById('temp').innerHTML = celcius + '°';
document.getElementById('location').innerHTML = d.name;
if( description.indexOf('rain') > 0 ) {
document.body.className = 'rainy';
} else if( description.indexOf('cloud') > 0 ) {
document.body.className = 'cloudy';
} else if( description.indexOf('sunny') > 0 ) {
document.body.className = 'sunny';
} else {
document.body.className = 'clear';
}
}
window.onload = function() {
weatherBallon( 6167865 );
}
footer {
position:fixed;
bottom:0px;
left:0;
height: 77px;
width: 100%;
margin: auto;
font: 30px "Elastik-B";
}
.footer ul {
margin: 0;
padding: 0;
position:absolute;
list-style-type: none;
bottom:15px;
right:5%;
}
.footer li {
text-align:right;
float: right;
display: block;
padding: 15px;
}
<footer>
<div class="footer">
<ul>
<li><div id="temp">...</div></li>
</ul>
</div>
</footer>
You have not added your api key in first line
const key = " ";
Please add api key and check if you are still getting an error message, try this
<script lang="text/javascript">
const key = 'b2b1b01a9261a8b31e450dffc404f9e9';
if(key=='') document.getElementById('temp').innerHTML = ('Remember to add your api key!');
function weatherBallon( cityID ) {
fetch('http://api.openweathermap.org/data/2.5/weather?lat=47.204530&lon=-1.563377&appid=b2b1b01a9261a8b31e450dffc404f9e9')
.then(function(resp) { return resp.json() }) // Convert data to json
.then(function(data) {
drawWeather(data);
})
.catch(function() {
// catch any errors
});
}
function drawWeather( d ) {
var celcius = Math.round(parseFloat(d.main.temp)-273.15);
var fahrenheit = Math.round(((parseFloat(d.main.temp)-273.15)*1.8)+32);
var description = d.weather[0].description;
document.getElementById('description').innerHTML = description;
document.getElementById('temp').innerHTML = celcius + '°';
document.getElementById('location').innerHTML = d.name;
if( description.indexOf('rain') > 0 ) {
document.body.className = 'rainy';
} else if( description.indexOf('cloud') > 0 ) {
document.body.className = 'cloudy';
} else if( description.indexOf('sunny') > 0 ) {
document.body.className = 'sunny';
} else {
document.body.className = 'clear';
}
}
window.onload = function() {
weatherBallon( 6167865 );
}
</script>

Jquery multicomplete suggestion box control with keyboard

This code work perfectly. but the suggested text can't control using keyboard
when arrow key up and down. i want to control this suggested text using keyboard
how can i do this. please help..................
/*
*
* jQuery MultiComplete
* =====================
* Written by Tom Hallam
* http://tomhallam.github.com/jQuery-Multicomplete/
* Licenced with the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence
* See: http://creativecommons.org/licenses/by-sa/3.0/
*
*/
(function ($) {
$.fn.multicomplete = function (options) {
// Set up the default options
var defaults = {
// Debug mode provides verbose error messages
debug: true,
// Source
source: [],
// AJAX Method (if source is a URL)
method: 'POST',
// Minimum length before a search can be triggered
minimum_length: 3,
// Delay before performing a search, ignored if source is local
search_delay: 500,
// Case sensitive search?
case_sensitive: false,
// Highlight found words?
highlight_results: true,
// Left offset for results panel
offset_left: 0,
// Top offset for results panel
offset_top: 5,
// Result template
result_template: function(row) {
// -- Please fill this in!
},
// Events -------
// On result click
result_click: null,
// On form submit
form_submit: null
},
// Extend the base object
settings = $.extend(defaults, options);
// Object to keep track of our timers
var timers = [],
// And our result groups
groups = {},
// The results themselves
results = [],
// And the query
query = '';
// Iterate over the selected elements and apply the behavior.
return this.each(function () {
multicomplete_init($(this));
});
// Bootstrapper function to attach events to the elements selected
function multicomplete_init(el) {
// Create a unique ID for this element
id = 'multicomplete-' + Math.floor(Math.random() * 1000);
$(el).data('multicomplete-id', id);
// Make a new key in our timer object
timers[id] = {};
// We need to set a timer for input to trigger based on a delay
$(el).on('keyup', function() {
// Keep a local copy of the value
query = $(this).val();
// Clear any old timers
window.clearTimeout(timers[id]);
// If there's nothing left in the input box, do nothing and hide my result panel
if(query.length == 0) {
$('.panel-multicomplete-results.' + id).hide();
return;
}
// Reset the results array
results = [];
// Make sure the query is hitting the minimum length constraint
if(query.length > settings.minimum_length) {
// Where are we sending this search?
switch(typeof(settings.source)) {
case 'string':
timers[id] = window.setTimeout(function(){
multicomplete_searchajax(function() {
multicomplete_render(el);
});
}, settings.search_delay);
break;
case 'object':
multicomplete_searchobject();
multicomplete_render(el);
break;
}
}
}).attr('autocomplete', 'off');
// Hide the DIV when someone clicks outside of the result pane.
$(document).on('mouseup', function(e) {
if($('.panel-multicomplete-results.' + id).has(e.target).length === 0) {
$('.panel-multicomplete-results.' + id).hide();
}
});
}
// Parse a result group
function multicomplete_parsegroup(group_results, group_name) {
// Loop through the group
$(group_results).each(function(index, row) {
for(var field in row) {
// No numbers (for now)
if(typeof row[field] == 'number') {
return true;
}
if(typeof row[field] == 'object') {
multicomplete_parsegroup(row);
}
else {
// If we find a result then push into our results array.
if(multicomplete_match(row[field])) {
results.push({
'field': field,
'row': row,
'group': group_name
});
return true;
}
}
}
});
}
// Does this string match the query
function multicomplete_match(field) {
if(settings.case_sensitive == true) {
return field.indexOf(query) > -1;
}
else {
return field.toLowerCase().indexOf(query.toLowerCase()) > -1;
}
}
// Search an object
function multicomplete_searchobject() {
if(settings.source.length == 0) {
if(settings.debug == true) {
alert('Source was set to an array, but the array was empty.');
}
}
// Loop through the source
for(var group_name in settings.source) {
if(settings.source[group_name].length)
groups[group_name] = multicomplete_parsegroup(settings.source[group_name], group_name);
}
}
// Search an AJAX endpoint
function multicomplete_searchajax(callback) {
// Perform the remote call.
ajax = $.ajax({
'type': settings.method,
'url': settings.source,
'dataType': 'json',
'data': {
'query': query
},
'success': function(data) {
// Loop through the source
for(var group_name in data) {
if(data[group_name].length)
groups[group_name] = multicomplete_parsegroup(data[group_name], group_name);
}
// Call the callback
callback.call(this, data);
},
'error': function(error) {
if(settings.debug == true) {
if(error.status == 412) {
alert('Your remote data source is not valid JSON! Remember to use double quotes instead of single.');
}
if(error.status == 404) {
alert('Your remote data source does not exist on this server.');
}
if(error.status == 500) {
alert('The remote server encountered an error whilst processing your source.');
}
}
}
});
}
// Render a search result
function multicomplete_render(el) {
// Where is the element
l = el.offset().left,
t = el.offset().top,
mc_html_class = 'panel-multicomplete-results ' + el.data('multicomplete-id'),
mc_class = '.panel-multicomplete-results.' + el.data('multicomplete-id');
// Is there already a results div for this element?
if($(mc_class).length == 0) {
// Build the div
$('<div class="' + mc_html_class + '"></div>').css({
'position': 'absolute',
'left': (l + settings.offset_left),
'top': (t + $(el).height() + settings.offset_top)
}).appendTo('body');
}
else {
$(mc_class).empty().show();
}
// Were there any results?
if(results.length == 0 && !$(mc_class + ' .panel-no-results').length) {
$('<div class="panel-no-results">No results found</div>').appendTo(mc_class);
}
else {
// Create a results div
$('<div class="results"></div>').appendTo(mc_class);
// Loop through the results and group them again
$(results).each(function(index, result) {
if($(mc_class + ' .results .' + result.group).length == 0) {
$('<div class="group ' + result.group + '"><div class="group-title">' + result.group + '</div><div class="group-items"></div></div>').appendTo(mc_class + ' .results');
}
// Cache the result row
r = $('<div class="result"></div>').appendTo(mc_class + ' .results .' + result.group + ' .group-items');
// Get the HTML for the result template
result_tmpl = settings.result_template.call(this, result.row, result.group, result.field);
// Apply the click action
$(result_tmpl).on('click', function() {
if(typeof settings.result_click == 'function') {
settings.result_click.call(this, result.row, result.group);
}
else {
multicomplete_defaultclick(result.row, result.group, el);
}
}).appendTo(r);
});
// Apply a clearfix to the groups
$('<div class="clearfix"></div>').appendTo(mc_class + ' .results .group');
// If we have the highlight option turned on then do that
if(settings.highlight_results == true) {
multicomplete_highlight($(mc_class + ' .results').get(0), query.toUpperCase());
}
}
}
// Default click action for a result
function multicomplete_defaultclick(result, group, el) {
// Is there even a form?
if($(el).closest('form').length == 0) {
}
else {
// Override the form submit to do some funky tings
$(el).closest('form').on('submit', function(e) {
// Check if we've already modified the form
if($(this).data('multicomplete-modified') == true) {
$(this).submit();
}
else {
// Stop the form from submitting
e.preventDefault();
// Modify the element
if(!!el.attr('name')) {
old_name = el.attr('name');
el.attr('name', el.attr('name' + '-mc-dummy'));
}
// Create a new hidden element with the ID
$('<input type="hidden" name="' + old_name + '" value="' + (!!result.id ? result.id : JSON.stringify(result)) + '" />').insertAfter(el);
// Add the checkpoint on to the form
$(this).data('multicomplete-modified', true);
// Submit the form
$(this).submit();
}
});
}
}
/*
highlight v3
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:jb#eaio.com>
*/
function multicomplete_highlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos = node.data.toUpperCase().indexOf(pat);
if (pos >= 0) {
var spannode = document.createElement('span');
spannode.className = 'highlight';
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(pat.length);
var middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
} else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < node.childNodes.length; ++i) {
i += multicomplete_highlight(node.childNodes[i], pat);
}
}
return skip;
}
}
})(jQuery);
$(document).ready(function() {
$('#input-multicomplete').multicomplete({
minimum_length: 1,
result_template: function(result, group, matched_field) {
tmpl = '<div>';
if(!!result.image) {
tmpl += '<div class="image"><img src="' + result.image + '" /></div>';
}
tmpl += '<div>' + result.name + '</div>';
if(!!result.address) {
tmpl += '<div class="meta">' + result.address + '</div>';
}
// Only display this field if something was matched in it
if(!!result.cuisine && matched_field == 'cuisine') {
tmpl += '<div class="cuisine">Cuisine offered: ' + result.cuisine + '</div>';
}
tmpl += '</div>';
return tmpl;
},
result_click: function(row, group) {
alert('You chose "' + row.name + '" in ' + group);
},
source: {
"Attractions": [
{
"name": "The Tower of London",
"address": "London, EC3N 4AB",
"image": "http://www.hrp.org.uk/Images/TOL_Main.jpg"
},
{
"name": "Camden Lock Market",
"address": "1 Kentish Town Road, London, NW1 8",
"image": "http://www.london-attractions.info/images/attractions/camden-market.jpg"
},
{
"name": "Anne Frank Museum",
"address": "Prinsengracht 267, 1000 AS, Amsterdam",
"image": "http://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/AnneFrankHouseAmsterdamtheNetherlands.jpg/220px-AnneFrankHouseAmsterdamtheNetherlands.jpg"
}
],
"Hotels": [
{
"name": "The Ritz",
"address": "150 Piccadilly, London, W1J 9BR",
"image": "http://www.londonhotels.net/images/photogallery/the-ritz-london/the-ritz-london.jpg"
},
{
"name": "51 Buckingham Gate",
"address": "51 Buckingham Gate, London, SW1E 6AF",
"image": "http://static.laterooms.com/hotelphotos/laterooms/193559/gallery/51-buckingham-gate-london_060620111405093617.jpg"
},
{
"name": "Hotel de l'Europe",
"address": "2–14 Nieuwe Doelenstraat, Amsterdam, 1012 CP ",
"image": "http://www.concierge.com/images/cnt/lists/goldlist06/europe/netherlands/amsterdam/hotel_de_leurope/amsterdam_hotel_002p.jpg"
}
],
"Restaurant": [
{
"name": "Petrus",
"address": "1 Kinnerton Street, Knightsbridge, London, SW1X 8EA",
"image": "http://berkshirereview.net/images/petrus_london_dining.jpg"
},
{
"name": "Vermeer",
"address": "Prins Hendrikkade 59-72, 1012 AD Amsterdam ",
"image": "http://www.restaurantvermeer.nl/Portals/7/UltraPhotoGallery/3425/45/[7].Vermeer---desert-2.jpg"
}
]
}
});
});
/* DEMO STYLES */
.result .image {
float: left;
margin-right: 10px;
}
.result .image img {
width: 32px;
height: 32px;
border: 1px solid #ccc;
padding: 1px;
}
.result .meta {
font-size: 11px;
color: #666;
}
.result a {
text-decoration: underline;
}
.result:hover {
background-color: #f7f7f7;
}
/*
*
* jQuery MultiComplete
* =====================
* Written by Tom Hallam
* http://tomhallam.github.com/jQuery-Multicomplete/
* Licenced with the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence
* See: http://creativecommons.org/licenses/by-sa/3.0/
*
*/
.panel-multicomplete-results {
border: 1px solid #ccc;
width: 420px;
font-family: Tahoma;
font-size: 12px;
background: url(mc-bg.png) repeat-y;
}
.panel-multicomplete-results .result {
padding: 5px;
border-bottom: 1px solid #e7e7e7;
cursor: pointer;
}
.panel-multicomplete-results .result:last-child {
border: none;
}
.panel-multicomplete-results .group {
border-bottom: 1px solid #ccc;
}
.panel-multicomplete-results .group:last-child {
border: none;
}
.panel-multicomplete-results .group-title {
float: left;
width: 100px;
padding: 5px;
font-weight: bold;
}
.panel-multicomplete-results .group-items {
float: left;
width: 300px;
}
.highlight {
font-weight: bold;
}
/* UTILITIES */
.clearfix {
clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
Start typing a city: <input type="text" name="multiselect" id="input-multicomplete" />
</div>
https://jsfiddle.net/ynyqed1m/

jquery Multiple text scroll on div hover not work

I have This Code for scroll text on hover div using jQuery:
HTML:
<div id="target" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">
<span class="tooMuchText tooMuchText1">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
<br>
<div id="target" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">
<span class="tooMuchText tooMuchText1">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
<br>
<div id="target" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">
<span class="tooMuchText tooMuchText1">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
JS:
$(function()
{
$(".tooMuchText1").hoverForMore({
"speed": 300,
"loop": false,
"target":'#target'
});
});
CSS:
.tooMuchText {
overflow: hidden;
white-space: nowrap;
display: block;
text-align: left;
text-overflow: ellipsis;
cursor: default;
}
So, I need to Scroll multiple(for each) div text on hover with target id. But My code Work only in first div with target id. how do can I fox this problem ?!
Demo jsfiddle
This is just example can you try multiple class in div ? if yes than i have try this in js fiddle please check.. if it may help you
(function($, window) {
var isjQuery = !!$.fn.jquery;
var isFirefox = /Firefox/.test(navigator.userAgent);
var isMobile = /Mobile/.test(navigator.userAgent);
var defaults = {
"speed": 60.0,
"gap": 20,
"loop": true,
"removeTitle": true,
"snapback": true,
"alwaysOn": false,
"addStyles": true,
"target": true,
"startEvent": isMobile ? "touchstart" : (isjQuery ? "mouseenter" : "mouseover"),
"stopEvent": isMobile ? "touchend" : (isjQuery ? "mouseleave" : "mouseout")
};
$.fn['hoverForMore'] = function(options) {
var self = this;
var head = document.getElementsByTagName('head')[0];
var originalOverflow, originalOverflowParent, startTime;
options = $.extend({}, defaults, options);
var targetSelector = options.target || self.selector;
// Always-on without looping is just silly
if (options.alwaysOn) {
options.loop = true;
options.startEvent = "startLooping"; // only triggered programmatically
}
// Detect CSS prefix and presence of CSS animation
var hasAnimation = document.body.style.animationName ? true : false,
animationString = 'animation',
transitionString = 'transition',
transformString = 'transform',
keyframePrefix = '',
domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
pfx = '';
// Find the CSS prefix, if necessary
if (hasAnimation === false)
for (var i = 0; i < domPrefixes.length; i++) {
if (document.body.style[domPrefixes[i] + 'AnimationName'] === undefined)
continue;
pfx = domPrefixes[i];
animationString = pfx + 'Animation';
transitionString = pfx + 'Transition';
transformString = pfx + 'Transform';
cssPrefix = '-' + pfx.toLowerCase() + '-';
hasAnimation = true;
break;
}
// Auto-add ellipsis and such
if (options.addStyles) {
head.appendChild($(
'<style type="text/css">' + self.selector + '{' + 'cursor:default;' + 'text-align:left;' + 'display:block;' + 'overflow:hidden;' + 'white-space:nowrap;' + 'text-overflow:ellipsis;' + cssPrefix + 'user-select: none;' + '}</style>')[0]);
}
// Non-animation fallback. TODO: Animate with jQuery instead
if (!hasAnimation) {
// Fallback to title text hover
$(options.target || self.selector).each(function(n, el) {
var $el = $(el);
$el.attr("title", $.trim($el.text()));
});
return self;
}
// Keyframes are only used in loop mode
if (options.loop) {
// Attach global style
var $keyframeStyle = $('<style type="text/css"></style>');
var $keyframeStyleReverse = $('<style type="text/css"></style>');
head.appendChild($keyframeStyle[0]);
head.appendChild($keyframeStyleReverse[0]);
}
// For non-loop mode, set an empty transform value (FireFox needs this to transition properly)
else {
$(self.selector).each(function(n, el) {
el.style[transformString] = 'translateX(0px)';
});
}
// Attach start event
$(targetSelector).on(options.startEvent, function(e) {
startTime = (new Date()).getTime();
// Get hovered item, and ensure that it contains an overflown item
var $item = $(options.target ? self.selector : this).filter(":first");
if (!$item.length) return true;
var $parent = $item.parent();
var pixelDiff = $item[0].scrollWidth - $item.width();
if (pixelDiff <= 0) // && !options.alwaysOn // TODO: <marquee> without overflow
return true;
if (options.removeTitle) $item.removeAttr("title");
// Over-ride the text overflow, and cache the overflow css that we started with
originalOverflowParent = originalOverflowParent || $parent.css("overflow");
originalOverflow = originalOverflow || $item.css("overflow");
$parent.css("overflow", "hidden");
if (isMobile && options.addStyles)
$('body').css(cssPrefix + "user-select", "none");
$item
.css("overflow", "visible")
.addClass("scrolling");
if (options.loop) {
// Remove a previous clone
$item.children(".hoverForMoreContent").remove();
// Attach a duplicate string which will allow content to appear wrapped
var $contentClone = $('<span class="hoverForMoreContent" />')
.css({
"paddingLeft": parseInt(options.gap) + "px"
})
.text($item.text());
$item.append($contentClone);
var contentWidth = ($contentClone.width() + parseInt(options.gap));
// Build keyframe string and attach to global style
var keyframes = '#' + cssPrefix + 'keyframes hoverForMoreSlide { ' + 'from {' + cssPrefix + 'transform:translateX( 0 ) }' + 'to {' + cssPrefix + 'transform:translateX( -' + contentWidth + 'px ) }' + '}';
$keyframeStyle[0].innerHTML = keyframes;
// Go go gadget animation!
var sec = contentWidth / parseFloat(options.speed);
$item[0].style[animationString] = 'hoverForMoreSlide ' + sec + 's linear infinite';
} else // if(!options.loop)
{
var sec = pixelDiff / parseFloat(options.speed);
// Apply transition + transform instead of looping
$item[0].style[transitionString] = cssPrefix + 'transform ' + sec + 's linear';
// Alas, Firefox won't honor the transition immediately
if (!isFirefox)
$item[0].style[transformString] = 'translateX(-' + pixelDiff + 'px)';
else setTimeout(function() {
$item[0].style[transformString] = 'translateX(-' + pixelDiff + 'px)';
}, 0);
}
});
// Attach stop event
if (!options.alwaysOn)
$(targetSelector).on(options.stopEvent, function(e) {
var $item = $(options.target ? self.selector : this).filter(":first");
if (!$item.length) return true;
if (options.loop) {
if (options.snapback) {
// Reverse our animation
var contentWidth = $item.children('.hoverForMoreContent').width() + parseInt(options.gap);
var timeDiff = ((new Date()).getTime() - startTime) * 0.001;
var offsetX = (timeDiff * options.speed) % contentWidth;
var switchDirection = offsetX > (contentWidth / 2);
// Build keyframe string and attach to global style
var keyframes = '#' + cssPrefix + 'keyframes hoverForMoreSlideReverse { ' + 'from {' + cssPrefix + 'transform:translateX( ' + (0 - offsetX) + 'px ) }' + 'to {' + cssPrefix + 'transform:translateX( ' + (switchDirection ? 0 - contentWidth : 0) + 'px ) }' + '}';
$keyframeStyleReverse[0].innerHTML = keyframes;
var sec = (switchDirection ? contentWidth - offsetX : offsetX) * 0.2 / parseFloat(options.speed);
$item[0].style[animationString] = 'hoverForMoreSlideReverse ' + (sec > 1 ? 1 : sec) + 's linear';
$item.removeClass("scrolling");
// After animation resolves, restore original overflow setting, and remove the cloned element
setTimeout(function() {
if ($item.is(".scrolling")) return;
$item
.children(".hoverForMoreContent")
.remove();
$item.css("overflow", originalOverflow);
$item.parent().css("overflow", originalOverflowParent);
if (isMobile && options.addStyles)
$('body').css(cssPrefix + "user-select", 'text');
}, (sec * 1000) - -50);
} else // if(!options.snapback)
{
$item[0].style[animationString] = '';
$item
.css("overflow", originalOverflow)
.find(".hoverForMoreContent")
.remove();
$item.parent().css("overflow", originalOverflowParent);
if (isMobile && options.addStyles)
$('body').css(cssPrefix + "user-select", 'text');
}
} else // if(!options.loop)
{
var timeDiff = ((new Date()).getTime() - startTime) / 1000.0;
var match = $item[0].style[transitionString].match(/transform (.*)s/);
var sec = (match && match[1] && parseFloat(match[1]) < timeDiff) ? parseFloat(match[1]) : timeDiff;
sec *= 0.5;
if (!options.snapback)
$item[0].style[transitionString] = '';
else
$item[0].style[transitionString] = cssPrefix + 'transform ' + sec + 's linear';
$item.removeClass("scrolling")
// Firefox needs a delay for the transition to take effect
if (!isFirefox)
$item[0].style[transformString] = 'translateX(0px)';
else setTimeout(function() {
$item[0].style[transformString] = 'translateX(0px)';
}, 0);
if (!options.snapback) {
$item.css("overflow", originalOverflow);
if (isMobile && options.addStyles)
$('body').css(cssPrefix + "user-select", 'text');
} else // if(options.snapback)
{
setTimeout(function() {
if ($item.is(".scrolling")) return;
$item.css("overflow", originalOverflow);
if (isMobile && options.addStyles)
$('body').css(cssPrefix + "user-select", 'text');
}, sec * 1000);
}
}
});
// To manually refresh active elements when in always-on mode
self.refresh = function() {
$(self.selector).each(function(n, el) {
$(el).not(".scrolling").trigger(options.startEvent);
})
};
// Always-on mode, activate! <marquee>, eat your heart out.
if (options.alwaysOn)
self.refresh();
return self;
};
})(window.jQuery || $);
$(function() {
$(".tooMuchText1").hoverForMore({
"speed": 300,
"loop": false,
"target": '#target'
});
$(".tooMuchText2").hoverForMore({
"speed": 300,
"loop": false,
"target": '#target1'
});
$(".tooMuchText3").hoverForMore({
"speed": 300,
"loop": false,
"target": '#target2'
});
});
.tooMuchText {
overflow: hidden;
white-space: nowrap;
display: block;
text-align: left;
text-overflow: ellipsis;
cursor: default;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="target" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">
<span class="tooMuchText tooMuchText1">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
<br>
<div id="target1" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">
<span class="tooMuchText tooMuchText2">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
<br>
<div id="target2" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">
<span class="tooMuchText tooMuchText3">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
There is at least one conceptual problem here:
id's should always be unique - for identical items, use classes
There are obviously more elegant ways to do this, but latching onto your use of id's, you can expand that, and iterate through the spans, gather their unique ID, then grab the unique ID of the parent, using that as the target.
$(function() {
$(".tooMuchText").each(function() {
var thisParentId = $(this).parents("div").attr("id");
var thisId = $(this).attr("id");
$('#' + thisId).hoverForMore({
"speed": 300,
"loop": false,
"target": '#' + thisParentId
});
});
});
To finish this up, just add a unique id to each of your SPANs and DIVs.
<div id="target3" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">
<span id='tooMuchText3' class="tooMuchText">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>

Script Re-sizing Webpage

I am currently using a Shooting Star script I found online to randomize shooting stars across the webpage. Whenever a shooting star goes out of the visible webpage, scroll bars appear and re-size the entire page for a moment. This happens quite frequently. Is there a way I can just have the shooting star delete itself once it hits the edge of the webpage, or maybe have it so that the webpage isn't affected by the shooting stars? Here's the website where I got the script from: http://codepen.io/manufosela/pen/Gymih
Here's the code:
<html>
<head>
<title>Shooting star Example</title>
<meta charset="utf-8">
<meta name="author" content="#manufosela">
</head>
<body class="stars">
<h1>SHOOTING STARS...</h1>
<div id="ShootingStarParams"></div>
<script type="text/javascript" src="http://codeorigin.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="ShootingStarClass.js"></script>
<script type="text/javascript">
$( document ).ready( function(){
var shootingStarObj = new ShootingStar( "body" );
shootingStarObj.launch();
});
</script>
</body>
</html>
body { color:#FFF; height:600px; width:99%; height:95%; color:#FFF; }
.stars {
z-index: 0; position: absolute; /* width: 420em; height: 70em; */
background-image: url( http://www.14denoviembre.es/img/hori.png ), url( http://www.14denoviembre.es/img/stars_5.png ); background-repeat: repeat-x,repeat-x repeat-y;
transform:translate3D(0em, 0em, 0); animation: stars 21s ease; transform-style: preserve-3d;
}
(function(){
/**
author: #manufosela
2013/08/27 copyleft 2013
ShootingStar class Main Methods:
launch: launch shooting stars every N seconds received by param. 10 seconds by default.
launchStar: launch a shooting star. Received options object by param with:
- dir (direction between 0 and 1)
- life (between 100 and 400)
- beamSize (between 400 and 700)
- velocity (between 2 and 10)
**/
ShootingStar = function( id ) {
this.n = 0;
this.m = 0;
this.defaultOptions = { velocity:8, starSize:10, life:300, beamSize:400, dir:-1 };
this.options = {};
id = ( typeof id != "undefined" )?id:"";
this.capa = ( $( id ).lenght > 0 )?"body":id;
this.wW = $( this.capa ).innerWidth();
this.hW = $( this.capa ).innerHeight();
};
ShootingStar.prototype.addBeamPart = function( x, y ) {
this.n++;
var name = this.getRandom( 100, 1 );
$( "#star"+name ).remove();
$( this.capa ).append( "<div id='star"+name+"'></div>" );
$( "#star"+name ).append( "<div id='haz"+this.n+"' class='haz' style='position:absolute; color:#FF0; width:10px; height:10px; font-weight:bold; font-size:"+this.options.starSize+"px'>·</div>" );
if ( this.n > 1 ) $( "#haz" + ( this.n - 1 ) ).css( { color:"rgba(255,255,255,0.5)" } );
$( "#haz" + this.n ).css( { top: y + this.n, left: x + ( this.n * this.options.dir ) } );
}
ShootingStar.prototype.delTrozoHaz = function() {
this.m++;
$( "#haz" + this.m ).animate( {opacity:0}, 75 );
if ( this.m >= this.options.beamSize ) { $( "#ShootingStarParams" ).fadeOut( "slow" ); }
}
ShootingStar.prototype.getRandom = function( max, min ) {
return Math.floor( Math.random() * (max - min + 1)) + min;
}
ShootingStar.prototype.toType = function ( obj ) {
if ( typeof obj === "undefined" ) { return "undefined"; /* consider: typeof null === object */ }
if ( obj === null ) { return "null"; }
var type = Object.prototype.toString.call( obj ).match( /^\[object\s(.*)\]$/ )[1] || '';
switch ( type ) {
case 'Number': if ( isNaN( obj ) ) { return "nan"; } else { return "number"; }
case 'String': case 'Boolean': case 'Array': case 'Date': case 'RegExp': case 'Function': return type.toLowerCase();
}
if ( typeof obj === "object" ) { return "object"; }
return undefined;
}
ShootingStar.prototype.launchStar = function( options ) {
if ( this.toType( options ) != "object" ) { options = {}; }
this.options = $.extend( {}, this.defaultOptions, options );
this.n=0;
this.m=0;
var i=0, l=this.options.beamSize,
x=this.getRandom( this.wW - this.options.beamSize - 100, 100 ), y=this.getRandom( this.hW - this.options.beamSize - 100, 100 ),
self = this;
for( ; i<l; i++ ) { setTimeout( function(){ self.addBeamPart( x, y ); }, self.options.life + ( i * self.options.velocity ) ); }
for( i=0; i<l; i++ ) { setTimeout( function(){ self.delTrozoHaz() }, self.options.beamSize + ( i * self.options.velocity ) ); }
$( "#ShootingStarParams" ).html( "Launching shooting star. PARAMS: wW: " + this.wW + " - hW: " + this.hW + " - life: " + this.options.life + " - beamSize: " + this.options.beamSize + " - velocity: " + this.options.velocity );
$( "#ShootingStarParams" ).fadeIn( "slow" );
}
ShootingStar.prototype.launch = function( everyTime ) {
if ( this.toType( everyTime ) != "number" ) { everyTime = 10; }
everyTime = everyTime * 1000;
this.launchStar();
var self = this;
setInterval( function() {
var options = {
dir: ( self.getRandom( 1, 0 ))?1:-1,
life: self.getRandom( 400, 100 ),
beamSize: self.getRandom( 700, 400 ),
velocity: self.getRandom( 10, 4 )
}
self.launchStar( options );
}, everyTime );
}
})();
body {
overflow: hidden;
}
This prevents scrollbars from appearing when content of an element goes beyond its dimensions.

Don't success to change the input width

I'm making some project like that should look like http://jsbin.com
when I'm trying to change the input width it is does'nt success
var clickedHtml = "#EFEDEF";
var clickedCss = "#EFEDEF";
var clickedJs = "#EFEDEF";
var clickedRes = "#EFEDEF";
function inputSize() {
var perc = 0;
if (clickedHtml == "#818081") {
perc++;
}
if (clickedCss == "#818081") {
perc++;
}
if (clickedJs == "#818081") {
perc++;
}
if (clickedRes == "#818081") {
perc++;
}
if (perc != 0) {
perc = 100 / perc;
}
return "\"" + perc.toString() + "%\"";
}
$("#htmlBut").click(function () {
if (clickedHtml == "#EFEDEF") {
$("#htmlBut").css("backgroundColor", "#818081");
clickedHtml = "#818081";
} else {
$("#htmlBut").css("backgroundColor", "#EFEDEF");
clickedHtml = "#EFEDEF";
}
$("#htmlField").css({
width: inputSize(),
display: 'block'
});
});
htmlField - input id.
htmlBut - html button id.
You need to just return the value as a string, no need to enclose it in ""
return perc.toString() + "%";
In your case the returned value "50%" is not valid, it should be just 50%
Return 'return perc.toString() + "%";' from inputSize method.

Categories