jQuery appendTo gives invalid argument in IE
I am trying to create an interface to the swfobject found at http://code.google.com/p/swfobject/. I am building the needed alternate content for when the user does not have flash player installed. This is working fine in FF, but not in IE for some reason. I have done this the same way a million times before and it has always worked, I can not figure out why I am getting this error this time.
Basically, when the pag开发者_如何转开发e loads, it calls a function $.SWFObject.embedSWF() which builds the alternate content, and calls the swfobject.embedSWF function. The alternate content is built with a ready function like the following.
When the setupAlternateContent function is called the error occurs at the ('#' + containerID).
embedSWF: function(flashFilename, containerID, width, height, minFlashVersion, flashvars, params, attributes) {
//If the flashvars, params, or attributes variables were passed in and are objects, then save them, otherwise they will be empty.
settings.flashvars = (flashvars && typeof(flashvars) == 'object') ? flashvars : {};
settings.params = (params && typeof(params) == 'object') ? params : {};
settings.attributes = (attributes && typeof(attributes) == 'object') ? attributes : {};
//Setup the alternate content that will be used if the user does not have flash installed
$(document).ready(function() { setupAlternateContent(containerID); });
//Call the embedSWF function which is found in the swfobject core file
swfobject.embedSWF(flashFilename, containerID, width, height, minFlashVersion, flashUpdater, settings.flashvars, settings.params, settings.attributes);
}
function setupAlternateContent(containerID) {
//Create the innerContainer div element
var innerContainer = $.create('div', {
}).appendTo('#' + containerID).css({
font: '18px Arial, Verdana, sans-serif',
height: '130px',
width: '240px',
paddingTop: '35px',
margin: '0px auto'
});
//Put the flash image inside the innerContainer
$.create('img', {
src: SWFOBJECT_FOLDER_LOCATION + 'flash_icon.png',
alt: 'Install Flash'
}).appendTo(innerContainer).css({cursor: 'pointer'}).click(function() { window.location = 'http://get.adobe.com/flashplayer'; });
//Add a message bellow the flash icon
$.create('p', {}, 'Install Adobe Flash Player').appendTo(innerContainer);
}
IE does not like the ('#' + containerID) argument which does not make any sense because i have done this before without problems. Also, I am using jQuery DOMEC extension which is where the $.create comes from.
Any help is appreciated. Thanks!
Metropolis
You may want to rethink your approach. If you need to display JS-generated alternate content when Flash Player is not available, I suggest doing a swfobject.hasFlashPlayerVersion("9")
check before attempting to create the alt content. This check can be performed before the DOM loads.
Note that swfobject.embedSWF is wrapped in its own domready-style event, and therefore doesn't need to be wrapped in jQuery's $(document).ready event.
Simple example:
var hasFlash = swfobject.hasFlashPlayerVersion("9");
if(hasFlash){
swfobject.embedSWF( ... );
} else {
//Create alt content right away (no need to wait for dom to load)
var altcontent = setupAlternateContent();
//When DOM is ready, append alt content to page
$(document).ready(function () { altcontent.appendTo("mycontainer") });
}
This approach speeds things up (no sitting around waiting for DOM to load just to figure out what needs to be done), and also prevents the alt content from being generated if it isn't needed.
Following this logic, I'd refactor your code to something like this (please forgive any typos):
embedSWF: function(flashFilename, containerID, width, height, minFlashVersion, flashvars, params, attributes) {
if(swfobject.hasFlashPlayerVersion(minFlashVersion)){
//If the flashvars, params, or attributes variables were passed in and are objects, then save them, otherwise they will be empty.
settings.flashvars = (flashvars && typeof(flashvars) == 'object') ? flashvars : {};
settings.params = (params && typeof(params) == 'object') ? params : {};
settings.attributes = (attributes && typeof(attributes) == 'object') ? attributes : {};
//Call the embedSWF function which is found in the swfobject core file
swfobject.embedSWF(flashFilename, containerID, width, height, minFlashVersion, flashUpdater, settings.flashvars, settings.params, settings.attributes);
} else {
//Create alt content right away (no need to wait for dom to load)
var altcontent = setupAlternateContent();
//When DOM is ready, append alt content to page
$(document).ready(function() { altContent.appendTo(containerID); });
}
function setupAlternateContent(containerID) {
//Create the innerContainer div element
var innerContainer = $.create('div').css({
font: '18px Arial, Verdana, sans-serif',
height: '130px',
width: '240px',
paddingTop: '35px',
margin: '0px auto'
});
//Put the flash image inside the innerContainer
$.create('img', {
src: SWFOBJECT_FOLDER_LOCATION + 'flash_icon.png',
alt: 'Install Flash'
}).appendTo(innerContainer).css({cursor: 'pointer'}).click(function() { window.location = 'http://get.adobe.com/flashplayer'; });
//Add a message bellow the flash icon
$.create('p', {}, 'Install Adobe Flash Player').appendTo(innerContainer);
return innerContainer;
}
I have got the same error only in IE, not in any other browser. I replaced .html() with .replaceWith() and it worked. When using .replaceWith, it replaces the whole DIV. So in the content you are replacing with, add the div once again, so you will not loose it.
example: if you are trying to do something like this.
$(#testDIV).replaceWith(testData);
then make sure 'testData' is of this format.
<div id='testDiv'>
This is new content.
</div>
This way, even if you use replaceWith, you will not loose you DIV.
It looks like in your document ready handler you are calling setupAlternateContent with a variable called containerID
- is this variable ever defined anywhere? If not then inside the function you will be doing appendTo('#')
which I wouldn't be surprised at if it caused an error. What is the id of the container and where is it set before the document ready fires?
You could try an alert(containerId)
inside setupAlternateContent
to see that you are passing what you think you are to the function...
(Editing after new information added)
I don't know that the $.create method does but if you could try using jQuerys built in DOM creation: var innerContainer = $('<div />').appendTo(....
Or:
var innerContainer = $('<div />').css({
font: '18px Arial, Verdana, sans-serif',
height: '130px',
width: '240px',
paddingTop: '35px',
margin: '0px auto'
});
$('#' + containerID).append(innerContainer);
Or even all at once:
$('#' + containerID).append(
$('<div />').css({
font: '18px Arial, Verdana, sans-serif',
height: '130px',
width: '240px',
paddingTop: '35px',
margin: '0px auto'
}),
$('<img />').attr({
src: SWFOBJECT_FOLDER_LOCATION + 'flash_icon.png',
alt: 'Install Flash'
}).css({
cursor: 'pointer'
}).click(
function() {
window.location = 'http://get.adobe.com/flashplayer';
}
)
);
精彩评论