I am having problem getting my tooltip to work when using the jQuery load() function. The tooltip works fine if i don't use load() to load external dynamic data.
I googled and found the i may need to use live(), but I can't figure how to get it to work. Any suggestion?
thank you!!
Here is my scripts:
function loadEMERContent(uid) {
$("#ActionEWPNBook").load("ajaxLoadDATA.cfm?uid="+uid, null, showLoading);
$("#EWPNBookloading").html('<img src="/masterIncludes/images/ajaxLoading.gif" alt="loading" align="center" />');
}
function showLoading() {
$("#EWPNBookloading").html('');
}
function simple_tooltip(target_items, name){
$(target_items).each(function(i){
$("body").append("<div class='"+name+"' id='"+name+i+"'><p style='padding:5px;'>"+$(this).attr('title')+"</p></div>");
var my_tooltip = $("#"+name+i);
$(this).removeAttr("title").mouseover(function(){
my_tooltip.css({opacity:0.8, display:"none"}).stop().fadeIn(400);
}).mousemove(function(kmouse){
my_tooltip.css({left:kmouse.pageX+15, top:kmouse.pageY+15});
}).mouseout(function(){
my_tooltip.stop().fadeOut(400);
});
});
}
Here is my ajaxLoadDATA.cfm: it returns an unorder list
<li><span title="dynamic title here" class="tipthis">date</span></li>
In your callback function, you need to run the tooltip code against the new items, like this:
function showLoading(data) { //data = the response text, passed from `.load()`
$("#EWPNBookloading").html('');
var items = //get items here, something like $('.giveMeATooltip', data);
var name = //set name, not sure what you're using for this
simple_tooltip(items, name);
}
One side tip, if you change this line:
$("body").append("<div class='"+name+"' id='"+name+i+"'><p style='padding:5px;'>"+$(this).attr('title')+"</p></div>");
To something like this:
$("body").append(
$("<div></div>", { 'class': name, 'id': name + i }).append(
$("<p style='padding:5px;'></p>").text($(this).attr('title'))
)
);
Your tooltip generation will be much faster due to how jQuery can cache document fragments for reuse.
I use a modified version of this tooltip. This version uses .live so loaded content will automatically have tooltip functionality. All you need to do is:
Add this script to your main page (adding it as an external file is perferred)
You need to ensure that the elements that need a tooltip have a class="tipthis" and that the tooltip contents are within the title attribute. Also, the tooltip can contain HTML (e.g. <h1>Tooltip</h1>Hello,<br>World).
You will also need some basic CSS:
#tooltip { background: #f7f5d1; color: #333; padding: 5px; width: 300px; }
Here is the script (using live and it requires jQuery version 1.4+)
/* Tooltip script */
this.tooltip = function(){
// Defaults
var tooltipSpeed = 300; // fadein speed in milliseconds
var xOffset = 20; // Don't use negative values here
var yOffset = 20;
$('.tipthis').live('mouseover',function(e) {
this.t = this.title;
this.title = '';
$('<div></div>', {
id : 'tooltip',
css: {
display : 'none',
position: 'absolute',
zIndex : 1000,
top : (e.pageY - xOffset) + 'px',
left : (e.pageX + yOffset) + 'px'
}
})
.html( this.t )
.appendTo('body');
$('#tooltip').fadeIn(tooltipSpeed);
})
.live('mouseout',function(){
this.title = this.t;
$('#tooltip').remove();
})
.live('mousemove',function(e){
$("#tooltip").css({
top : (e.pageY - xOffset) + 'px',
left: (e.pageX + yOffset) + 'px'
});
})
}
$(document).ready(function(){ tooltip(); });
Here is some sample HTML:
Hover over me!
Related
Here is my code:
var tagDes = document.createElement('DIV');
tagDes.className = 'tagDes';
tagDes.style.cssText = 'position:absolute;'+
'background:#282828;'+
'color:#fff;'+
'padding:10px;'+
'top:'+(posX+hei)+'px;'+
'left:'+(posY+wid)+'px;'+
'font-size:10pt;';
tagDes.onmouseout = function(){
$(this).remove();
};
$('#main-container').append(tagDes);
$('.tagDes').append(array[5]+'<a class="tagMenu">sdsdssds</a>');
posX, posY, hei, wid is reffering to an element for positioning. array[5] is a string.
I want to hover for a li and create div that contain link(tagMenu class) inside(looks like title attribute). But when I hover the link inside that div, the div will remove(). What I looking for is when I hover the link the div still visible and it will removed from page when I mouseout from it. Any suggestion? Please help me.
try something like this:
tagDes.onmouseout = function(e){
if (e.toElement.parentNode == this || e.toElement == this) {
return;
}
$(this).remove();
};
If I understood you correctly you want to bind onmouseout event to inner link element. Then the code can be like this (I made use of more jQuery to simplify it):
var $tagDes = $('<div class="tagDes"></div>').css({
background: '#282828',
color: '#fff',
padding: '10px',
top: (posX + hei) + 'px',
left: (posY + wid) + 'px',
fontSize: '10pt'
})
.append(array[5] + '<a class="tagMenu">sdsdssds</a>')
.appendTo('#main-container');
$tagDes.on('mouseleave', function() {
$tagDes.remove();
});
A user will be able to click on 3 points on an image, and i want to display a BLACK dot at those points. Then i will save these values in my database, and regenerate the image with those 3 points later on.
This is a 2 part question:
1.) In my code, i am not able to detect the onClick event when the image is clicked. Can someone look into this. Here's my code. JSFIDDLE
$(document).ready(function () {
$('body').click(function (ev) {
alert("d");
mouseX = ev.pageX;
mouseY = ev.pageY
alert(mouseX + ' ' + mouseY);
var color = '#000000';
var size = '1px';
$("body").append(
$('<div></div>')
.css('position', 'absolute')
.css('top', mouseY + 'px')
.css('left', mouseX + 'px')
.css('width', size)
.css('height', size)
.css('background-color', color));
});
});
HTML
<body background="http://www.craigjoneswildlifephotography.co.uk/blog/wp-content/uploads/2010/07/CMJ57311.jpg">
</body>
2.) Say that i have the X and Y coordinates of the points, and how can i regenerate the image with those points ?
Just use document instead of body (your body element has a calculated height of 0, but document is always the full size of the window):
http://jsfiddle.net/TrueBlueAussie/95vczfve/5/
$(document).ready(function () {
$(document).click(function (ev) {
mouseX = ev.pageX;
mouseY = ev.pageY
console.log(mouseX + ' ' + mouseY);
var color = '#000000';
var size = '1px';
$("body").append(
$('<div></div>')
.css('position', 'absolute')
.css('top', mouseY + 'px')
.css('left', mouseX + 'px')
.css('width', size)
.css('height', size)
.css('background-color', color));
});
});
As a side note: Your original JSFiddle is also a great example of why you should not connect delegated events to body instead of document. The body element can be styled out of existence (also document exists before the DOM is even loaded) :)
Or, as Brian provided, a reduced version http://jsfiddle.net/BrianDillingham/95vczfve/7/:
$(document).ready(function(){
$(document).click(function (ev) {
$("body").append(
$('<div></div>').css({
position: 'absolute',
top: ev.pageY + 'px',
left: ev.pageX + 'px',
width: '10px',
height: '10px',
background: '#000000'
})
);
});
});
And Brian's final update with limit of 3 dots: http://jsfiddle.net/BrianDillingham/95vczfve/8/
Your body has 0 height because it has 0 content.
Try adding this to your CSS:
html, body { height: 100%; margin: 0; }
Or try adding some content.
jsFiddle
On a side tip, a lot of things about your jQuery can be made cleaner/easier:
$(document).ready(function(){
// here I asign the event dynamically, not needed for 'body' as such tag should always be present,
// but something you should look into
// see also: http://api.jquery.com/on/
$(document).on('click', 'body', function(e) {
mouseX = e.pageX;
mouseY = e.pageY
// simply press F12 to look at your browsers console and see the results
console.log('Mouse Position:\t' + mouseX + '|' + mouseY);
// no need in JS to write var for every variable declartion,
// just seperate with a comma
var color = '#000000',
size = '5px'; // changed size to 5px from 1 just to make it easier to see what's going on for you
// No need to use $("body") since this event takes place on the body tag
// $(this), in an event, always equals the selector the event is tied to
$(this).append(
// making an element with jquery is simple
// no need to insert whole tag, all you need is tag name and a closer
// like so
$('<div />')
// easily tie all css together
.css({
// also, in jquery CSS, any css variable with a '-'
// can be renamed when assigning
// simply remove the '-' and capitilize the first letter of the second word
// like so, here in 'background-color'
backgroundColor: color,
height: size,
left: mouseX + 'px',
position: 'absolute',
top: mouseY + 'px',
width: size
})
);
})
});
Regarding part 2 of your question, my first thought is to include query params in the image URL, so that instead of http://www.example.com/thingies/someimage.jpg you get something like http://www.example.com/thingies/someimage.jpg?x0=10&y0=25&x1=30&y1=5. From there you would simply check if that string has query params with names matching what you're looking for (x0, y0, x1, etc...) and place points according to those.
Alternatively, you could also store the parameters in the URL for that web page, but that might lead to noisy URLs depending on what you're doing.
This depends on the server storing the coordinates, though.
My second thought is Local Storage, would store the points with the client, but that means that the points are not necessarily sent to the server, and are being read only from the client's browser. It also depends on the browser supporting that, and allowing that. Of course, since 3 coordinates is a rather small set of data, it could be stored in a browser cookie.
Here's what I'm trying to achieve:
Scrolling marquee content (with flexible length) makes a complete journey from right to left of the screen
Once it has disappeared off the screen, bring up some generic messages
In the background during generic messages, check for any new scrolling content and load it
Only when the generic messages have finished displaying, start scrolling again (if there is new content), otherwise repeat the generic messages
http://jsfiddle.net/Vbmm5/
(function($) {
$.fn.marquee = function(options) {
return this.each(function() {
var o = $.extend({}, $.fn.marquee.defaults, options),
$this = $(this),
$marqueeWrapper,
containerWidth,
animationCss,
elWidth;
o = $.extend({}, o, $this.data());
o.gap = o.duplicated ? o.gap : 0;
$this.wrapInner('<div class="js-marquee"></div>');
var $el = $this.find('.js-marquee').css({
'margin-right': o.gap,
'float':'left'
});
if(o.duplicated) {
$el.clone().appendTo($this);
}
$this.wrapInner('<div style="width:100000px" class="js-marquee-wrapper"></div>');
elWidth = $this.find('.js-marquee:first').width() + o.gap;
$marqueeWrapper = $this.find('.js-marquee-wrapper');
containerWidth = $this.width();
o.speed = ((parseInt(elWidth,10) + parseInt(containerWidth,10)) / parseInt(containerWidth,10)) * o.speed;
var animate = function() {
if(!o.duplicated) {
$marqueeWrapper.css('margin-left', o.direction == 'left' ? containerWidth : '-' + elWidth + 'px');
animationCss = { 'margin-left': o.direction == 'left' ? '-' + elWidth + 'px' : containerWidth };
}
else {
$marqueeWrapper.css('margin-left', o.direction == 'left' ? 0 : '-' + elWidth + 'px');
animationCss = { 'margin-left': o.direction == 'left' ? '-' + elWidth + 'px' : 0 };
}
$marqueeWrapper.animate(animationCss, o.speed , 'linear', function(){
getUpdates();
});
};
setTimeout(animate, o.delayBeforeStart);
});
};
})(jQuery);
$(function(){
$('#scrollerContent').marquee({
speed: 3000,
gap: 50,
delayBeforeStart: 0,
direction: 'right',
duplicated: false,
pauseOnHover: false,
});
});
function getUpdates()
{
alert("Hello"); // This is where the jQuery get function would be to update the text
alert("Show Details"); // This is where the generic details would be displayed
marquee();
}
The problem is the scrolling element requires a width, which obviously changes with every new 'load' of messages. I tried putting the getUpdates() function inside the main jQuery function, which does work almost perfectly but doesn't update the containerWidth variable, so messages longer than the original start half-way through, and shorter messages take ages to appear.
What I need is for the whole of the function to be re-run, including the re-setting of the width after the #scrollerText paragraph has been changed.
How do I do this?
If you had used console.log() instead of alert() you would have had the console open and seen
Uncaught ReferenceError: marquee is not defined
In getUpdates() you're calling a function marquee(); that does not exist. The script terminates there.
Go back a few steps (undoing what you've removed) and where the code triggers the animation, add the code to update the text before that, or if you're getting data you need to wrap that bit of code.
So, if you were getting data from the server, theurl.php would return text new text and nothing else. Move the code that triggers the animation to go again within the $.get callback function.
http://jsfiddle.net/Vbmm5/4/
$marqueeWrapper.animate(animationCss, o.speed , 'linear', function(){
// clear the text to prevent it from hanging at the end of the
// marquee while the script gets new data from the server
$this.find('#scrollerText').text('');
// get new text
$.get('theurl.php', function(response){
$this.find('#scrollerText').text(response);
// update the width
elWidth = $this.find('.js-marquee:first').width();
//fire event
$this.trigger('finished');
//animate again
if(o.pauseOnCycle) {
setTimeout(animate, o.delayBeforeStart);
}
else {
animate();
}
});
});
(the URL and post data in the example on jsfiddle is jsfiddle's way of returning html)
I've used $this.find('#scrollerText').text(response); even though there should be only one id and $('#scrollerText').text(response); would be fine. If you were to have multiple marquees you would target each marquee's text using $this.find, so if you want more than one use classes instead $this.find('.scrollerText').text(response);
I am trying to incrementally reposition an element by setting the -webkit-transform property to +=200px
But it doesn't work. I'm missing something, but don't know what.
http://jsfiddle.net/yVSDC/
Clicking the div is supposed to move it further down by 200px everytime.
CSS doesn't work like that, and jQuery doesn't pull that data out so you can do it like that.
You'd need to read the value, add 200 and then reset it.
var getTranslatedY = function (element) {
var transform = element.css("transform") || element.css("-webkit-transform") || element.css("-moz-transform");
if (transform == "none") {
return 0;
}
return parseInt((transform.match(/^matrix\(.*?(-?[\d.]+)\)$/) || [])[1]) || 0;
};
$('#m').on(
'click',
function () {
var element = $(this);
element
.css('-webkit-transform',
"translateY(" + (getTranslatedY(element) + 200) + "px)");
});
jsFiddle.
var step = 200;
$('body').on('click', "#m", function(){
$(this).css('-webkit-transform','translateY('+ step +'px)');
step = step+200;
});
And instead -webkit-transform:translateY(100px); in CSS you can set margin-top: 100px;
http://jsfiddle.net/yVSDC/28/
You have to get the Current webkit-transform value and increment it. Alternative Solution is ustin the top CSS Property
You can try this (it's free): http://ricostacruz.com/jquery.transit/
Sample Code:
$('.box').transition({ x: '200px' });
$('.box').transition({ y: '200px' });
$('.box').transition({ x: '200px', y: '200px' });
This doesn't seem to be working for me. I want to perform these actions only on images with a title attribute set. It seems my problem is when I use $(this), it is referring to the title attribute? Thanks in advance.
(function($) {
$(function() {
/* Run this only if images have a title attribute */
if ($('.node-page img[title], .node-news img[title]')) {
$(this).each(function() {
var image = $(this);
var caption = image.attr('title');
var imagealign = image.css('float');
image.after('<span class="caption">' + caption + '</span>');
image.next('span.caption').andSelf().wrapAll('<div>');
image.parent('div').addClass('caption-wrapper').css({'width': imagewidth, 'height': 'auto', 'float': imagealign});
});
}
});
})(jQuery);
It seems you got mixed-up with the if and the each(). You should apply your each to your selector directly. If no image have a title attribute then it won't do anything, else it will apply your function to each element.
(function($) {
$(function() {
/* Run this only on images that have a title attribute */
$('.node-page img[title], .node-news img[title]').each(function() {
var image = $(this);
var caption = image.attr('title');
var imagealign = image.css('float');
image.after('<span class="caption">' + caption + '</span>');
image.next('span.caption').andSelf().wrapAll('<div>');
image.parent('div').addClass('caption-wrapper').css({'width': imagewidth, 'height': 'auto', 'float': imagealign});
});
});
})(jQuery);