I added English for my website so it will support 2 languages.
On the first language, I use css file where everything is RTL.
Now, when i switch to English, I remove the RTL css file and add a css file where dir is LTR.
On Chrome, IR and Firefox it works fine.
But on Safari (I tried only mobile safari) it partaily ignores the LTR.
You can see it here: http://parkplanner.co.il/ and use the 'English' button on the menu to change language.
This is the LTR css file - http://parkplanner.co.il/css/ltr-adj.css
Thanks!
use direction:ltr; not the dir attribute
This looks like well known issue.
Read the thread.
Force DOM redraw/refresh on Chrome/Mac
// in jquery $('#parentOfElementToBeRedrawn').hide().show(0);
// in plain js document.getElementById('parentOfElementToBeRedrawn').style.display = 'none'; document.getElementById('parentOfElementToBeRedrawn').style.display = 'block';
If this simple redraw doesn't work you can try this one. It inserts an empty text node into the element which guarantees a redraw.
var forceRedraw = function(element){
if (!element) { return; }
var n = document.createTextNode(' ');
var disp = element.style.display; // don't worry about previous display style
element.appendChild(n);
element.style.display = 'none';
setTimeout(function(){
element.style.display = disp;
n.parentNode.removeChild(n);
},20); // you can play with this timeout to make it as short as possible
}
Related
I am new to writing Firefox extension and want to append a div to a document, not to the body of webpage, in JavaScript in a Firefox extension. How can I do this?
var div = document.createElement("div");
div.id = "div1";
div.textContent = "Its my div";
var st = div.style;
st.display = "block";
st.top = "0px";
st.left = "0px";
st.width = "100%";
document.appendChild(div);
document.documentElement gives you the DOM element of the HTML tag.
document.documentElement.appendChild(div);
When using XUL-overlays (and XUL windows), please note that window and document do not refer to the web content, but the XUL window itself (the browser itself).
document.documentElement.localName == "window"; // not "html"
document.documentElement.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
You need to use content or gBrowser to interact with the websites loaded in a tab in a browser window (browser.xul in Firefox)
For example, to have your code create and add a <div> to the <html> of a the website in the selected tab (not that it makes sense, but it seems to be what the question is asking for)
var div = content.document.createElement("div"); // note the use of `content`
div.id = "div1";
div.textContent = "Its my div";
var st = div.style;
st.display = "block";
st.top = "0px";
st.left = "0px";
st.width = "100%";
content.document.documentElement.appendChild(div); // note the use of `content`
Of course, that example will only work when:
Executed after the browser window itself was full loaded
The currently active tab is actually an html document and loaded enough to have a usable DOM.
See e.g. the "Detecting page load" section and other documentation and examples on that page and related/linked pages.
On a somewhat related issue, please note that the Firefox code and all XUL overlays do share a common scope/namespace, and you therefore need to make sure that the global variables your code uses do not conflict or have the potential to conflict with other code. Usually you do this by prefixing/namespacing your stuff or using only an anonymous function to get a non-shared function scope.
var div = ...; // bad, might conflict with other code
(function() {
"use strict";
// strict mode, to make implicit variable declarations an error, among other thiings
var div = "..."; // OK, local to the anonymous function
...
})();
I am trying to access an element in my Edge Animate animation (which is a menu bar) from the parent document. The element has an onClick event which is triggered depending on the #bookmark in the URL of the parent web page. My code works perfectly in Firefox but does not work in Internet Explorer(10). IE is unable to see any elements within the 'Stage' div whereas Firefox can.
This is the JavaScript code on my parent page: -
<script language='javascript'>
var thisPage = window.location.pathname;
var fullurl = document.URL;
var xxx = fullurl.substring(fullurl.indexOf('#'));
var pageString = xxx.replace("#", "");
pageString = pageString.replace("http://www.mydomain.com/portfolio/photography.html", "");
if (pageString == "corporate") {
window.onload = function() {
var iframe = document.getElementById('U10511_animation');
var innerDoc = (iframe.contentDocument) ?
iframe.contentDocument : iframe.contentWindow.document;
var corporateRectangle = innerDoc.getElementById('Stage_Corporate_Rectangle');
corporateRectangle.click();
}
};
</script>
The above code will select the Corporate tab in the menu when viewed in Firefox but not IE when the URL has the suffix #corporate.
When I insert an 'alert' for the variable 'corporateRectangle' in Firefox it returns [HTMLObj] and in IE it returns 'null'.
Any ideas anyone? Thanks.
Have you tried checking the console for an error of some sort to help you and us understand the error?
IE JavaScript often works differently than in other browsers. And iframes are particularly problematical. One possibility is that you are getting the wrong document, such that the documentyou are retrieving either does not exist or does not contain the element you are looking for. So you just have to do some debugging. Here is how I would proceed. Run your script in IE.
1) Determine whether innerDoc is iframe.contentDocument or iframe.contentWindow.document. Make sure innerDoc is not null. If it is, try to get the document a different way.
2) Assuming innerDoc is not null, enumerate all of the elements in innerDoc. You can do that as follows:
for(i = 0; i < innerDoc.all.length; i++) alert(innerDoc.all [i].id);
Make sure that the id you are looking for is actually in the document. I suspect it isn't and that you need to get a different document object under IE.
I assume you are stuck with having to use iframes. If not, I suggest you use a different approach as iframes can be very problematical and browser-specific in how they work.
internet Explorer gets confused over name and id - it is highly recommended to treat these two attributes as if they were the same.
You can fix it either by 1) ensure that there are no id/name conflicts in your document, or 2)
override IE's native getElementById-method.
Read more about it here.
Ok... thanks to everyone who left suggestions.
The issue was that the menu animation has a preloader. Firefox ignores the preloader whereas IE treats the preloader as onLoad being complete. Therefore the attempt to access the element ID is null as it hasn't been loaded yet.
I decided to approach the problem from a different tack and read my bookmark from within the animation. This turned out to be a very simple solution once I figured out that I had to put the code in the first frame of the animation NOT in creationComplete or compositionReady.
This was the code: -
var bookmark = parent.window.location.hash;
bookmark = bookmark.replace("#", "");
if (bookmark == "corporate") {
sym.play("corp");
}
yes, as simple as that.
I'm trying to toggle text on click. When 'Pause' is clicked change the text to 'Play'.
For some reason the text is updating but not rendering correctly. It's as if that part of the DOM is being updated but not refreshed. For some reason this is only happening in the webkit browsers (Safari 5, Chrome 11). Firefox 4 is rendering it the way it should.
Here's a video of the problem: http://www.youtube.com/watch?v=tIRKx25NmYo
I'm using Cmd+A in the video to select the text, which appears to refresh the text and get it to display properly.
Here's the code:
<span class="playercontrols" id="playpause" onclick="toggle(this.id);" style="cursor:pointer;">Pause</span>
<script type="text/javascript">
function toggle(sender){
var t = document.getElementById(sender);
var txt = t.innerHTML;
switch(txt)
{
case 'Pause':
txt = 'Play';
pause();
break;
case 'Play':
txt = 'Pause';
play();
break;
default:
txt = 'Pause';
}
t.innerHTML = txt;
}
</script>
EDIT: I commented out every other piece of javascript referenced and written on the page and the problem is still there. I have no idea what's wrong but it doesn't appear to be a collision or conflict.
SOLVED IT. (Not allowed to mark this answered because it's too recent.)
Edit: Answer now added below.
Thanks for all the comments. Hopefully this post will help others in the future with the same problem.
It seems that flashing the text (setting visibility to hidden and then back to its original value) fixes the issue..
So here is the work around.
t.innerHTML = txt;
/* add the following right after changing the text */
var visibility = t.style.visibility;
t.style.visibility = 'hidden';
setTimeout( function(){
t.style.visibility = visibility;
}, 1);
demo http://jsfiddle.net/gaby/SgwsZ/4/
The problem was with the styling on the "playercontrols" class.
.playercontrols {
position: relative;
top: 80px;
left: 50px;
}
I had it set to position relative which apparently sent webkit's update rendering out of whack.
Here is the situation. I have some javascript that looks like this:
function onSubmit() {
doSomeStuff();
someSpan.style.display="block";
otherSpan.style.display="none";
return doLongRunningOperation;
}
When I make this a form submit action, and run it from a non IE browser, it quickly swaps the two spans visibility and run the long javascript operation. If I do this in IE it does not do the swap until after onSubmit() completely returns.
I can force a dom redraw by sticking an alert box in like so:
function onSubmit() {
doSomeStuff();
someSpan.style.display="block";
otherSpan.style.display="none";
alert("refresh forced");
return doLongRunningOperation;
}
Also, the obvious jquery refactoring does not affect the IE behavior:
function onSubmit() {
doSomeStuff();
$("#someSpan").show();
$("#otherSpan").hide();
return doLongRunningOperation;
}
This behavior exists on IE8 and IE6. Is there anyway to force a redraw of the DOM in these browsers?
Mozilla (maybe IE as well) will cache/delay executing changes to the DOM which affect display, so that it can calculate all the changes at once instead of repeatedly after each and every statement.
To force an update (to force an immediate, synchronous reflow or relayout), your javascript should read a property that's affected by the change, e.g. the location of someSpan and otherSpan.
(This Mozilla implementation detail is mentioned in the video Faster HTML and CSS: Layout Engine Internals for Web Developers.)
To continue what ChrisW says:
here's flushing script to flash DOM, so you don't have to call alert(""); (found at http://amolnw.wordpress.com/category/programming/javascript/):
function flushThis(id){
var msie = 'Microsoft Internet Explorer';
var tmp = 0;
var elementOnShow = document.getElementById(id);
if (navigator.appName == msie){
tmp = elementOnShow.parentNode.offsetTop + 'px';
}else{
tmp = elementOnShow.offsetTop;
}
}
It works for me!!!
Thanks for the tip.
I had this problem in Chrome 21 dragging a word that had a letter with a descender ('g'). It was leaving a trail of moth dust behind on the screen, which would vanish the next time something made the screen refresh. ChrisW's solution (interrogating a layout-sensitive property) didn't work.
What did work was to add a 1-pixel blank div at the top of the page, then remove it a millisecond later, by calling the following the function at the end of the drag operation:
// Needed by Chrome, as of Release 21. Triggers a screen refresh, removing drag garbage.
function cleanDisplay() {
var c = document.createElement('div');
c.innerHTML = 'x';
c.style.visibility = 'hidden';
c.style.height = '1px';
document.body.insertBefore(c, document.body.firstChild);
window.setTimeout(function() {document.body.removeChild(c)}, 1);
}
Note: You need the delay. Simply adding and removing the div doesn't work. Also, the div needs to be added above the part of the page that needs to be redrawn.
You can also wrap you longterm function in a setTimeout(function(){longTerm();},1);
Can your longRunningOperation be called asynchronously?
element.focus() works for me in IE10
function displayOnOff(){
var elm = document.getElementById("myDiv");
elm.style.display="block";
elm.focus();
for(var i=0; i<1000000; i++){
console.log("waiting...............");
}
elm.style.display = "none";
}
I am using the openwysiwyg editor in my webpage. I want to clear the contents of it. I have used
$('#report').val('');
but that doesn't clear it.
The editor creates an iframe and updates the contents there, syncing as it goes.
How would I go about clearing it?
You probably need to supply a bit more information - the html itself would be very useful, but I'm going to assume that report is the id of the textarea you need cleared.
If it's a normal textarea, your code should really work.
If (as Paulo mentions in the comments) it's being modified by an openwysiwyg editor, it's probably being turned into an iFrame with it's own HTML page in it. It's a lot more difficult to manipulate the iFrame.
Looks like that's the case.
Have a look at this example to see if it helps you reference the iFrame itself: http://www.bennadel.com/index.cfm?dax=blog:1592.view
This is a hacked excerpt of the example.html that comes with openwysiwyg:
<script type="text/javascript">
// Use it to attach the editor to all textareas with full featured setup
//WYSIWYG.attach('all', full);
// Use it to attach the editor directly to a defined textarea
WYSIWYG.attach('textarea1'); // default setup
WYSIWYG.attach('textarea2', full); // full featured setup
WYSIWYG.attach('textarea3', small); // small setup
// Use it to display an iframes instead of a textareas
//WYSIWYG.display('all', full);
function getIFrameDocument( id )
{
var iframe = document.getElementById(id);
if (iframe.contentDocument) {
// For NS6
return iframe.contentDocument;
} else if (iframe.contentWindow) {
// For IE5.5 and IE6
return iframe.contentWindow.document;
} else if (iframe.document) {
// For IE5
return iframe.document;
} else {
return null;
}
}
function clearcontents()
{
getIFrameDocument('wysiwygtextarea1').body.innerHTML = '';
}
</script>
Then somewhere in the page, I've got a clear button (actually div):
<div style="width:120px;height:20px;background:#ff0000;text-align:center;display:block;" onclick="clearcontents();">Clear!</div>
Note that the id of your textarea is prefixed with wysiwyg. That's the name of the iFrame.
I've tested this in Firefox but nothing else at the moment. The code for getting the iFrame I found on the Net somewhere, so hopefully it works for other browsers :)
This works, but is butt ugly:
var frame = WYSIWYG.getEditor('--ENTER EDITOR NAME HERE--');
var doc = frame.contentWindow.document;
var $body = $('html',doc);
$body.html('');
Replace --ENTER EDITOR NAME HERE-- by whatever you pass to the editor when you call attach.
I believe this works
$('#report').text('');