I have an element (in html)
<image xlink:url="https://abc" id="my_ele">
I do
ele = document.getElementById("my_ele")
// Now want to get https://abc
This answer here Getting 'xlink:href' attribute of the SVG <image> element dynamically using JS in HTML DOM
says:
getAttributeNS('http://www.w3.org/1999/xlink', 'href');
But I'm not really sure what that translates to in my example.
(btw, Google docs displays images like this, at least in Chrome. Don't know why they don't use a proper IMG tag.)
<image xlink:href="https://abc" id="my_ele">
and
ele = document.getElementById("my_ele")
var url = ele.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
Related
I have HTML tag with link in background style and I want this link to be a string in my JS file. How can I do that?
<div class="bmlistt" style="background: url('b.ppy.sh/thumb/845746.jpg';)"></div>
You can grab the it using this:
var bg = $("div.bmlistt").css('background');
bg = bg.replace('url(','').replace(')','').replace(/\"/gi, "");
How about the following:
const imageElement = document.getElementsByClassName('bmlistt')[0];
let image = imageElement.style.background.replace('url("', '').replace('")', '');
console.log(image);
<div class="bmlistt" style="background: url(b.ppy.sh/thumb/845746.jpg)"></div> <!-- Fix ";" in style attribute -->
No need for big libraries. querySelector to get the div. I would use its style.background or style.backgroundImage property. The latter of those only contains the image itself, and not any other background css you might specify in a real life scenario, possibly making it easier to extract the url.
Unfortunately with your specific HTML that doesn't work, because of an error in the CSS (the semicolon). So in that case you have to parse the style attribute as text, rather than relying on the style object property, which contains the browser's interpretation of your CSS. Both solutions are shown below.
var theDiv = document.querySelector('.bmlistt');
console.log(theDiv.style);
// Doesn't work because of error in the CSS. Otherwize this would do it.
var css = theDiv.style.backgroundImage;
console.log(css.substr(5, css.length - 7));
var attr = theDiv.getAttribute('style');
// This, if you know the length of the 'overhead' around the url, or
// a regular expression.
console.log(attr.substr(17, attr.length - 20));
<div class="bmlistt" style="background: url('b.ppy.sh/thumb/845746.jpg')"></div>
I am attempting to use DOMParser to parse (X)HTML and then display it within the page. It appears to embed the correct elements in the page with the markup looking exactly as it should, but despite this they behave strangely (e.g. setting style='display: none' has no effect.)
What is going on here?
var parser = new DOMParser();
var markup = '<p id="testp">Can you see me?</p>';
var doc = parser.parseFromString(markup,"text/xml");
document.body.appendChild(doc.documentElement);
document.getElementById('testp').setAttribute('style', 'display: none');
https://jsfiddle.net/57064q1u/
you have to use text/html to use the style attribute. Otherwise you will only create a xml node.
var doc = parser.parseFromString(markup,"text/html");
I have a page where i open a modal and i want that each time it is opened a new svg image is displayed there.
<div class="col s3 center-align" id="event_logo">
<object type="image/svg+xml" data="" id="literary_logo_object" class="event_logo_object" ></object>
</div>
I want to assign the data attribute of <object> dynamically.
What i tried is
document.getElementById('literary_logo_object').setAttribute('data','svg/literary.svg');
var event_logo = Snap(Snap("#literary_logo_object").node);
It seems that changing the attribute data is not allowed like this. After adding the last line, i get the following error
Error: Invalid value for <svg> attribute height="undefined"
Error: Invalid value for <svg> attribute width="undefined"
both the errors are in line 930 of snap.svg.js, which is very highly unlikely.
What else i have tried
I readily defined the object tag like this
<div class="col s3 center-align" id="event_logo">
<object type="image/svg+xml" data="svg/literary.svg" id="literary_logo_object" class="event_logo_object" ></object>
</div>
and made it hide, i.e., display : none
then i tried unhiding the object like
$("#literary_logo_object").show();
var event_logo = Snap("#literary_logo_object").node;
again after the second line i am getting the same error.
Its not quite clear what you are attempting, ie I'm not sure why you are using Snap (yet) for this.
document.getElementById('literary_logo_object').setAttribute('data','svg/literary.svg');
The above should load the new svg in place, thats it.
You don't need Snap for this, as you aren't doing anything with the svg.
I'm also not sure why you don't just use a Snap.load() function, or is there some specific reason you need an object tag ?
If you want to then do something with the SVG thats loaded, you can reference it with 'contentDocument' (as this is in a different document), so using Snap it would look something like this...
var obj = document.getElementById('literary_logo_object');
obj.setAttribute('data','svg/literary.svg');
obj.onload = function( ev ) { // it may take a while to load
Snap( obj.contentDocument.getElementById("someElInsideSvg") )
.animate({ transform: 't-400,-400' }, 2000); //do whatever
}
I have a html snippet being returned through ajax. The snippet is an <img> tag.
<img src="image.jpg" />
I need to extract the value of the src attribute without loading the image initially. The reason for this is the src attribute contains a partial path that I need to manipulate in my app to load the image properly.
I have the following code currently extracting the src attribute:
var src = $(value).attr('src');
However, this causes the image to load, resulting in a 404. I would like to avoid this unnecessary request.
How can I extract the value of the src attribute without causing the browser to load the image?
I solved this by changing the name of the src attribute before loading it into jquery.
value = value.replace('src', 'data-src');
var src = $(value).attr('data-src');
Doing this allows me to extract the value without causing the browser to attempt to load the images.
Your best bet is probably to output a data tag on the image. You can then manipulate this using jQuery and then use it to write the final image path.
So you'd do something like this in your HTML:
<img data-img-src="abc.jpg" class="my-image" />
Then in your jQuery:
var path = $('.my-image').data('img-src');
console.log(path); // Do something here, then write the new path with:
$('.my-image).attr('src', new_path);
EDIT: Sorry I just re-read the bit where it's coming via AJAX. In that case, you can probably use the data callback of your ajax request to strip the src from the image.
$.ajax('someURL.html', function(data){
var html = data.replace(/\ssrc/g, ' data-src'),
img = $(html),
src = 'some/path/' + img.data('src');
img.attr('src', src);
$('#container').append(img);
});
If you just have the string , like <img src="image.jpg" /> why dont you go for regex?
Something like: /[\"\'][a-z0-9A-Z\.]*/.
PS:My regex skills are poor,so you could manipulate it accordingly.
Use
var string = '<img src="image.png">';
var matches = string.match(/src\=("|')(.*?)\1/);
console.log(matches[2]);
You can simply remove the attribute after accessing it.
This will not load the invalid image, as you can confirm in your console:
var s= $('<img src="invalidURL.jpg">'),
src= s.attr('src');
s.removeAttr('src');
console.log(src);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Remove removeAttr(), and it will attempt to load the image.
I have trouble composing an inline-SVG using Javascript.
The problem can be reduced to the following code (live example here):
Somewhere inside the body:
<svg id="drawing" xmlns="http://www.w3.org/2000/svg" version="1.1">
</svg>
Inside onReady:
$("#drawing").append($("<rect style='fill: blue' width='100' height='100' />"));
I expected to see a blue rectangle now. However, Chrome and Firefox don't show anything.
Using Firebug, I found out that Firefox interprets the "rect" as a HTMLUnknownElement (and not as a SVGElement).
If I choose "Edit SVG" on the SVG element (using Firebug) and insert a whitespace somewhere, the SVG seems to be reparsed and the rectangle appears.
How can I tell the parser to parse this fragment correctly?
I'm afraid it's not that easy:
jsfiddle is not the place to test svg, it sends wrong content-type
references to external js-files can't be created the html-way(always keep in mind, svg doesn't have to do anything with html)
jquery uses some dummy-div's for creating the elements when using append(), but svg doesn't know div-elements
also note: binding's to the load-event of a svg-document with jQuery doesn't seem to work
Here an example-code, works for me in FF when delivered as image/svg+xml
<svg id="drawing"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
onload="fx()">
<script type="text/ecmascript" xlink:href="http://code.jquery.com/jquery-latest.js" />
<script type="text/ecmascript">
function fx()
{
$(document.createElementNS('http://www.w3.org/2000/svg', 'rect'))
.css('fill','blue')
.attr({'width':100,'height':100})
.appendTo('#drawing');
}
</script>
</svg>
But like Marcin I would suggest to use a plugin.
To add from the parent document you may use an object containing the properties of the element, basic example:
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
function fx(obj,params)
{
var svgDoc=obj.contentDocument;
if(typeof params.name!='string')return;
var props=$.extend({'attrs':{},'style':{},'selector':null},params);
props.target=(!props.selector)?svgDoc.documentElement:$(svgDoc).find(props.selector)
$(svgDoc.createElementNS('http://www.w3.org/2000/svg', props.name))
.css(props.style)
.attr(props.attrs)
.appendTo(props.target);
}
/*]]>*/
</script>
</head>
<body>
<object onload="fx(this,{'name':'rect','attrs':{'width':100,'height':100},'style':{'fill':'blue'},'selector':'#drawing'})"
data="my.svg"
type="image/svg+xml"
width="200"
height="200">
<param name="src" value="my.svg">
</object>
</body>
</html>
The structure of the object:
name:tagName(string)
attrs:attributes(object)
style:style(object)
selector:selector(string, if omitted the root-element will be selected)
This example shows how to embed SVG in XHTML, including the programmatic creation of new SVG elements: http://phrogz.net/svg/svg_in_xhtml5.xhtml
This example shows how to use XHR to fetch SVG as XML, find a fragment of it, and two ways convert it into the local document before appending the node to the existing SVG document: http://phrogz.net/svg/fetch_fragment.svg
In general:
Don't use jQuery with SVG directly.
Dynamically-created SVG elements must be created using createElementNS, supplying the SVG namespace URI 'http://www.w3.org/2000/svg'. (Note, however, that the SVG attributes should not be created with a namespace.)
You need to be sure to serve your XHTML as XML (content-type: application/xhtml+xml) and not as text/html.
Here's a general-purpose function I use on occasion for creating SVG elements conveniently. It works both within SVG documents as well as SVG-in-XHTML, allows for text content to be created directly, and supports namespaced attributes (such as xlink:href).
// Example usage:
// var parentNode = findElementInTheSVGDocument();
// var r = createOn( parentNode, 'rect', {
// x:12, width:10, height:10, 'fill-opacity':0.3
// });
function createOn(root,name,attrs,text){
var doc = root.ownerDocument;
var svg = root;
while (svg.tagName!='svg') svg=svg.parentNode;
var svgNS = svg.getAttribute('xmlns');
var el = doc.createElementNS(svgNS,name);
for (var attr in attrs){
if (attrs.hasOwnProperty(attr)){
var parts = attr.split(':');
if (parts[1]) el.setAttributeNS(svg.getAttribute('xmlns:'+parts[0]),parts[1],attrs[attr]);
else el.setAttributeNS(null,attr,attrs[attr]);
}
}
if (text) el.appendChild(document.createTextNode(text));
return root.appendChild(el);
}
I assume you'd like to get a fragment of SVG parsed, without having to turn it into JSON and whatnot. Here's some CoffeeScript that does it. I tested the code on SVG embedded in HTML, but I think it should work in any circumstance.
https://github.com/pwnall/ddr/blob/master/javascripts/graphics/pwnvg.coffee#L169
I wrap the SVG fragment in an tag to build a stand-alone SVG document, then I use a DOMParser to parse the SVG document, and I pull out the children of the root element (the wrapper) one by one, and stick them into the original SVG's DOM.
In theory, there is an easier (and faster approach), but it doesn't work right now. http://crbug.com/107982
See: Convert svg into base64
I always make sure a svg fragment is inside a svg element or just force refresh the svg.