I have this HTML code (it is located in contenteditable="true" block):
<ol>
<li>Mozilla Firefox 1.5+</li>
<li>Internet <span>Explorer</span> 6+</li>
<li>Opera 9.6+</li>
<li>Google Chrome 2+</li>
<li>Apple Safari 3+</li>
</ol>
User has selected some text in this list:
exactly the word «Chrome»,
or exactly the word «Explorer» (it is wrapped with span tag).
The main difference between words «Chrome» and «Explorer» is that word «Explorer» is wrapped with span tag, but «Chrome» is not.
So, how do I know if selected text wrapped with some HTML tags or not?
With some regexp? — I don't know how to get selected text with HTML tags (I know only how to get plain text from selection).
With detecting range's commonAncestorContainer.parentNode? — If I have selected word «Chrome», my parentNode will be li tag (but li tag doesn't wrap my selected word directly, I don't want set styles for li tag). So, I cannot use commonAncestorContainer.parentNode 'cos it is useless for me.
Actually, I just want to set some CSS styles for the selected text:
if user's selected text has already directly wrapped with some HTML tag, I want to add CSS rules for this tag (eq. if user has selected word «Explorer» I want to add style="font-weight:bold;" for the span tag; if user has selected Apple Safari 3+ I want to add CSS rules for li tag)
if user's selected text is just plain text (not directly wrapped with some tags, like word «Chrome»), I want to wrap this text with some tags and add some CSS rules. (With this item I have no problems, I know how to do this.)
UPD:
Look, when I select some text and then run document.execCommand('Bold', false, null), browser wraps my selection with b tags. When I select exactly the same text again and run the same document.execCommand('Bold', false, null) command, boldness disappear. So, browser somehow knows that my selection is wrapped with b tags and remove them (unwrap). So, how does browser know, is selection wrapped with tags or not? If browser knows, why it is so hard to make it with JS?
This is a slightly complex area:
IE < 9 has a completely different API for selections and ranges from other browsers
Getting hold of and then styling the selected content requires some careful DOM manipulation
Here are two suggestions:
If you just want to toggle boldness on the selection, you can use document.execCommand("bold", false, null)
If using CSS classes rather than element style properties/attributes, you could use the CSS class applier module of my Rangy library.
Related
I am attempting to use a CSS selector in Google Tag Manager to track the stock number of a product.
screenshot
The data is in an unordered list, and the stock number is in its own separate li element. I do know how to target the li element I want, only it pulls in "Stock #: 38194" when I JUST want the stock number. Here's how the code looks:
<li><span>Stock #:</span> 38194</li>
Is there a way I can format the CSS selector - or perhaps use custom JS - to tell GTM to pull that number outside the span tags, and not the words "Stock #"?
In a perfect world, I could put the stock number in its own set of span tags, and give those an id or class, but I have no access to the back end.
Thanks for your help!
There is no css selector for textnodes, so you cannot target text that is not wrapped into an element. Probably the easiest way to do this would be to use a DOM variable to return the text node of the li element (being text it will not contain the markup for the span) and then use a custom javascript to replace the unwanted text, so: {{myDOMvariable}}.replace("Stock #","");
I wrote the following JS code:
<script>
function myFunction() {
document.write("<img src=x>")
}
myFunction();
</script>
while my function works fine and adds a new img tag to the page whenever I use Ctrl+Shift+I in Chrome then Ctrl+F then I type <img src=x> and I get 0 of 0 found. How to fix this?
From your comment:
ctrl+shift+i in chrome then ctrl+F then I type and I get 0 of 0 found
There's no need to do that. Just right-click the image and click Inspect. Chrome will take you right to it in the Elements panel.
Re searching in the Elements panel:
The Elements panel doesn't show the exact HTML you wrote, it shows you the DOM, rendered as canonical HTML. So for instance, the src attribute will be in quotes.
But, the search box in the Elements panel doesn't search HTML, it searches the DOM. So typing plain text will match text in text in text nodes, text in attributes, attribute names, tag names, etc., but not exact HTML. So if you search for the URL of the image, it'll find it, but it won't find it if you search for <img src=. This has nothing to do with it having been added via document.write, it's just how Chrome's Elements panel works.
You can find the element by typing XPath or a CSS selector, for instance img[src=x] will find it. Here's an example (I used your Gravatar rather than x):
There, you can see that the selector img[src*=gravatar] found the image, because that selector (using the "contains" attribute selector, *=) matches the element.
Am working on an e_pub reader ios app. For highlight the selected text I am calling the javascript after selected the text, by surrounding the selected text with a span tag. My problem is is the selection happens within the paragraph, highight happens, if it made across the paragraph it doesn't work because of intermediate <p> tag. How to check whether the selected range has any html tags or not ?
instead of searching you can remove all html tag inside your content. simply by using jquery
var content = "<div>This Text contains <p> Some P tags</p> and <span> span tag </span></div>";
console.log($(content).text());
so you can remove all tags and wrap with your content with span then apply highlight.
If I'm adding a tag in JavaScript to another tag how can I check to see if it's valid.
IE I have this block:
Using JQuery:
var fragment = $("<p>Some text is <strong>here</strong></p>");
Is there a way using either JavaScript or some library to query this fragment and get a list of allowable tags?
For instance:
fragment.wrapInner('<em></em>');
Will generate valide HTML, but:
fragment.wrapInner('<div></div>');
Won't as div is not allowed inside a P tag.
The reason I want to do this is related to Range#surroundContents, as it's not letting me insert span tags directly inside divs, only insides p tags and the reverse is true as well, but I need a solution that will insert the correct type element inside the tag. IE div should not insert into p and the reverse, but these are far far from the only cases I need to concern myself with, as I'm dealing with generic content, so I need a general solution.
My goal is to be able to get the highlighted text within a document, but only if that text is within a given section, and then apply a certain style to that selected text after clicking a div tag. I'll explain what I mean:
So, having looked at window.getSelection() and document.selection.createRange().text, I attempted to use elmnt.getSelection() or elmnt.selection.createRange().text for some HTML element, elmnt. However, it doesn't seem to work, so that idea seems pretty null. This means I can't use this idea to determine the text that is highlighted within a given location. In case this doesn't make sense, essentially, I want html code that looks like this:
<body>
<div id="content">Stuff here will not be effected</div>
<div id="highlightable">Stuff here can be effected when highlighted</div>
<div id="morecontent">Stuff here will also not be effected</div>
</body>
So that whenever I've highlighted text, clicking on a specified div will apply the proper CSS.
Now, on to the div tags. Basically, here's what I've got on that:
$('.colorpicker').click( function(e)
{
console.log(getSelectedText());
}
Eventually, all I want this to highlight the selected text and have the div tag change the color of the selected text to that of the respective div tag that I've selected. Neither of these seems to be working right now, and my only guess for the reason of the div tag is that it unhighlights whatever I've got selected whenever I click on the div tag.
Fallbacks:
If there is more than one time that 'abc' is found on the page and I highlight to color 'abc', I would like that only that copy of 'abc' be highlighted.
I know this is a lot in one question, but even if I could get a little head start on this idea, my next personal project would be going a lot more smoothly. Thanks. :)
The key in the solution to this will be working with the objects that represent text ranges in browsers, not the selected text itself. Look into methods available to you in both the FireFox Range and IE TextRange objects. Both of these contain means of replacing the selected text with your own markup (e.g. a span wrapping your selected text.)
For FF look into Range.getRangeAt(0).surroundContents(element)
For IE look into TextRange.pasteHTML()
I must warn you though... You'll probably end up down a scary path of browser quirks if you go through with this. Already from the get-go you're supporting two different objects for two of the major browsers.