Simply tag-based highlighting with Javascript - javascript

I got this code which works:
<html>
<head>
<title>JS highlighting test</title>
<script type="text/javascript">
function highlight()
{
var t = document.getElementById('highlight').innerHTML;
t = t.replace(/(if|switch|for|while)\s*(\()/gi, "<b>$1</b>$2");
document.getElementById('highlight').innerHTML = t;
}
</script>
</head>
<body onload="javascript:highlight();">
<pre id="highlight">
1 if(foo) {
2 bar();
3 }
4
3 while(--baz) {
5 oof();
6 }
</pre>
</body>
</html>
I would like to have it for all <pre> tags instead of just one with some specific and
unique id as it works now. The best would be to have an combination of a specific tag
with a specific id. Is it possible to extend the small JS function above to work this
way (using some document.getElementsByTag(tag).getElementsById(id).innerHTML or
something alike (I don't know what exactly suites the need) in a loop? I tried myself but with no real success. I need only as simple solution as possible, nothing really special.
Thank you for your ideas.
--
nkd

You almost guessed it right ;-)
function doSomethingWithAllPres() {
var pres = document.getElementsByTagName("pre");
for (var i = 0; i < pres.length; i++) {
// you can check the class name via pres[i].className === "highlight"
// (and you should use a class instead of an id therefore)
if (pres[i].className.indexOf("highlight") >= 0) {
// action goes here
}
}
}
Using a JS-Framework like jQuery, things would be even more simple:
$("pre.highlight").each(function(i) {
// action goes here
});
However, using a framework might be overkill...

Related

In a pinch, stuck in a simple onclick text cycle

For a project, I'm trying to highlight the logical fallacy of circular reasoning and have precious few lines of code later to be inserted into a separate webpage.
I am trying to create a simple process of clicking the displayed text to switch back and forth between the two questions. I've tried buttons and it only complicates and make no progress. Half a day gone, still banging my head on desk, as the phrase goes.
I read elsewhere that creating a var tracker facilitates, though I see it only for images, rather than displayed text. It feels like approaching my wits end, but I lack the time to walk away and try again.
This is my code thus far:
<!doctype html>
<head>
<script>
function change() {
var paragraph = document.getElementById("whytrust");
paragraph.innerHTML="I am trustworthy, but how can you be sure?";
}
</script>
</head>
<body>
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
</body>
</html>
You need some place to hold the old message so you can put it back again after you toggle the contents.
<!doctype html>
<head>
<script>
var newMsg = "I am trustworthy, but how can you be sure?";
function change() {
var paragraph = document.getElementById("whytrust");
var oldMsg = paragraph.innerHTML;
paragraph.innerHTML = newMsg;
newMsg = oldMsg;
}
</script>
</head>
<body>
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
</body>
</html>
This a quick and dirty implementation of what you want. I added a data-textindex attribute to the html element. There I stored an index for the currently shown text. In the javascript I check the current value, update data-textindex and replace it with new text.
function change() {
let paragraph = document.getElementById("whytrust");
let currentlyshown = paragraph.getAttribute('data-textindex');
if(currentlyshown == 0){
paragraph.innerText="I am trustworthy, but how can you be sure?";
paragraph.setAttribute('data-textindex', '1');
}else if(currentlyshown == 1){
paragraph.innerText="You can trust me, but how can you be sure?";
paragraph.setAttribute('data-textindex', '0');
}
}
<p id="whytrust" data-textindex="0" onclick="change();">You can trust me, but how can you be sure?</p>
On a sidenote: You can improve this code a lot. Like storing your text in a json-object. Or maybe using the ternary operator if you are 100% sure there will always be 2 choices. maybe give the function some arguments so you can apply it in a more general scenario.
Try tracking some sort of 'state' for your paragraph -- be it on/off, active/inactive...
Each time the change() function gets called, it doesn't remember what the paragraph was or was supposed to be. So, by setting a state of some sort (in my example a data-state attribute assigned to the paragraph element) the code can know how to behave.
function change() {
var paragraph = document.getElementById("whytrust");
var output = '';
// data-* can be anything, but handy for referencing things
var state = paragraph.getAttribute('data-state');
// check if data-state even exists
if( !state ){
// set it to the default/original state
paragraph.setAttribute('data-state', 'inactive');
state = 'inactive';
}
// toggle the state
// and assign the new text
if( state === 'inactive' ){
paragraph.setAttribute('data-state', 'active' );
output = "I am trustworthy, but how can you be sure?";
}else{
paragraph.setAttribute('data-state', 'inactive');
output = "You can trust me, but how can you be sure?";
}
paragraph.innerHTML = output;
}
<p id="whytrust" onclick="change();">You can trust me, but how can you be sure?</p>
Another option, without tracking state could be hiding and showing the paragraph you want displayed. You don't really need to track state or save the alternating text...
// get the elements from the DOM that you want to hide/show
// you can get tricky and add alternative ways to track
// the paragraph elements, but this works nice for a demo
const whytrust = document.getElementById('whytrust'),
answer = document.getElementById('whytrust-answer');
function change( element ){
// the element parameter being passed is the paragraph tag
// that is present/visible
if( element.id === 'whytrust' ){
answer.className = ''; // clear the .hide class
whytrust.className = 'hide'; // add the .hide class
}else{
whytrust.className = ''; // clear the .hide class
answer.className = 'hide'; // add the .hide class
}
}
.hide{ display: none; }
<p id="whytrust" onclick="change(this);">I am trustworthy, but how can you be sure?"</p>
<p id="whytrust-answer" class="hide" onclick="change(this);">You can trust me, but how can you be sure?</p>
What I like about this solution is that it keeps the content in the HTML and the JavaScript just worries about what to hide/show.

Make all elements of a html class react on a click, which would modify the element itself

I am trying to write a tutorial for my students, in the form of a webpage with hidden "spoilers" that the student can unhide, presumably after thinking about the answer. So, long story short, the behavior I am looking for is:
in the beginning, the text appears with a lot of hidden words;
when a piece of text is clicked, it appears, and stays uncovered afterwards;
this should work with minimal overhead (not forcing me to install a complex framework) and on all my students' machines, even if the browser is outdated, even if jquery is not installed.
I searched for off the shelf solutions, but all those I checked were either too complicated or not doing exactly what I wanted. So I decided to do my own.
What I have so far is this:
<HTML>
<STYLE>
span.spoil {background-color: black;}
span.spoiled {background-color: white;}
</STYLE>
<HEAD>
<TITLE>SPOIL</TITLE>
<META http-equiv="Content-Type" content="text/html;charset=UTF-8">
<!--LINK rel="Stylesheet" type="text/css" href=".css"-->
</HEAD>
<BODY>
This is a text with <span class="spoil" onclick="showspoil(this)">spoil data</span>.
<br>
<span class="spoil" onclick="showspoil(this)">Unspoil me.</span>
<br>
<span class="spoil" onclick="showspoil(this)">And me.</span>
<script>
function showspoil(e) {
e.className="spoiled";
}
// var classname = document.getElementsByClassName("spoil");
// for (var i = 0; i < classname.length; i++) {
// classname[i].addEventListener('click', showspoil(WHATEXACTLY?), false);
// }
</script>
</BODY>
</HTML>
It does the job, except that I find it annoying to have to write explicitly the "onclick..." for each element. So I tried adding an event listener to each member of the class, by imitating similar resources found on the web: unfortunately, this part (the commented code above) does not work. In particular, I do not see which parameter I should pass to the function to transmit "the element itself".
Can anyone help? If I may play it lazy, I am more looking for an answer to this specific query than for pointers to a series of courses I should take: I admit it, I have not been doing html for a loooooong time, and I am sure I would need a lot of readings to be efficient again: simply, I do not have the time for the moment, and I do not really need it: I just need to solve this issue to set up a working solution.
Problem here is you are calling the method and assigning what it returns to be bound as the event listener
classname[i].addEventListener('click', showspoil(WHATEXACTLY?), false);
You can either use a closure or call the element directly.
classname[i].addEventListener('click', function () { showspoil(this); }, false);
or
classname[i].addEventListener('click', showspoil, false);
If you call it directly, you would need to change the function to
function showspoil(e) {
this.className="spoiled";
}
Another option would be to not bind click on every element, just use event delegation.
function showspoil(e) {
e.className="spoiled";
}
document.addEventListener("click", function (e) { //list for clcik on body
var clicked = e.target; //get what was clicked on
if (e.target.classList.contains("spoil")) { //see if it is an element with the class
e.target.classList.add("spoiled"); //if it is, add new class
}
});
.spoil { color: red }
.spoiled { color: green }
This is a text with <span class="spoil">spoil data</span>.
<br>
<span class="spoil">Unspoil me.</span>
<br>
<span class="spoil">And me.</span>
function unspoil() {
this.className = "spoiled"; // "this" is the clicked object
}
window.onload = function() {
var spoilers = document.querySelectorAll(".spoil"); // get all with class spoil
for (var i = 0; i < spoilers.length; i++) {
spoilers[i].onclick = unspoil;
}
}
span.spoil {
background-color: black;
}
span.spoiled {
background-color: white;
}
This is a text with <span class="spoil">spoil data</span>.
<br>
<span class="spoil">Unspoil me.</span>
<br>
<span class="spoil">And me.</span>
An additional approach could be to add the click-listener to the document and evaluate the event target:
document.addEventListener("click", function(e){
if (e.target.className == "spoil"){
e.target.className = "spoiled";
}
});
That way
you only need one event listener in the whole page
you can also append other elements dynamically with that class without the need for a new event handler
This should work, because the event's target is always the actual element being clicked. If you have sub-elements in your "spoil" items, you may need to traverse up the parent chain. But anyway I think this is the least resource-wasting way.
var spoilers = document.getElementsByClassName('spoil');
for(i=0;i<spoilers.length;i++){
spoilers[i].addEventListener('click',function(){
this.className = "spoiled";
});
}

Bind methods on appended elements

I have an AgentClass with the method this.move. It's working with static objects but when I create new HTML Objects via .append(), I can't use them with my this.move method.
All the new objects have an ID and I want to animate them with the move method.
I often read "live, on, ..." but they all need an event... I don't have such an event on them. They move directly. I tried something like that:
$('.agents').on("load", Agent.move());
But that isn't working... Any ideas?
Codesinppet:
var Agent = function(agentType, xTarget, yTarget) {
...
this.move = function() {
var id = this.agentId;
$('.agent#'+id).animate({
left:"200px"
}, 1000);
}
}
And I append them after this like this:
for (deployed = 0; deployed <= agents; deployed++) {
$('.agents').append('<div class="agent" id="'+deployed+'"></div>');
}
It would be awesome if someone could help me!?
You can use .clone(true)
A Boolean indicating whether event handlers and data should be copied along with the elements. The default value is false.
var agents = 6;
for (deployed = 0; deployed <= agents; deployed++) {
$element = $('<div class="agent" id="'+deployed+'"></div>').clone(true);
$('.agents').append($element);
}
.agent {
height:50px;
width:50px;
background-color:yellow;
margin-bottom:10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Agent</title>
</head>
<body>
<div class="agents">
</div>
</body>
</html>
But for maximum optimization event is better to use an event handler "on" to monitor the items that will be added after reloading the DOM .
This allocates less memory

Conditionally blink text

Can anyone let me know how can i make it blink text based on if statement?
Sample:
if value 0 - NO BLINK
If not 0 - Should blink
Thank you in advance
I think you mean $('.blink'), assuming you mean a class and not a tag name.
<script type="text/javascript">
setInterval(function(){
$('.blink').each(function(){
$(this).css('visibility' , $(this).css('visibility') === 'hidden' ? '' : 'hidden')
});
}, 250);
</script>
JSFiddle test
You don't need the inline style, Since you are using jQuery, toggle will help you doing this. you can simply do it in this way.
Here is demo:
setInterval(function(){
$('.blink').toggle();
}, 250);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class='blink'>Hello!</div>
<div class="blink">Testing again.</div>
See this fiddle.
http://jsfiddle.net/tcy6a5kz/
//Line 21
if (blinkStatus == 1) {
Blinker.start();
}
else {
Blinker.stop();
}
At this line, you can change the if statement to whatever you want (true-like or false-like value).
You can get the span value like this:
// This will return the inner text of the span
// I expect this text as 0 or more. (number or text)
// No text in the span == 0
$('span.top-title').val();
So you can change my code at line 21:
//Line 21
if ($('span.top-title').val() == 1) {
Blinker.start();
}
else {
Blinker.stop();
}
NOTE: You need jQuery included to your site to run this code. Everything starting with '$' is jQuery object and cannot operate without jQuery library.
In case you do not have jQuery. You can include it in your HTML:
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
This script must be included before the scripts that uses jQuery. (in most cases it's included at the <head> tag of the HTML. I'm not sure, but I think the "blog service providers" ignoring script definitions in the blog posts.
I know this is too old, but it might help someone searching for this.
I figure it out myself and I know that this is not the best solution.
<div class="blink1">
<span><asp:Label runat="server" Text="Label" ID="inprogress"></asp:Label></span>
</div>
<div class="blink2"><span><asp:Label runat="server" Text="Label" ID="behindsched"></asp:Label></span>
</div>
<script>
var in_progress = parseInt(documentElementById("<%=inprogress.ClientID%>").innerHTML);
var behind_sched = parseInt(documentElementById("<%=behindsched.ClientID%>").innerHTML);
var blinkfunc1 = function(){
$('.blink1').toggle();
}
var blinkfunc2 = function(){
$('.blink2').toggle();
}
var blinkspeed = 550;
$(document).ready(function{
if(in_progress > 0){
setInterval(blinkfunc1, blinkspeed);
}
if(behind_sched > 0){
setInterval(blinkfunc2, blinkspeed);
}
});
</script>
Make sure you don't forget this into your head tag
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Changing a javascript variable inside a DIV using JQuery

Firstly - i'm not even sure if the syntax is correct, but what i'm trying to do is, i have a div showing an animated image sequence which picks a position using a variable.
I will eventually use JSON to feed the value being changed, but for now i'm just trying to understand how to use JQuery to change the variable. Here's the code:
<div id="noiseAnimDiv" style="float: center; background-color: #ffffff; ">
<script type="text/javascript" src="./animatedpng.js">
</script>
<script type="text/javascript">
var stoptheClock = 3;
noiseAnim = new AnimatedPNG('noise', './noise/noise0.png', 8, 50);
noiseAnim.draw(false);
noiseAnim.setFrameDelay(stoptheClock, 1000); //spin yet stay on value 3
</script>
</div>
<script type="text/javascript" src="//code.jquery.com/jquery-1.10.2.js"></script>
<script>
$(document).ready(
function() {
$("#stoptheClock").val(6); //
}
);
</script>
Any help much appreciated
code is live btw at so you can at least see the animation seq
http://ashleyjamesbrown.com/fgbp/noise.htm
The AnimatedPNG library you are using only checks the variable's value once - when initialized. in your code, you are changing the value after initializing it.
$(document).ready(
function() {
$("#stoptheClock").val(6); //
}
);
Should be
function() {
stoptheClock = 6;
noiseAnim.draw(false);
noiseAnim.setFrameDelay(stoptheClock,1000);
}
You are not using JQuery for any useful cause in your code, therefore I have removed all of the Jquery parts.

Categories