This problem only occurs on IE8 (not IE8 compatibility mode).
I have a file called sample.htm:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html><head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
<script src='http://jqueryjs.googlecode.com/files/jquery-1.3.2.js' type='text/javascript'></script>
</head>
<body style='position:relative;z-index:1'>
<input>Click
<script>
function Popup(url) {
overlay = $("<div style='position:fixed; width:100%; height:100%; z-index:10005'><div style='position:absolute; width:100%; height:100%; background:black; -ms-filter:\"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)\"; filter: alpha(opacity=50);'></div>");
iframe = $("<iframe name='Overlay' style='position:absolute; height:80%; width:80%; top:10%; left:10%;' src='" + url + "'></iframe>");
closebut = $("<img style='position:absolute; cursor:pointer; right:10%; top:10%;' width='24px' height='24px' src='/images/close.png' onclick='RemovePopup()' >");
overlay.append(iframe).append(closebut);
$('body').prepend(overlay);
}
function RemovePopup() {
overlay.animate({top:'100%'},800,'swing', function() { $(this).remove(); });
}
</script>
</div></body></html>
Here is the complete content of test1.html: <html><head></head><body><input></body></html>
So create these 2 files, open sample.htm in IE8, click the link to open the popup, type something in the textbox there, close the popup, try and type in the first textbox. If you can, repeat 2 or 3 times.
Eventually the first textbox becomes disabled.
Can anyone suggest a workaround?
Thanks for any help
Essentially I think this is a focus problem. If you can get the browser into the situation where the <input> seems disabled then you can actually Tab to the <input> and enter a value as expected.
I believe the $(this).remove(); call to remove the iframe at the end of the animation is causing the problem when an element in the iframe has focus. I'd suggest giving the first <input> focus before removing the iframe.
For example, use $('input:first').focus(); if it is the first input. It seems to work in my testing here.
Related
Me and a guy from work are working on a web application for our clients to log on and manage there details. One of the sections asks the user to upload there company logo but as we all know the html browes button or the tag as its also known is a hard cookie to style. this is how I want it to look:
But the reality is if I put a plain old file tag in there it would look bland, generic and out of place so I Googled for the solution and after a it of hunting I came across this code which yielded the image below the code (Which I also show the file upload without the opacity set to zero):
#divinputfile
{
height:85px;
width:250px;
margin:0px;
background-image: url(images/upload_file.gif);
background-repeat: no-repeat;
background-position: right bottom;
}
#divinputfile #filepc
{
opacity: 0.0;
-moz-opacity: 0.0;
filter: alpha(opacity=00);
font-size:16px;
cursor: pointer;
}
#filepc
{
margin-top: 12px;
}
#fakeinputfile
{
margin-top:-28px;
}
#fakeinputfile #fakefilepc
{
width:250px;
height:22px;
font-size:18px;
font-family:Arial;
}
<body>
<br />
<div id="divinputfile">
<div id="fakeinputfile">
<br />
<input name="fakefilepc" type="text" id="fakefilepc" />
</div>
<div align="right">
<input name="filepc" type="file" size="1" id="filepc" onchange="document.getElementById('fakefilepc').value = this.value;"/>
</div>
</div>
</body>
This is a basic hack and when I select the styled button I'm really selecting the invisible upload button, then the value of the upload is passed into the test box above to look like its really part of the upload. Two problem with this method and I hoping you'll be able to help me here is
a) Only the button can be click to upload. In most browsers(not including Chrome) you can click into the text box as well as the button to upload the image. Sure with this method the text of the file path is added to the textbox but any alteration to that box wont change the file eg: if you selected file1.jpg to upload but you really wanted file2.jpg, changing the file path in the textbox wont change a thing to the ACTUAL upload element
b) Some browers like Chrome and Opera add the \fakepath\ filepath to the textbox and this is just ugly, so any if statement that can strip this out also would be hugely useful.
Hope you guys can help me with this, if not via code hints then if anyone knows a good JavaScript plug that saves the day.
Thanks
You already have javascript for the textbox to display the new filepath value on change.
That’s where you will have to also remove any /fakepath/ parts etc.
You can also add a click event to the text-box which will activate the file-browse click event.
I can instantly tell you that’s rather easy with jQuery, but I don’t know how one would do it with plain JS.
/e:
In fact, it seems file-input actions can not be triggered. See related question In JavaScript can I make a "click" event fire programmatically for a file input element?
Question a:
No firing the click event. Security and all that. You could add a second invisible upload button just like the first. If one changes, clear out the other. And the hacks pile up...
Question b:
See Kissaki's answer. You'll need some JS to clear out that 2nd invisible field anyhow...
Here is a solution.
Question A is solved by making the <input type="file" /> the full size of your widget, and using divisions to create non-clickable areas.
Question B is solved using the trick I found here
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Style the File Upload Input - Example</title>
<style type="text/css">
#file-upload {
position:relative;
top:0px;
left:0px;
width:250px;
height:65px;
overflow:hidden;
padding-top:15px;
background-image: url(images/upload_file.gif);
background-repeat: no-repeat;
background-position: right bottom;
}
#file-upload input[type='file'] {
width:250px;
height:65px;
font-size:65px;
opacity:0;
filter:alpha(opacity=0);
position:absolute;
top:15px;
left:0px;
z-index:9;
}
#file-upload input {
width:97%;
}
#file-upload #no-click {
position:absolute;
bottom:0px;
left:0px;
z-index:10;
width:125px;
height:40px;
}
</style>
</head>
<body>
<div id="file-upload">
<input size="0" name="filepc" type="file" id="filepc" onchange="var clone = this.cloneNode(true);clone.type='text';document.getElementById('fakefilepc').value = clone.value?clone.value:this.value;" />
<div id="fake-file-upload">
<input name="fakefilepc" type="text" id="fakefilepc" />
<div id="no-click"></div>
</div>
</div>
</body>
You might want to worry about graceful degradation... here's the same with the HTML, CSS and JavaScript more cleanly separated which should degrade cleanly.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Style the File Upload Input - Example</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("body").addClass("js");
$("#file-upload").append("<div id=\"fake-file-upload\">" +
"<input name=\"fakefilepc\" type=\"text\" id=\"fakefilepc\" />" +
"<div id=\"no-click\"></div>" +
"</div>");
$("#file-upload input[type='file']").change(function() {
var clone = this.cloneNode(true);
clone.type='text';
document.getElementById('fakefilepc').value = clone.value?clone.value:this.value;
});
});
</script>
<style type="text/css">
#file-upload {
position:relative;
top:0px;
left:0px;
width:250px;
height:65px;
}
body.js #file-upload {
overflow:hidden;
padding-top:15px;
background-image: url(images/upload_file.gif);
background-repeat: no-repeat;
background-position: right bottom;
}
body.js #file-upload input[type='file'] {
width:250px;
height:65px;
font-size:65px;
opacity:0;
filter:alpha(opacity=0);
position:absolute;
top:15px;
left:0px;
z-index:9;
}
body.js #file-upload input {
width:97%;
}
body.js #file-upload #no-click {
position:absolute;
bottom:0px;
left:0px;
z-index:10;
width:125px;
height:40px;
}
</style>
</head>
<body>
<div id="file-upload">
<input size="0" name="filepc" type="file" id="filepc" />
</div>
</body>
I was using the following image as the image images/upload_file.gif (and its respective dimensions for everything related thereto)
I believe the following link might help you: "Ajax Upload; A file upload script with progress-bar, drag-and-drop".
Not really ajax, just a clever use of an iframe.
Hope it helps. Code well!
It's tough to do and even tougher to do cross-browser. Webkit (safari/chrome) has a very different way of handling this than the IEs and Mozilla. As shown, you'll end up resorting to a ton of hacks which you'll constantly need to check against each browser as they get released.
One way I've found is to progressively enhance to use a flash plug-in. You only need to check for flash being present and flashblock not blocking the element.
For example: http://www.uploadify.com/demos/ (although this doesn't seem to check for flashblock!)
I have a PHP form for discussions. Each message has its own response button, which is dynamically generated. I'm using javascript in the button to make a response form visible at the bottom of the page, but I can't for the life of me get the page to jump down to the form once it's visible. This is a problem for pages that have a lot of discussions on it, as some users may not know to scroll down and will just think the button didn't work.
Here's what I have now for my button code:
<img src="images/reply.jpg" border=0 />
The changeVisibility function looks like this:
function changeVisibility(parentID, elementID) {
document.getElementById(elementID).style.visibility="visible";
document.forms[0].parent_id.value=parentID;
var el = document.getElementById(elementID);
el.scrollIntoView(true);
}
In my form, I have a div whose id is set to responseForm. When clicking the button, the div does become visible, but the scrollIntoView is not working - I have to manually scroll down to see it. Any ideas?
Use window.location.hash
function changeVisibility(parentID, elementID) {
document.getElementById(elementID).style.visibility="visible";
document.forms[0].parent_id.value=parentID;
window.location.hash = '#' + elementID;
return false;
}
<img src="images/reply.jpg" border=0 />
EDIT: I think the issue before was that you weren't returning false, so the default action (going to #) was still occurring.
OK, I finally found something that works. I've been doing what I was taught to do in the Stone Age: when using javascript calls in what needs to be a link, use
a href="#" onClick="yourFunction()"
Apparently it's the # that's killing things for me; if I just use
a href="javascript:yourFunction()"
it works correctly. This may or may not be considered good practice anymore, but it works.
User window.location.hash to redirect to an ID/anchor. E.g.
HTML:
<p id="youranchor">bla bla</p>
JavaScript:
window.location.hash='youranchor';
EmmyS - This code does work. Here's a complete example for you:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Some title</title>
<script type="text/javascript">
function jumpToParagraph() {
window.location.hash='paragraphjump';
}
</script>
</head>
<body>
<p onclick='jumpToParagraph();'>Jump to the paragraph at the end! [version 1]</p>
<p>Jump to the paragraph at the end! [version 2]</p>
<p style="height: 1500px;">Some nonsense</p>
<p id="paragraphjump">You made the jump</p>
</body>
</html>
Put it into a file and test the file in your browser.
Hmm, you could try using document.body.scrollTop = document.getElementById(elementId).offsetTop; (not tested)
Hum, the following JavaScript code works like a charm:
<script type="text/javascript">
function scrollToPos() {
var el = document.getElementById("abc");
el.style.visibility = "visible";
el.style.display = "block";
el.scrollIntoView(true);
}
</script>
When clicking this link scroll<br />
the following div get's gets visible and scrolls into view (tested in IE6, IE8, FF3.6.3, Google Chrome 4.1 and Opera 10.5, all on windows)
<div id="abc" style="height:100px;color:red;font-weight:bold;visibility:hidden;display:none;">
abc
</div>
$("#id").tooltip({
effect: "slide",
tip: '.tooltip'
});
I want to delete the object created by this code.
"flowplayer jquery tools" plugin
This question has an answer described in the bottom of my post!
See the bottom if you don't wanna loose you time
.
----------UPDATE----------
That should be something like this
The code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html><head>
<title>jQuery tooltip</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="http://cdn.jquerytools.org/1.1.2/full/jquery.tools.min.js"></script>
<script type="text/javascript">
/******* THIS FUNCTION IS JUST FOR TEST, REMOVE IT LATER *********/
$(document).ready(function() {
$("#_2").tooltip({
effect: "slide",
tip: '.tooltip' ,
position: 'bottom center'
});
});
/******* THIS FUNCTION IS JUST FOR TEST, REMOVE IT LATER *********/
/** The code below is not working as I expect, it doesn't MOVE tooltip **/
var old_id;
//first time - create tooltip
function my_create(id){
$("#"+id).tooltip({
effect: "slide",
tip: '.tooltip',
position: 'bottom center'
});
}
//next times - move tooltip to other element
function my_unlink(id){
$("#"+id).unbind("mouseover");
//todo
}
function my_link(id){
//todo
}
//THE MAIN FUNCTION
function do_tip(new_id){
if(old_id){
my_unlink(old_id);
my_link(new_id);
alert(new_id);
}
else
my_create(new_id);
old_id=new_id;
//new_id.focus();
}
</script>
<style>
.tooltip {
display: none;
background:transparent url(http://flowplayer.org/tools/img/tooltip/black_arrow_bottom.png);
font-size:14px;
height:70px;
width:160px;
padding:25px;
color:#fff;
}
h1 {
width: 400px;
text-align: center;
background-color: yellow;
}
</style>
</head>
<body>
<h1 onclick="do_tip(this.id)" id="_1">John</h1>
<h1 onclick="do_tip(this.id)" id="_2">Mary</h1>
<h1 onclick="do_tip(this.id)" id="_3">Dan</h1>
<h1 onclick="do_tip(this.id)" id="_4">Paul</h1>
<h1 onclick="do_tip(this.id)" id="_5">Kim</h1>
<div class="tooltip">There should be only one tooltip on a page!</div>
</body></html>
.
---------UPDATE 2----------
Here's the answer
Linking/unlinking jquery object to an element
The moral of this long tale is:
I've been thinking it's a common, not code or plugin-specific question. I thought that the solution should be as simple as "destroy old tooltip object and then create a new one, attatched to other element"
You write that you want to delete the object created by the code.
What the code does is that first searches for an element with id 'ID' in your page,
let's call this "the trigger".
I'm changing one thing in the code here: Instead of selecting the trigger by id 'ID'
I select using the class 'do_tooltip_for_this'. This way I can set up a tooltip for
multiple triggers at once.
If the user moves the mouse over the trigger, an element with class 'tooltip', that is
already present in the page, will be shown and positioned near that trigger.
If the user moves the mouse away from the trigger this element is automatically hidden again.
This works for several triggers as well, the same tooltip is reused.
You can also hide the tooltip by hand by writing
$('.tooltip').hide();
You can disable the whole behaviour by writing
$(".do_tooltip_for_this").unbind("mouseover");
Here's the whole code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html><head>
<title>jQuery tooltip</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="http://cdn.jquerytools.org/1.1.2/full/jquery.tools.min.js"></script>
<script type="text/javascript">
var o;
$(document).ready(function() {
o = $(".do_tooltip_for_this").tooltip({
effect: "slide",
tip: '.tooltip' ,
position: 'bottom center'
});
});
</script>
<style>
.tooltip {
display: none;
background:transparent url(http://flowplayer.org/tools/img/tooltip/black_arrow_bottom.png);
font-size:12px;
height:70px;
width:160px;
padding:25px;
color:#fff;
}
h1 {
width: 400px;
text-align: center;
background-color: yellow;
}
</style>
</head>
<body>
<h1 title="a tooltip regarding John" class="do_tooltip_for_this">This is John</h1>
<h1 title="a tooltip regarding Paul" class="do_tooltip_for_this">This is Paul</h1>
<h1 title="a tooltip regarding George" class="do_tooltip_for_this">This is George</h1>
<h1 title="a tooltip regarding Ringo" class="do_tooltip_for_this">This is Ringo</h1>
<div class="tooltip"></div>
</body></html>
How about using this:
delete (object_here);
This will remove the javascript objects.
Depends. If you to something like .remove() on it, it actually removes the entire element with that ID from the page.
If you just want to remove the tooltip from it, check out the plugin that you're using. Usually plugins provide a destroy option (the dialog provided by jQuery UI does this).
Unless you're willing to remove the entire element from the page and then recreate it, these is nothing in the core library to do that. If you wanna give that method a go this would get you going in the right direction:
$('#id').replaceWith($('#id').clone());
By default .clone won't copy events and data bound to an element, so that should be a dirty way to get rid of the tooltip. But again, see if your plugin has any built-in way to clean up.
$("#id").tooltip({});
Have you tried that?
by using jQuery you could use .remove()
$("#id").remove(); // will remove element with an id of 'id'
EDITED
it work for someone here. It might also work on you.
// unbind focus and mouseover to cover all the bases just
// incase the tooltip is not being applied to an input
$("#id").unbind("focus");
$("#id").unbind("mouseover");
$("#id").removeData('tooltip');
Here is some code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style>
body { margin:0; padding:0; }
#a {
position:absolute;
background:#0FF;
left:0;
height:300px;
width:120px;
}
input, #a {
margin:10px;
}
</style>
<script>
function foo() {
box = document.getElementById('a');
var computedStyle = box.currentStyle || window.getComputedStyle(box, null);
box.style.left = parseInt(computedStyle.left) + 10 + 'px';
setTimeout("foo()",20);
}
</script>
</head>
<body>
<input type="button" value="RUN, FORREST, RUN!" onClick="setTimeout('foo()',20)">
<div id="a"></div>
</body>
</html>
As you can see, it animates DIV at page, but animation isn't clear and smooth — border of DIV actually deforming.
Somebody know how i can make it work correctly?
Ditto JustLoren: it works fine on my machine. I'm not sure what you mean by the border ‘deforming’... maybe you're talking about tearing? If so, I'm afraid there is nothing you can do about it.
The traditional solution to tearing is to wait for vsync to draw your next frame, but that ability is not available in JavaScript. No framework can fix it. (Framework fans: please stop suggesting “Use my_favourite_framework! It solves all problems!” to JavaScript questions you don't understand.)
As mck89 suggests, you can certainly make the animation smoother (which can reduce the impact of tearing too) by drawing more frames, at the expense of taking more CPU power to perform. You might also prefer to keep a variable to store your x value, rather than parsing it from the currentStyle every time. It would be simpler and more widely supported by browsers.
ETA re comment: There's not a concrete minimum timeout in JS (I can get it down to 1ms sometimes), but how many fps you can get out of an animation is highly dependent on the browser and the power of the machine, which is why generally it's a good idea to base position/frame on the amount of time that has elapsed since the start of the animation (using new Date().getTime()) rather than moving/changing a fixed amount each frame.
In any case, about the fastest you can practically go is using an interval of 16ms, which corresponds to one frame on a 60Hz monitor (the usual flatscreen default).
You should increment the left coordinate by 1 px and set a lower time for the interval.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style>
body { margin:0; padding:0; }
#a {
position:absolute;
background:#0FF;
left:0;
height:300px;
width:120px;
}
input, #a {
margin:10px;
}
</style>
<script>
function foo() {
box = document.getElementById('a');
var computedStyle = box.currentStyle || window.getComputedStyle(box, null);
box.style.left = parseInt(computedStyle.left) + 1 + 'px';
setTimeout("foo()",1);
}
</script>
</head>
<body>
<input type="button" value="RUN, FORREST, RUN!" onClick="setTimeout('foo()',20)">
<div id="a"></div>
</body>
</html>
JQuery and YUI and almost every other js library provides animation utility, perhaps you should look into those.
In my experience, mootools (http://mootools.net) provides the smoothest animation.
Do you know a good cross-browser way of knowing how wide will be a text line so you can break it exactly to fit a fixed width?
Suppose you want to break a long text like so it doesn't overflow a fixed width container, but you want the line to break the closest to the border possible, so guessing where to insert s isn't a clean solution.
I want to investigate, I imagine this could be done having an invisible div then printing the line inside it and checking the div's width, or something like that, with Javascript.
Has anyone done something like this?
*(the focus is not word wrapping, that's just the application that comes to my mind now, but knowing a text's width is what I want)
Here is a complete "Heath Robinson" (does that reference travel well?) approach.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script type="text/javascript">
function txtContent_onchange()
{
var span = document.getElementById("spanMeasure")
span.innerHTML = "";
span.appendChild(document.createTextNode(this.value));
document.getElementById("txtWidth").value = span.scrollWidth;
}
</script>
<style type="text/css">
#spanMeasure
{
position:absolute;
top:0px;
left:0px;
visibility:hidden;
width:10px;
white-space:nowrap;
overflow:hidden
}
</style>
</head>
<body>
<input id="txtContent" onchange="txtContent_onchange.call(this)" /><br />
<input id="txtWidth" />
<span id="spanMeasure"><span>
</body>
</html>
The critical thing here is the configuration of the span element. This element will not impact the visual appearance of the page. Its scrollWidth property will return the length of the text it contains. Of course you would need to set any font style attributes to get a reasonable value.
According to quirksmode site Opera may be a little flaky with this approach but I suspect its the closest you will get to a fully cross-browser solution.