简体   繁体   中英

Applying CSS to items outside of an iFrame (or other element)

I'm trying to inject some css to the body of my SharePoint webpage for a background image. The .js is essentially this:

document.getElementsByTagName( "Body" )[ 0 ].style.backgroundImage = <My Image URL>
document.getElementsByTagName( "Body" )[ 0 ].style.backgroundSize = "50%"
document.getElementsByTagName( "Body" )[ 0 ].style.backgroundPosition = "50% 50%"

And it works as I expect, unless there's an iFrame in the middle (or any other 'body' tag). Then the image gets put inside the iFrame as well as the body of my page. These iFrames are essentially popups that come up whenever you need to upload documents, change some settings on the site, etc. They're not up all the time but I don't want the image there, regardless.

When I call document.getElementsByTagName('Body') I always get the Body tag of whatever iFrame is currently up, or I'll get the document's main body. But it's always an HtmlCollection array of 1 item. Same thing happens if I use document.body

All of the body tags have the same generic setup ( <body class="ms-backgroundImage" style="..." spellcheck="false"> ) regardless of if they're the site's actual Body tag or if it's the iFrame's body.

Is there a way with Javascript to say "Apply to the main body, but not to any others"?

Your description contradicts the documentation (see https://developer.mozilla.org/en-US/docs/Web/API/Document/body ). Are you really sure it behaves as you described? Your described behavior is nothing I have ever experienced as a developer. Can you check again and maybe updates this question?

First, the reason you're getting an HtmlCollection when calling getElementsByTagName is because that function returns an array regardless of whether it matches zero, one or many items (observe the plural "s" in "Elements").

The different JS web api "get"-functions are pretty self explanatory that way, in that
getElementById (no plural s) returns a single DOM-node, whereas getElementsBy[Name|ClassName|TagName] all return an array of nodes.

Now to your main question:
By iFrames I take it you mean modal dialogs?
Modal dialogs in SharePoint have one thing in common, which is that they all have the url parameter "&IsDlg=1". This means you can check whether you're in a dialog or not, and have your code act accordingly.

Here's the code you're looking for, which will apply your style to all non-modal pages.

// could have used GetUrlKeyValue("IsDlg") === "1",
// but not sure if sp.js is loaded, so this is safer
var isDialog = document.location.search.indexOf("IsDlg=1") > -1;
// for non-dialog pages
if(!isDialog) {
    var docBody = document.body;
    // if for some crazy reason document.body returns an array??
    if(document.body.length) { docBody = document.body[0] }
    // styling
    docBody.style.backgroundImage = "[Your Image URL]";
    docBody.style.backgroundSize = "50%";
    docBody.style.backgroundPosition = "50% 50%";
}

PS: Customizing the master page is not reccomended practice in newer (>2007) versions of SharePoint. There are several other methods ( CustomActions , for instance) of customizing the platform without touching the out-of-the box master page, which you should familiarize yourself with if you want to work professionally with sharepoint.

To make the change I was trying to do, I just had to add an image to the "Look and Feel" of the page via Site Settings -> Look and Feel. Quick and easy, doesn't require any code... Thankfully.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM