Andrei Nagy Andrei Nagy - 6 months ago 19
iOS Question

Dinamically hide parts of html in webview

I'm working on a proof of concept feature to add the ability to hide part of a web page loaded in a webview, and I can't get it working...

I have something like this in a UIWebview extension, calling it when the webview finishes loading:

let dummyStyle = "var dummyStyle = document.createElement('style'); dummyStyle.innerHTML = 'div {display: none;}'; document.body.appendChild(dummyStyle); "

let classToHide = "content"
let jsHideString = "var e = document.body.getElementByClassName('\(classToHide)'); e.style = dummyStyle; e.style.display = 'none';"
self.stringByEvaluatingJavaScriptFromString(dummyStyle + jsHideString)


The main issue seems to be (checked with safari/chrome developer tools) that the document element doesn't have a style property. Even if I set it manually in the console, it doesn't update when e.style.display = 'none'.

Besides searching for the element id or class, I want to keep the assumptions about the end user web page to a minimum.

Thanks for reading my question!

Edit with working solution:

let classToHide = "content"
let jsHideString = " " +
" var e = document.body.getElementsByClassName(\"\(classToHide)\")[0];" +
"e.style.display = \"none\";"

let DOMContentLoadedNotification = " " +
"var addL = function addListener(obj, eventName, listener) { " +
"if (obj.addEventListener) { " +
"alert('added listener');" +
"obj.addEventListener(eventName, listener, false); " +
"} else { " +
"alert('attactch event');" +
"obj.attachEvent(\"on\" + eventName, listener); " +
"};" +
"};" +

"var completion = function finishedDCL() { " +
"alert('finishedDCL');" +
jsHideString +
"};" +

"if (document.readyState == \"complete\" || document.readyState == \"loaded\") { " +
"alert('document already loaded');" +
jsHideString +
"} else {" +
"alert('document not loaded');" +
"addL(document, \"DOMContentLoaded\", completion()); " +
"};"

print("Webview: \(self.stringByEvaluatingJavaScriptFromString(DOMContentLoadedNotification))")

Answer

Don't generate the stylesheet, just manipulate directly the .style property of the DOM node.

Set nodeReference.style.display = 'none'

The problem with no style property must be that you don't wait for the DOM to be ready. Watch for the DOMContentLoaded event.

https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded