I am working with a jquery script i found online for my ticketing software. It adds the functionality of adding videos to a WIKI. the problem is it does not set a height or width to the video is it possible that it can be done with this code?
if ($('#idEditArticle')) {
var videos = $('a[href$=".m4v"], a[href$=".mp4"]');
$.each(videos, function(i, video) {
$(video).parent().prepend('<video src="'+$(video).attr('href')+'" controls></video><br/>');
});
}
here is the output in html
<p>
<a border="0" class="fb_attachment" href="default.asp?pg=pgDownload&pgType=pgWikiAttachment&ixAttachment=136818&sFileName=Paragon%20Invoice%203.mp4" rel="nofollow" title="">Paragon Invoice 3.mp4</a></p>
Even if its possible to manually add it to the html. I can't add inline css to the elements. I tried wrapping it into a div but it won't take an inline style it just deletes it upon submission.
Can i add a height and width to the jquery code to automatically set the height and width of videos.
This should work. Please note I am using max-width but any style will do.
if ($('#idEditArticle')) {
var videos = $('a[href$=".m4v"], a[href$=".mp4"]');
$.each(videos, function(i, video) {
// Added a style attribute here.
$(video).parent().prepend('<video src="'+$(video).attr('href')+'" controls style="max-width: 100%;"></video><br/>');
});
}
A clearer (from a coding perspective) way would be:
if ($('#idEditArticle')) {
// Search for all matching elements. Returns an array of jQuery objects.
var videos = $('a[href$=".m4v"], a[href$=".mp4"]');
// Simply use the array.each to iterate over the preceeding array.
videos.each(function(){
// now create a link, video and source element
var link = $(this);
var video = $('<video />');
var source = $('<source />').attr('src', link.attr('href'));
// append the element correctly to create a tree
video.append(source);
// Heres where you apply multiple style elements
video.css({'max-width':'100%'});
// prepend the tree to the desired location
link.parent().prepend(video);
});
}
The implementation works (might have had an extra space in < source /> - its supposed to be <source />:
// Search for all matching elements. Returns an array of jQuery objects.
var videos = $('a[href$=".m4v"], a[href$=".mp4"]');
// Simply use the array.each to iterate over the preceeding array.
videos.each(function(){
// now create a link, video and source element
var link = $(this);
var video = $('<video />');
var source = $('<source />').attr('src', link.attr('href'));
// append the element correctly to create a tree
video.append(source);
video.css('max-width','100%');
// prepend the tree to the desired location
link.parent().prepend(video);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
Test
Related
I work in a system where we have these elements representing a part of an audio clip, and a timeline for the audio that is browsable (click around to play different parts). However, the elements representing the parts of the audio clip does not actually link to the parts of the audio.. (so no "click this to play this part").
I have deducted that it is possible to link to a specific part of the call via for example: http://thelink.com/timeline?startms=%221600326183999%22. And that the elements all have an attribute called "startms", for example:
<div class="segment-item" startms="1600326183999"></div>
Is there any way I could loop through all the elements in the page with the class "segment-item" and add a href="" with the value of their individual "startms" value to the link (http://thelink.com/timeline?startms=%22TheValueHere%22).
Then finally, since I cannot build an addon to my browser for this, would it be possible to make a snipped which can be pasted into the console for easy use when I need it? Any other suggestions to making such a thing be easily accessible for usage without making or using an addon for chrome?
If you want to add the link to the element, you should add it like that
const elements = document.getElementsByClassName("segment-item")
for (element of elements) {
const a = document.createElement("a")
a.href = `http://thelink.com/timeline?startms=%22${element.getAttribute("startms")}%22`
a.innerText = "LINK NAME"
element.appendChild(a)
}
Adding a link based on element properties goes like this
const elements = document.getElementsByClassName("segment-item")
for (element of elements) {
element.innerHTML = `<a href="http://thelink.com/timeline?startms=%22${element.getAttribute("startms")}%22">
Link name
</a>`
}
This is quite a challenging problem. I haven't seen it solved anywhere on Stack Overflow. So I decided to post it.
0 ----17----+ +---30---
| | | +----47
| | | |
<div>ABC<b>B Elem<i>Italic</i>ent</b> DEF</div>
| |
+---8--- ---37--+
Action: Let's say Element <i> tag is clicked.
Problem: Create a function that returns coordinates [17,30]
Note: The coordinates are start and end caret position, represented as 0-based index, in original HTML source code, encompassing only the element that was clicked. May assume normalized HTML nodes as in id = "" becomes id="". (But extra credit, if it doesn't.)
Example 2: If <b> tag was clicked. The script should return [8, 37] because it is the start/end caret position encompassing the B tag.
Example 3: If ABC text or DEF text was clicked, return value is [0,47]
Walk the parent chain until you hit whatever tag you consider to be a container (<div> in your case, apparently).
Use the parent's childs to locate the particular child you're coming from, in case you have two or more identical childs, like in from <i>two</i> to <i>two</i> to <i>two</i> <i>two</i>.
That should give you the child offset within the parent. You can then cumulate the offsets until you hit the div tag or whatever other container element.
Ending position is just this offset plus the clicked element length.
And after two days of solving this, I am posting my own solution.
I tried to parse the DOM and count characters manually, at first. But that was more complicated than it had to be.
Credit: Thanks to kuroi neko, who suggested the end caret position is just start position + length of the HTML encompassing the clicked tag.
Note: I am manually removing <tbody> tags, before calculating caret values. This is because, even original HTML does not contain them, during normalization process (which takes place during innerHTML or outerHTML call,) they are auto-inserted. It's a personal preference, if you're building a text editor that needs this functionality -- to leave them alone and update original HTML.
On the other hand, if you prefer the purist approach, and want to consider the original HTML intact, as it was written by the author of said HTML, then you may want to remove <tbody> manually. This also assumes that you take responsibility for taking care of all other cases, similar to these. Whatever they might be. (Not included in the solution below.)
Solution: Considering textarea (HTML source editor) and #preview are two separate elements representing the same HTML.
$(document).ready(function() {
// Normalize source code
var normalized_html = document.getElementById("preview").innerHTML;
// Remove all TBODY tags (they are auto-inserted, even if not present in original HTML)
normalized_html = normalized_html.replace(/<tbody>/g, '');
$("#textarea").html(normalized_html);
$("#preview").on("click", function(event) {
// Get clicked tag HTML
var tag = event.target.outerHTML;
// Get original HTML before split character is inserted
var orig_html = document.getElementById("preview").innerHTML;//.replace(/<preview>/g, '').replace(/<\/preview>/g, '');
// Insert unique separator just before the tag that was clicked, to mark beginning
$(event.target).before("[*-*]");
// Get preview source code
var html = document.getElementById("preview").innerHTML;
// Remove line breaks
html = html.replace(/\r|\n/g, '');
// Remove tags that were auto-inserted by native normalization process that did not exist in original HTML.
html = html.replace(/<tbody>/g, '');
var before_split = html;
// Split HTML at the tag that was clicked
html = html.split("[*-*]")[0];
// Restore preview to original HTML
$("#preview")[0].innerHTML = orig_html;
// Get start and end of caret in source code
var caret_start = html.length;
var caret_end = caret_start + tag.length;
console.log("caret start = " + caret_start + " end = " + caret_end);
});
});
You achieve that by simply using Descop library.
// Get the source html code of target document
var html = yourFunctionToGetHTML();
// Get the target document itself
var dom = yourFunctionToGetDocument();
// Get the element you want to found in source code
var element = document.getElementById("target-element");
// Create an instance of Descop
var descop = new Descop();
// Connect document
descop.connectDocument(dom);
// Connect source code
descop.connectSource(html);
// Get element position in source code
var position = descop.getElementPosition(element);
// eg. position => { start: 320, end: 480 }
Requirement Description:
I have a page in which there is a description section. The description section is basically a big html section consists of images and texts.
So if a user clicks on an image, then the user should be redirected to another page which has only the description data in it. After redirection, the page should scroll itself to that clicked image.
Standard Solution
I know the issue is easy if we have the id for each image, such that we can send the id in the url with the hash and then using $anchorscroll, the page will automatically scrolls to that clicked image.
Actual Problem
But the issue is that i dont have an id with the img tag.
The html of description section is like this:
....
<div class="someclass"><img src="cdn url of the image"></div>
....
Please note that there is no such particular format of the html structure.
It can be in any form.
But the img tag contains only src.
The other page also has the same description data and HTML structure as the previous. I just need to scroll the page to the clicked image.
What can be the solution?
It's not good practises to do such things with AngularJS.
Anyway, I made you a function that will search for images that only contain src attributes.
But be carefull, if you remove or manipulate the elements, remember to call the $scope.$apply() Method! Otherwise AngularJS will not know that any element has been changed.
/**
* Gets all images with only a src attribute
* #param element Any element from where to start the function. If not defined document will be used
* #returns {Array} An array of Matching element
*/
function getMyImages(element) {
element = element || document;
var images = element.querySelectorAll('img[src]');//Get all images with src attributes
var matches = [];
for (var i = 0, j = images.length; i < j; i++) {
var attributes = images[i].attributes;
if (attributes.length > 1) {//Skip images with more than one attribute
continue;
}
if (attributes[0].name === 'src') {//if the attribute is a src attribute, add it to the matches
matches.push(images[i]);
}
}
return matches;//Matches will now just contain images with only src attribute
}
How can I use vanilla javascript + regEx to remove image elements, based on their source?
I am reading a RSS feed with a web app. I want to remove certain image elements if their source contains the word "comments".
It would be ideal to edit the rss feed before it's rendered onto the page (just pulled from the http request, and still in a 'string').
update:
Thanks for the replies. At the very bottom of each article, they are including a link to comments... which is what I want to remove.
Here is the code at the very end of each article:
<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ADDRESS/FEED"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/[ADDRESS]/[FEED]" /></a>
also, the [feed] value changes per article. So would it be better to check for the word 'comments' or check if the source starts with x?
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var img = images[i];
if (img.src.indexOf('comments') > 0) {
var link = img.parentNode;
link.parentNode.removeChild(link);
}
}
line 1: get a list of all images elements on the page
line 2: iterate over the list, remove those who's src has the word 'comments'. This is done by calling the indexOf method of any string object. Detailed here
Thanks for the replies. lins05 suggested some code that i've adjusted slightly. Note: instead of removing the element or it's parent, the following code simply hides the element.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var img = images[i];
if (img.src.indexOf('comments') > 0) {
img.style.display = "none";
}
}
The rss feed's list of articles are stored in a model on the page. It would be more ideal to chop the comments out of the model.. however the current approach of 'hiding the element every time the article is on the page' works fine :)
You may try this
var imgs=document.images;
for(i=0;i<imgs.length;i++)
if(imgs[i].src.test('comments'))
imgs[i].parentNode.parentNode.removeChild(imgs[i].parentNode);
DEMO.
Problem:
Extract all html between two headers including the headers html. The header text is known, but not the formatting, tag name, etc. They are not within the same parent and might (well, almost for sure) have sub children within it's own children).
To clarify: headers could be inside a <h1> or <div> or any other tag. They may also be surrounded by <b>, <i>, <font> or more <div> tags. The key is: the only text within the element is the header text.
The tools I have available are: C# 3.0 utilizing a WebBrowser control, or Jquery/Js.
I've taken the Jquery route, traversing the DOM, but I've ran into the issue of children and adding them appropriately. Here is the code so far:
function getAllBetween(firstEl,lastEl) {
var collection = new Array(); // Collection of Elements
var fefound =false;
$('body').find('*').each(function(){
var curEl = $(this);
if($(curEl).text() == firstEl)
fefound=true;
if($(curEl).text() == lastEl)
return false;
// need something to add children children
// otherwise we get <table></table><tbody></tbody><tr></tr> etc
if (fefound)
collection.push(curEl);
});
var div = document.createElement("DIV");
for (var i=0,len=collection.length;i<len;i++){
$(div).append(collection[i]);
}
return($(div).html());
}
Should I be continueing down this road? With some sort of recursive function checking/handling children, or would a whole new approach be better suited?
For the sake of testing, here is some sample markup:
<body>
<div>
<div>Start</div>
<table><tbody><tr><td>Oops</td></tr></tbody></table>
</div>
<div>
<div>End</div>
</div>
</body>
Any suggestions or thoughts are greatly appreciated!
My thought is a regex, something along the lines of
.*<(?<tag>.+)>Start</\1>(?<found_data>.+)<\1>End</\1>.*
should get you everything between the Start and end div tags.
Here's an idea:
$(function() {
// Get the parent div start is in:
var $elie = $("div:contains(Start)").eq(0), htmlArr = [];
// Push HTML of that div to the HTML array
htmlArr.push($('<div>').append( $elie.clone() ).html());
// Keep moving along and adding to array until we hit END
while($elie.find("div:contains(End)").length != 1) {
$elie = $elie.next();
htmlArr.push($('<div>').append( $elie.clone() ).html());
};
// htmlArr now has the HTML
// let's see what it is:
alert(htmlArr.join(""));
});
Try it out with this jsFiddle example
This takes the entire parent div that start is in. I'm not sure that's what you want though. The outerHTML is done by $('<div>').append( element.clone() ).html(), since outerHTML support is not cross browser yet. All the html is stored in an array, you could also just store the elements in the array.