I am retrieving the links in YT via JavaScript like this:
function GetTheLinks()
{
var linksArray = [];
for(var i = 0; i < document.links.length; i++)
{
var link = document.links[i];
linksArray.push( link.innerHTML );
linksArray.push( link.innerText );
linksArray.push( link.href );
}
return linksArray;
}
Since some time, I am now retrieving links that have the innerText e. g. "Just playing 0:27".
However, I do not see these links in the YT page.
So I wonder what they are and how to filter them out.
I have added such a link below to show what I mean.
Thank you!
link.innerText:
20:05
Läuft gerade (<-- German for "Just Playing")
link.href:
https://www.youtube.com/watch?v=k_2cSmg2ha4
link.innerHtml:
<yt-image alt="" ftl-eligible="" notify-on-loaded="" notify-on-unloaded="" class="style-scope ytd-thumbnail" disable-upgrade="" hidden="">
</yt-image>
<yt-img-shadow ftl-eligible="" class="style-scope ytd-thumbnail no-transition empty" style="background-color: transparent;"><!--css-build:shady--><img id="img" class="style-scope yt-img-shadow" alt="" width="9999"></yt-img-shadow>
<div id="overlays" class="style-scope ytd-thumbnail"><ytd-thumbnail-overlay-time-status-renderer class="style-scope ytd-thumbnail" overlay-style="DEFAULT"><!--css-build:shady--><yt-icon class="style-scope ytd-thumbnail-overlay-time-status-renderer" disable-upgrade="" hidden=""></yt-icon><span id="text" class="style-scope ytd-thumbnail-overlay-time-status-renderer" aria-label="20 Minuten, 5 Sekunden">
20:05
</span></ytd-thumbnail-overlay-time-status-renderer><ytd-thumbnail-overlay-now-playing-renderer class="style-scope ytd-thumbnail"><!--css-build:shady--><span id="overlay-text" class="style-scope ytd-thumbnail-overlay-now-playing-renderer">Läuft gerade</span>
<ytd-thumbnail-overlay-equalizer class="style-scope ytd-thumbnail-overlay-now-playing-renderer"><!--css-build:shady--><svg xmlns="http://www.w3.org/2000/svg" id="equalizer" viewBox="0 0 55 95" class="style-scope ytd-thumbnail-overlay-equalizer">
<g class="style-scope ytd-thumbnail-overlay-equalizer">
<rect class="bar style-scope ytd-thumbnail-overlay-equalizer" x="0"></rect>
<rect class="bar style-scope ytd-thumbnail-overlay-equalizer" x="20"></rect>
<rect class="bar style-scope ytd-thumbnail-overlay-equalizer" x="40"></rect>
</g>
</svg>
</ytd-thumbnail-overlay-equalizer>
</ytd-thumbnail-overlay-now-playing-renderer></div>
<div id="mouseover-overlay" class="style-scope ytd-thumbnail"></div>
<div id="hover-overlays" class="style-scope ytd-thumbnail"></div>
Related
I'm trying to create variable from a class inside the innerHTML down here:
ruleData.forEach((rule) => {
rulesWrapper.innerHTML += `
<div class='rule'>
<div id='rule-title' class='rule-title' onclick='showRuleDetail(${counter})'>
<div>
<p>${counter}.</p>
<p>${rule.title}</p>
</div>
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.5 5.5L7.5 10.5L12.5 15.5" stroke="#1E1E20" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class='rule-body'>
<p>${rule.body}</p>
</div>
</div>
`;
counter++;
});
For example I want to target rule-body class inside this innerHTML and change it's background
like this:
let ruleBody = document.querySelectorAll('.rule-body');
ruleBody[0].style.background = 'red';
But this doesn't work
,I get this error:
TypeError: Cannot read properties of undefined (reading 'style')
You can use DOMParser for this
ruleData.forEach((rule) => {
let rule_html = `
<div class='rule'>
<div id='rule-title' class='rule-title' onclick='showRuleDetail(${counter})'>
<div>
<p>${counter}.</p>
<p>${rule.title}</p>
</div>
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.5 5.5L7.5 10.5L12.5 15.5" stroke="#1E1E20" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class='rule-body'>
<p>${rule.body}</p>
</div>
</div>
`;
let rule = new DOMParser().parseFromString(rule_html,"text/xml").firstChild;
rule.querySelector('.rule-body').style.background = 'red';
rulesWrapper.appendChild(rule);
counter++;
});
Also if the counter is the index of the ruleData you can use forEach's index as well. (rule,i)=>{
You must access the .rule-body after the innerHTML and make sure it is indeed in the DOM. Then, this should work perfectly fine:
const container = document.querySelector("#container");
const button = document.querySelector("#button");
function exec() {
container.innerHTML = `<div class='rule-body'>yo</div>`;
const ruleBody = document.querySelectorAll('.rule-body');
ruleBody[0].style.backgroundColor = 'red';
}
button.onclick = exec;
<div id="container">
</div>
<button id="button">
CLICK TO INSERT
</button>
I suggest to map and delegate
const ruleData = [{"title":"Title 1","body":"This is the body"},{"title":"Title 2","body":"This is the body"}]
const rulesWrapper = document.getElementById("rulesWrapper");
rulesWrapper.innerHTML = ruleData.map((rule,i) => `
<div class='rule'>
<div class='rule-title' data-idx='${i}'>
<div>
<p>${i}.</p>
<p>${rule.title}</p>
</div>
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.5 5.5L7.5 10.5L12.5 15.5" stroke="#1E1E20" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class='rule-body'>
<p>${rule.body}</p>
</div>
</div>
`).join("");
rulesWrapper.addEventListener("click", function(e) {
const tgt=e.target.closest(".rule-title");
if (tgt) console.log(tgt.dataset.idx)
})
<div id="rulesWrapper"></div>
I am writing an update to my personal website where I remove duplicate html code. I am running into an error when I try to dynamically set the path to the href element.
Error: "ERROR TypeError: Cannot set property href of [object SVGImageElement] which has only a getter"
All other {{var}} instances work as expected
code that throws error:
<div class="row featurette" *ngFor="let row of json" >
<div class="col-md-7 {{row.textSpacing}}">
<h2 class="featurette-heading">{{row.title}}</h2>
<p class="lead">{{row.subTitle}}</p>
</div>
<div class="col-md-5 {{row.photoSpacing}}">
<svg class="bd-placeholder-img bd-placeholder-img-lg featurette-image img-fluid mx-auto" width="500" height="500" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" >
<image href={{row.src}} height="100%" width="100%"/>
</svg>
</div>
</div>
working code:
<div class="row featurette" *ngFor="let row of json" >
<div class="col-md-7 {{row.textSpacing}}">
<h2 class="featurette-heading">{{row.title}}</h2>
<p class="lead">{{row.subTitle}}</p>
</div>
<div class="col-md-5 {{row.photoSpacing}}">
<svg class="bd-placeholder-img bd-placeholder-img-lg featurette-image img-fluid mx-auto" width="500" height="500" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" >
<image href="/assets/images/hiking.JPG" height="100%" width="100%"/>
</svg>
</div>
</div>
Data Structure:
json = [
{
src: "/assets/images/hiking.JPG",
textSpacing:"",
photoSpacing:"",
title:"Hiking",
subTitle:"I love exploring with friends. The ability to be in untouched protected nature is something I value deeply. Most recent trip: Yosemite and Sequoia national parks. Hiker Pro Tip: Drop a GPS pin on your phone at the trailhead"
},
{
src: "/assets/images/Skiing.png",
textSpacing:"order-md-2",
photoSpacing:"order-md-1",
title:"Skiing",
subTitle:"I recently picked up skiing as an adult. This past winter I was able to go to Colorado to Ski in the mountains. Amazing!"
}
]
I believe you would need to do the [attr.href] for this to work. Example shown below.
<image [attr.href]="row.src" height="100%" width="100%"/>
or
<image attr.href={{row.src}} height="100%" width="100%"/>
You need quotes around your value {{row.src}}
<image href="{{row.src}}" height="100%" width="100%"/>
Let's say I have the following html context, which I don't have access to its creation :
<div id="outer">
<div id="chart-div">
<svg id="chart"></svg>
</div>
<div id="legend-div">
<svg id="legend"></svg>
</div>
</div>
What I'm trying to do is export this SVG to an image using canvg library, the problem here is that they are separated and so I get two canvas, and canvg library accepts a SVG definition string as input.
How can I modify the html elements above so that they are only one SVG? Using Javascript as this is a browser extension.
I have tried just switching the DIVs tags to SVG but it just broke everything and the SVG became blank
This is my solution to your problem: I make the outer div display:none, I'm creating another svg element (you may do it dynamicaly) end inside the #new svg I'm using the #chart and the #legend. I hope it helps.
svg{border:1px solid;}
#outer {display:none}
#outer div{position:absolute; width:500px;}
<div id="outer">
<div id="chart-div">
<svg id="chart" viewBox="0 0 300 150">
<circle stroke="gold" fill="none" cx="100" cy="75" stroke-width="40" stroke-dasharray="124.85" stroke-dashoffset="20" r="20" />
</svg>
</div>
<div id="legend-div">
<svg id="legend" viewBox="0 0 300 150">
<rect fill="skyBlue" x="200" y="100" width="80" height ="30" />
</svg>
</div>
</div>
<svg id="new" viewBox="0 0 300 150" width="500">
<use xlink:href="#chart" />
<use xlink:href="#legend" />
</svg>
This is a Javascript solution for merging two svg accessibles in the document through DOM manipulation.
var svgNS = "http://www.w3.org/2000/svg";
var outer = document.getElementById('outer');
// get chart content
var chart = document.getElementById('chart-div');
var chartSvg = chart.getElementsByTagName('svg')[0];
var chartContent = Array.from(chartSvg.childNodes);
// get legend content
var legend = document.getElementById('legend-div');
var legendSvg = legend.getElementsByTagName('svg')[0];
var legendContent = Array.from(legendSvg.childNodes);
// create a merged-div where we are going to merge the svgs
var merged = document.createElement('div');
merged.setAttribute('id', 'merged-div');
outer.appendChild(merged);
// createElementNS for svg
var mergedSvg = document.createElementNS(svgNS, 'svg');
mergedSvg.setAttribute('id', 'merged');
// keep the viewBox of the chart
mergedSvg.setAttribute('viewBox', chartSvg.getAttribute('viewBox'));
merged.appendChild(mergedSvg);
// adding the content of both svgs
for (let i = 0; i < chartContent.length; i++) {
mergedSvg.appendChild(chartContent[i]);
}
for (let i = 0; i < legendContent.length; i++) {
mergedSvg.appendChild(legendContent[i]);
}
// the unmerged svgs can be removed
chart.remove();
legend.remove();
<div id="outer">
<div id="chart-div">
<svg id="chart" viewBox="0 0 300 150">
<circle stroke="gold" fill="none" cx="100" cy="75" stroke-width="40" stroke-dasharray="124.85" stroke-dashoffset="20" r="20" />
</svg>
</div>
<div id="legend-div">
<svg id="legend" viewBox="0 0 300 150">
<rect fill="skyBlue" x="200" y="100" width="80" height ="30" />
</svg>
</div>
</div>
Resulting markup:
<div id="outer">
<div id="merged-div">
<svg id="merged" viewBox="0 0 300 150">
<circle stroke="gold" fill="none" cx="100" cy="75" stroke-width="40" stroke-dasharray="124.85" stroke-dashoffset="20" r="20"></circle>
<rect fill="skyBlue" x="200" y="100" width="80" height="30"></rect>
</svg>
</div>
</div>
I wish to fit svg text inside a rect. I could use an approach to compare the widths and add line breaks to the text, but it's not tedious.
Is there a more elegant way than this? Maybe by using CSS or d3?
UPDATE:the following code appends foreignObject using d3 but the div is not displayed. (it is there in the code inspecter)
var group = d3.select("#package");
var fo = group.append("foreignObject").attr("x", 15).attr("y", 15).attr("width", 190).attr("height", 90);
fo.append("div").attr("xmlns", "http://www.w3.org/1999/xhtml").attr("style", "width:190px; height:90px; overflow-y:auto").text("Thiggfis the dgdexsgsggs wish to fit insidegssgsgs");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<p id="p"></p>
<svg width="220" height="120" viewBox="0 0 220 120" id="package">
<rect x="10" y="10" width="200" height="100" fill="none" stroke="black"/>
</svg>
A namespace cannot be assigned by attr, it's a side effect of element creation. You need an html div so you need to tell d3 that by calling the element xhtml:div, once you do that, d3 will do the rest.
var group = d3.select("#package");
var fo = group.append("foreignObject").attr("x", 15).attr("y", 15).attr("width", 190).attr("height", 90);
fo.append("xhtml:div").attr("style", "width:190px; height:90px; overflow-y:auto").text("Thiggfis the dgdexsgsggs wish to fit insidegssgsgs");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<p id="p"></p>
<svg width="220" height="120" viewBox="0 0 220 120" id="package">
<rect x="10" y="10" width="200" height="100" fill="none" stroke="black"/>
</svg>
Here's a simple example of a foreignObject used to insert HTML markup into an SVG:
<svg width="220" height="120" viewBox="0 0 220 120">
<rect x="10" y="10" width="200" height="100" fill="none" stroke="black" />
<foreignObject x="15" y="15" width="190" height="90">
<div xmlns="http://www.w3.org/1999/xhtml" style="width:190px; height:90px; overflow-y:auto"><b>This</b> is the <i>text</i> I wish to fit inside <code>rect</code></div>
</foreignObject>
</svg>
I would like to target an <a> tag's ID inside an inline SVG that is being used as a responsive image map. I don't need to manipulate the SVG, just launch a modal with fancybox by that ID if someone clicks on that <a href...>. (launch an iframe of a local page in this case)
I have read a dozen threads related to this and understand there is a namespace issue but I'm a JS noob and cant quite put it together - thank you for taking a look!
I did try the $('a[xlink\:href=#shows]’) but no joy.
<div id="inline-svg">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 1280" preserveAspectRatio="xMidYMin slice" width="100%" height="100%">
<a xlink:href="http://www.facebook.com/" xlink:title="Facebook" xlink:show="new" id="facebook">
<rect x="1102" y="392” width="102" height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="http://twitter.com/" xlink:title="Twitter" xlink:show="new" id="twitter">
<rect x="1102" y="520" width="102" height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="#" xlink:title="Mailing List" id=“mlist">
<rect x="1215" y="392" width=“102” height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="shows.html" xlink:title=“Shows” id="shows" >
<rect x="1215" y="520” width=“102” height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<rect width="1920" height="1280" style="fill:none"/>
</svg>
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#shows”).fancybox({
maxWidth : 400,
maxHeight : 300,
type : 'iframe',
});
});
</script>
changing:
$("#shows”).
to:
$("#shows").
Should work fine.