I am trying to access the SVG DOM that has a variety of adobe illustrator (layered) elements within the SVG file. Ideally, I would align the HTML slider range number (1-100) with a individual 'g' elements and animate, hide, show when that range number is reached as the user engages with the slider.
Please see github project:
https://github.com/EdBrooks/media-stroke
$(document).ready(function() {
var input = document.getElementsByTagName('input')[0];
var svg = $('#svgFile').svg({loadURL: 'img/media_stroke.svg'});
for (i=0; i < svg.length; i++) {
var g = document.getElementsByTagName('g');
var g1 = [{0:g}];
console.log(g1);
// var g1 = document.getElementById('group1').style.visibility = "hidden";
// var re = [{0:g}];
// console.log(re);
}
function InputVal() {
this.number =
$('input');
var change = input.addEventListener('change', function() {
var value = this.value
console.log(value);
if (value == 23) {
alert('wow dumb')
}
}, false);
}
InputVal();
});
It looks like you want to perform manipulation on SVG elements and do some animation.. for that you can use library like Snap.svg which is similar to jQuery for HTML Dom!
Check out it's getting started page (look for section 15)
or watch video
Related
var range = this.quill.getSelection();
var value = prompt('please copy paste the image url here.');
if(value){
this.quill.insertEmbed(range.index, 'image', value, Quill.sources.USER);
}
I solved the problem of adding images by linking in the quill editor with the api code above. But I couldn't find how to add alt and title properties with the help of api. I can edit it later with the following javascript code, but I need to edit it at the image insertion stage.
if (e.target.tagName=='IMG') {
console.log(e.target.tagName)
var el = e.target;
el.setAttribute("title", "asdasdasd");
}
})
Also, when I add a or tag to the editor, it is surrounded by a p tag and cannot be edited. It puts everything in the p tag and doesn't allow tags like br. How can I solve these problems?
Sorry for the bad english.
There seems to be no easy and elegant way to do it. The API does not allow it (or I have not seen it) and the source code does not seem to be documented.
I propose this code while waiting for a better solution.
It is based on a solution to observe dynamically created elements. I have added the caption of the title and alt attribute.
To get the code to work, you will need to explain the following to your users:
They must write the title and alt in this format wherever they want to insert the image:
%title% A title %alt% An alternative text
Then, they must select that same:
%title% A title %alt% An alternative text
With that text selected they must click the image button and open the image.
Notice, at the moment, you cannot escape "%alt%", so you cannot use the "%alt%" expression within the value of an attribute.
Example:
%title% The title is before %alt% %alt% the %alt% attribute
This causes an unwanted alt attribute.
Paste this code after creating an editor.
BTW, it is only valid for the first editor that exists.
var FER_alt;
var FER_title;
function FER_callback(records) {
records.forEach(function (record) {
var list = record.addedNodes;
var i = list.length - 1;
for ( ; i > -1; i-- ) {
if (list[i].nodeName === 'IMG') {
if(FER_title.length > 0){
list[i].setAttribute('title',FER_title)
}
if(FER_title.length > 0){
list[i].setAttribute('alt',FER_alt)
}
}
}
});
}
var FER_observer = new MutationObserver(FER_callback);
var FER_targetNode = document.querySelector('.ql-editor')
FER_observer.observe(FER_targetNode, {
childList: true,
subtree: true
});
function FER_getTitleAlt(){
var selection = quill.getSelection();
var texto =quill.getText(selection.index,selection.length);
var titleE = texto.search("%alt%")
FER_title = texto.substr(7,titleE-7);
var titleI = titleE + 5
FER_alt = texto.substring(titleI)
}
var FER_imageboton = document.querySelector(".ql-image")
FER_imageboton.addEventListener("click",FER_getTitleAlt)
Instead of insertEmbed you can use getContents and setContents.
let delta = {
ops: [
{
attributes: {
alt: yourAltValue
},
insert: {
image: yourSrcValue
}
}]
};
let existingDelta = this.quill.getContents();
let combinedDelta = existingDelta.concat(delta);
this.quill.setContents(combinedDelta);
Extends Image blot and override the create method
const Image = Quill.import('formats/image');
class ImageBlot extends Image {
static create(value) {
const node = super.create(value);
if (typeof value === 'string') {
node.setAttribute('src', this.sanitize(value));
node.setAttribute('alt', this.sanitize(value).split('/').reverse()[0]);
}
return node;
}
}
Quill.register(ImageBlot);
In this example, we set alt attribute with image's basename
I am trying to make the elements clickable. However on clicking any of the <p> elements there is no alert box saying "hello". Please could you look at my code and possibly point me in the right direction?
function createLink(text, parentElement) {
var a = document.createElement('p');
var linkText = document.createTextNode(text);
a.appendChild(linkText);
a.onclick = function(e) {
e.preventDefault();
alert("hello");
};
parentElement.appendChild(a);
var br = document.createElement('br');
parentElement.appendChild(br);
}
var txtFile8 = new XMLHttpRequest();
txtFile8.open("GET", "http://www.drakedesign.co.uk/mdmarketing/uploads/date.txt", true);
txtFile8.onreadystatechange = function() {
if (txtFile8.readyState === 4) { // Makes sure the document is ready to parse.
if ((txtFile8.status == 200) || (txtFile8.status == 0)) { // Makes sure it's found the file.
allText8 = txtFile8.responseText;
arrayOfLines8 = allText8.match(/[^\r\n]+/g);
for (i = 0; i < arrayOfLines8.length - 1; i++) {
createLink(arrayOfLines8[i], document.getElementById("previousResultsList"));
}
}
}
};
txtFile8.send(null);
The script parses a text file online:
http://www.drakedesign.co.uk/mdmarketing/uploads/date.txt
Which is updated weekly and has dates written in it like so:
19/04/16
12/04/16
...
My script separates the text document into each line and stores it as an array. A for loop is then used to show the dates on the screen in a column which looks like so:
The problem is that on clicking each date an alert box is not shown saying "hello" and there seems to be no response at all.
All help is greatly appreciated.
I solved the issue!!
The problem was that I had divs with opacity 0 that were overlaying my parentElement! sorry stupid mistake!
I would like to implement a Table of Contents in the sidebar of a Google Docs document which will take you to the appropriate sections when clicked. I am generating the HTML for the sidebar element by element, and I see that there is a moveCursor(position) function in Document class, but I can't see how to actually call it using onclick. Not the full code but shows the problem:
function generateHtml() {
var html = HtmlService.createHtmlOutput('<html><body>');
var document = DocumentApp.getActiveDocument();
var body = document.getBody();
//Iterate each document element
var totalElements = body.getNumChildren();
for(var i = 0; i < totalElements; ++i) {
var element = body.getChild(i);
if(element.getType() == DocumentApp.ElementType.PARAGRAPH) {
var text = paragraph.getText();
if(text.trim()) { //Not blank paragraph
var position = document.newPosition(element, 0);
/**Would like to have <a onclick=document.moveCursor(position)> here**/
//Show first 20 chars as preview in table of contents
html.append('Detected paragraph ')
.append(text.substring(0, 20))
.append('<br />');
}
}
}
html.append('</body></html>');
return html;
}
How can I accomplish this in Apps Script? The code can be completely restructured as needed.
This line:
/**Would like to have <a onclick=document.moveCursor(position)> here**/
Change to:
<div onmouseup="myClientFunction()">Text Here</div>
Add a <script> tag to your HTML:
<script>
var valueToSend = code to get value;
window.myClientFunction = function() {
google.script.run
.myGsFunctionToMoveCursor(valueToSend);
};
</script>
Then you need a myGsFunctionToMoveCursor() function in a script file (.gs extension)
function myGsFunctionToMoveCursor(valueReceived) {
//To Do - Write code to move cursor in Google Doc
. . . Code to move cursor
};
I want to create a function that grabs all the instances of an image class on the page. As default these will be hidden, then randomly after a certain interval show one of those images (can be any image). Then the function will rerun and show another image. (whilst hiding the image that was shown on the first run through.
I've got to this stage with the function (not currently working)
(function randomShow() {
var showDiv = $('.show'),
el = showDiv.eq(Math.floor(Math.random() * showDiv.length));
el.show().delay(2000).show(randomShow);
})();
Thanks
I put together a jsFiddle using divs in place of images to demonstrate (pure js):
http://jsfiddle.net/oogley_boogley/az9gd8wf/
the script:
var divs = document.getElementsByClassName('square');
var arrLength = divs.length;
var randomNumberLimit;
var interval_speed = 1000;
setInterval(function(){
randomNumberLimit = Math.floor((Math.random() * arrLength) + 1);
for(i=0;i<arrLength;i++){
var matchingDiv = divs[i];
if(matchingDiv.id == randomNumberLimit){
matchingDiv.setAttribute("class","showing square blue");
}
if(matchingDiv.id != randomNumberLimit){
matchingDiv.setAttribute("class","hiding square blue");
}
}
}, interval_speed);
I want to fill a country depends on how many users are online from this country. I have SVG file which has all countries, and the if for example from Canada I have 5 people online, then script should fill id="ca to green.
I storage the Data in a JSON formatted file.
The error I get in the Console is:
TypeError: svgMap is undefined
var mapElement = svgMap.getElementById(iso).style.fill="#94d31b";
$(document).ready(function()
{
$.getJSON("results.json", function(data)
{
data = data.iso_countries;
var map = document.getElementById("blank_map");
var svgMap = map.contentDocument;
for(var key in data)
{
var iso = data[key].country;
var visitors = data[key].visitors;
if( visitors > 1 && 50>=visitors)
{
var mapElement = svgMap.getElementById(iso).style.fill="#94d31b";
}
else if( visitors > 50 && 500>=visitors)
{
document.getElementById("iso").style.fill="#94d31b";
}
}
});
});
It is possible you will have an easier time if you use d3.js to generate an SVG instead of JQuery. See this example, similar to what you would like to do. http://bl.ocks.org/mbostock/5912673
Your need NameSpace for javascript, to handle tags to append new tags o update tags
function Text(){
//svg is a google chart
var svg = document.getElementById('graphic').getElementsByTagName('svg')[0];
var parent = svg.contentDocument;
//show me structure svg as DOM
console.log(parent);
//find tag fill and change color and write element type text
for(var i=0; i<svg.childNodes[4].childNodes[1].childNodes[1].childElementCount; i++) {
var g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
var child = svg.childNodes[4].firstChild.nextSibling.firstChild.nextSibling.firstChild;
text.setAttribute('x', child.getAttribute('x'));
text.setAttribute('y', child.getAttribute('y'));
text.setAttribute('fill', '#000000');
text.setAttribute('dy', '-2');
text.textContent = 'Hell0';
parent.removeChild(child);
g.appendChild(child);
g.appendChild(text);
parent.appendChild(g);
}
}
I hope that it help you