Hide div inside (e.g. Twitter) shadow-dom with JavaScript - javascript

Using TamperMonkey to streamline page view on my side, and wish to hide part of the externally-sourced Twitter card(s) from printing. The image in the EmbeddedTweet does not print anyway, and leaves a large empty rectangle that wastes valuable space.
The DOM looks like the image below - how would I target the DIV with class SummaryCard-image (green arrow)? It doesn't matter to me if the DIV is removed from the DOM, or just hidden with CSS.
I have tried the below methods, which do not work:
(1) Injecting CSS with .SummaryCard-image{display:none !important;}
(2) jQuery: $('.SummaryCard-image').remove();
$('.SummaryCard-image').length returns 0
(Note the #shadow-root (open), 2nd element from the top)

You need to select the shadow root first inorder to traverse to that element. You need something like this
var twitterWidget= document.querySelector('twitterwidget').shadowRoot;
twitterWidget.querySelector('.SummaryCard-image').style.display = "none";
For multiple twitter widgets
var twitterWidgets = document.querySelectorAll('twitterwidget');
twitterWidgets.forEach(function(item){
var root = item.shadowRoot; root.querySelector('.SummaryCard-image').style.display = 'none';
})
Example
https://rawgit.com/ebidel/2d2bb0cdec3f2a16cf519dbaa791ce1b/raw/fancy-tabs-demo.html
var tabs= document.querySelector('fancy-tabs').shadowRoot
tabs.querySelector('#tabs').style.display = none

Related

Items inside flexbox not interactable

I have an interactive map generated using svg paths. Whenever I click a path, a container should appear containing some infos and links regarding that area.
The problem I have encountered is that nothing inside this container can be interacted with (ie. click links).
Items inside the container are generated using JS from a JSON file.
JSON reading works, although not over codepen, i dont know why (doesnt matter). You can see the code live here.
Here's my code: https://codepen.io/yasinibraim/pen/YzVVBMm
Short summary of the code:
SVG map inside svgContainer div
responsive info container inside containerInfo div
items inside containerInfo div generated inside clickUAT JS function. JSON fetched inside loadJSON function.
This is how i generate the content of containerInfo:
for (let i in actual_JSON){
if(actual_JSON[i].uat == caller){
if(firstItem == 1){
//newElement = document.createElement("ul");
}
header = document.createElement("p");
newElement = document.createTextNode (actual_JSON[i].title);
header.appendChild(newElement);
newElement = document.createElement ("a");
newElement.setAttribute('href',actual_JSON[i].link);
newElement.innerHTML = "Citește";
header.appendChild(newElement);
container.appendChild(header);
}
console.log(actual_JSON[i].Title);
}
Do you mean the links inside <div id="containerInfo" class="fadeIn"> when you click on a region?
This is because you have pointer-events: none; on the container, which will affect the children as well.
You either need to add pointer events to <a> element, or add pointer events back to #containerInfo when it becomes visible.

Hide Element when hover Element Javascript

I have a DIV that needs to be displayed/hide whenever i hover a menu item.
Here it is my website: Website
The Blug light section should be displayed only when I hover the Photo Booths menu on the header.
I have tried the following code on JSFiddle which it works but when i use it on my site it doesn't work
<script>
let test = document.getElementByClassName(".menu-item.menu-item-7912");
test.addEventListener("mouseover", function( event ) {
document.getElementById('test2').style.display = 'none';
});
test.addEventListener("mouseleave", function( event ) {
document.getElementById('mega-menu-customized').style.display = 'block';
});
</script>
I have tried using getElementByClassName but without success. Any ideas of how to make it work?
Are you getting DOM node in test variable, one problem I can see in your code is:
let test = document.getElementsByClassName(".menu-item.menu-item-7912");
Should be:
let test = document.getElementsByClassName("menu-item, menu-item-7912");
We do not use dot before class name and multiple classes can be separated by comma like:
let test = document.getElementsByClassName("class1, class2, class3");
Your issue is in the header element. On scroll, the style property of the document header is changing. Look:
sorry for the bad quality, upload size is maxed at 2MB
Without getting into too much detail, one thing that I see is that the height of the header is being reduced to only contain the main header. When the larger blue subheader is visible, part of that is because the style.height of the header is made to be much larger. Additionally, the first child of the header is a div with id 7905, and that seems to be what you need to target to modify the opacity of the larger blue header. You need to target that div:
const blueBannerContainer = document.getElementById('7905')
But your event handlers will also need to account for the height of the header element. display: block won't really help you here.

jQuery: inserting text into container div on hover

I'm using a simple jQuery image slider (Owl Carousel) to show a list of speakers at a convention with photos, and I'm trying to find a way to overlay text associated with each speaker onto a div placed above the slider. I have a mockup page here. As you can see on the mockup, I have two primary divs-- i.e. div#sit and div#carousel-sit; within the former I have an container with the class .sit-quote-container into which I'd like the quote text/markup injected. I would like this overlay text to pull from the paragraph elements with the .sit-quote class that exist for each speaker.
In addition to the problem of displaying the appropriate text within the container div, I'm seeing that placing the .sit-quote paragraph within each slide is causing a gap to appear under the speaker name (the grey box underneath) and I have no idea why this is happening given that I've set .sit-quote to display:none. I'm wondering if perhaps I need to move the elements containing the quotations out of the slider markup altogether (?)
As for the actual hover function, this is what I have so far, with the help of another SO user; but it doesn't seem to be working:
$(".slide-sit").hover(function() {
var clone = $(this).find(".sit-quote").clone();
clone.appendTo(".sit-quote-container");
}, function(){
$(".sit-quote-container").html(""); // this clears the content on mouseout
});
Ultimately, I'd like the quotes to fade in/out positioned within the main div. Thanks for any assistance, and please let me know if I need to provide further clarification as to the aim here.
you should first visible that quote
try this:
$(".slide-sit").hover(function() {
var clone = $(this).find(".sit-quote").clone();
clone.appendTo(".sit-quote-container").show(); // Here you should show the quote
}, function(){
$(".sit-quote-container").html("");
});
if you want to fade in:
$(".slide-sit").hover(function() {
var clone = $(this).find(".sit-quote").clone();
clone.appendTo(".sit-quote-container").fadeIn(); //Here if you want to fade the quote
}, function(){
$(".sit-quote-container").html("");
});
Use the below script to pull the text from .sit-quote p tag of the hovered item and display it in the .sit-quote-container
UPDATE
If needed wrap the quote in a para tag and to avoid complexity use a different class name, in this case .sit-quote_inner.
CSS : .sit-quote_inner{ display:none; }
JS
$('.sit-carousel-container .owl-item').hover(function(){
var quote = $(this).find('.sit-quote').text(); //Only text not the p tag
quote = '<p class="sit-quote_inner">' + quote + '</p>';
$('.sit-header .sit-quote-container').html(quote);
$('.sit-quote_inner').fadeIn(); //Add this
},function(){
$('.sit-header .sit-quote-container').html('');
});
The carousel seems to be dynamically injecting clones of the slides. In this case, you might want to delegate your event handler so that it works with the dynamically generated slides.
Also, if you want to fadeOut the text, you should remove it in the complete callback of fafeOut instead of simply emptying the html Try
$(document).on("mouseenter",".slide-sit",function() {
var clone = $(this).find(".sit-quote").clone();
clone.appendTo(".sit-quote-container").fadeIn("slow");
});
$(document).on("mouseleave",".slide-sit", function(){
$(".sit-quote-container")
.find(".sit-quote")
.fadeOut("slow",function(){ // Fadeout and then remove the text
$(this).remove();
})
});
The gap (grey background) is the background of .slide-sit, which is visible due to the margin-bottom: 15px; applied on the paragraph containing name (style rule .item p main.css line 67 it seems), removing this will fix the issue.
Update
It'd be better if you keep a .slide-sit inside the .sit-quote-container so that you can fade it in/out properly using the below script.
$(document).on("mouseenter",".sit-carousel-container .slide-sit",function() {
var content = $(this).find(".sit-quote").html();
(".sit-quote-container .sit-quote").html(content).fadeIn("slow");
});
$(document).on("mouseleave",".sit-carousel-container .slide-sit", function(){
$(".sit-quote-container").find(".sit-quote").fadeOut("slow")
});

How can I change css for every DOM object in the page in SAPUI5

I have a things inspector and this things inspector has two titles. I wan to be able to change the css on this titles and make their font size a bit smaller( default fontSize is 16px and I want to drop it to 12px). I tried to get these titles class and use this method to change their size:
var element = document
.getElementsByClassName("sapUiUx3TVTitleSecond")[1];
element.style.fontSize = '12px';
var element = document
.getElementsByClassName("sapUiUx3TVTitleFirst")[1];
element.style.fontSize = '12px';
it does work and I can see the change but as soon as the page finishes loading ( page loading takes couple of second because it needs to read a json object) title sizes go back to its default.
I dont even know this is a right way to access DOM elements and change their CSS.
Please point me to the right direction of how to change DOM object css in SAPUI5 in general
You could create a new CSS file which you include in your index.html.
Just add the needed selectors with the modified attributes in this custom CSS:
.sapUiUx3TVTitleSecond, .sapUiUx3TVTitleFirst {
font-size : 12px;
}
Edit: if you need to change it programmatically, you could use the addStyleClass("yourStyle") method which is available to every UI element
Execute the script after dom gets completely loaded. Try like this
$("document").ready(function()
{
var element = document
.getElementsByClassName("sapUiUx3TVTitleSecond")[1];
element.style.fontSize = '12px';
var element = document
.getElementsByClassName("sapUiUx3TVTitleFirst")[1];
element.style.fontSize = '12px';
})
$("document").ready(function()
{
$(".sapUiUx3TVTitleSecond").css("font-size","12px");
})

Wrapping a jquery validate span.error with nested divs

Heyo. This is my first stack overflow post because I am stumped and not finding many people who are trying to accomplish the same thing. I've tried using jquery .before(), .after(), and .wrap() to resolve this. I was initially using css :before and :after pseudo-elements, but as that won't work for legacy browsers, I've decided to use jquery.
I already have several forms on several pages with validation working. The error messages vary in length. We were using a static, one size background image on the default span element, so content was bleeding out on longer error messages. I built a flexible rounded corner series of nested divs to allow the error box to grow or shrink dynamically. The html I want to output is:
<div class="errorWrap">
<div class="errorTop"><span></span></div>
<div class="errorContent">
<span class="error">This is an error</span>
</div>
<div class="errorBottom"><span></span></div>
</div>
Here's an example of a solution I tried, but I'm still pretty new to javascript.
$('.error').before('<div class="errorWrap"><div class="errorTop"><span></span></div><div class="errorContent">');
$('.error').after('</div><div class="errorBottom"><span></span></div></div>');
Correct me if I'm wrong, but I think that I have the right idea with the jquery. But it's just kind of sitting there, not in any function being called. So I imagine that since the code isn't re-executing, it just doesn't show up. Is there an appropriate function to wrap this in? I'm certain I'm just not attacking this from the right direction. Any help is super appreciated.
the plugins "before" and "after" dont take html as string. you cannot start a div in one and close it in an other.
Either you take your current html and generate a new html string which you append where you want to or you use the "wrap" plugin http://api.jquery.com/wrap/
Using pure HTML
$(".error").html("<div class='beforeContent'>" + $(".error").html() + "</div>");
Using wrap (http://api.jquery.com/wrap/)
$(".error").wrap("<div class='beforeAndAfter'></div>");
If you want to show an error div after focus out of an input then you have to create it using html/wrap as Luke said and then you have to append it in ot the dom useing
$('.errorWrap').insertAfter('.focusedElement');
But there are other methods available to insert a new element like append/appendTo e.t.c,
I ended up fixing this problem on my own using jquery to create the div and it's nesting on pageload, the divs are generated with an error class that gives display:none. A custom errorPlacement function nests the error in the correct div. Then I used a custom validator highlight function to remove the class that hides the element. Then I used the unhighlight function to re-add the class to re-hide the div.
$(function() {
//Generate the elements and assign attributes
var errorWrap = document.createElement('div');
$(errorWrap).addClass('errorWrap hideError');
var errorTop = document.createElement('div');
$(errorTop).addClass('errorTop');
var topSpan = document.createElement('span');
var errorContent = document.createElement('div');
$(errorContent).addClass('errorContent');
var errorBottom = document.createElement('div');
$(errorBottom).addClass('errorBottom');
var bottomSpan = document.createElement('span');
//Place the elements directly after each dd element
$("dl > dd").append(errorWrap);
$("div.errorWrap").append(errorTop)
.append(errorContent)
.append(errorBottom);
$("div.errorTop").append(topSpan);
$("div.errorBottom").append(bottomSpan);
//Add custom validator defaults
$.validator.setDefaults({
errorPlacement: function(error, element) {
$(element).nextAll('.errorWrap').children('.errorContent').append(error);
},
highlight: function(element) {
$(element).nextAll('.errorWrap').removeClass('hideError');
},
unhighlight: function(element) {
$(element).nextAll('.errorWrap').addClass('hideError');
}
});
}
Although I'm sure this could have been done more shorthand, I really like this technique because I didn't have to update any of my pages that contained forms to get it to work. All of the nested divs are dynamically created by javascript, so I can include a global file to any page with forms and it will just work. Thanks for all who offered suggestions.

Categories

Resources