Find and Replace all instances of a word with jquery - javascript

I have an article with many instances of the word "color". I set up a button with the class .colour so that if you want you can click it and change the spelling from "color" to "colour" throughout the page. I've written some jQuery to do this but it only changes one instance of the word color but not all. You'd have to keep repeatedly clicking the button to change all of them.
$(document).ready(function(){
$(".colour").click(function(){
$("body").children().each(function() {
$(this).html($(this).html().replace("color","colour"));
});
})
})
Is there a way to repeatedly loop the script until it changes all instances? Also is it possible to make it so it is not case-sensitive? I'm new to javascript and jquery so might be a noob question. Thanks
Here's a codepen of it: http://codepen.io/patrickaltair/pen/vcdmy

Have your replace use a regex with a global replace.
Change:
$(this).html().replace("color","colour")
to:
$(this).html().replace(/color/g,"colour");
codepen example

I for one am not a big fan of using .html() in such cases, so
$(document).ready(function(){
$(".colour").click(function(){
$("body *").contents().each(function() {
if(this.nodeType==3){
this.nodeValue = this.nodeValue.replace(/color/g, 'colour')
}
});
})
})
h2.colour, h2.color{
font-size:16px;
max-width: 200px;
margin: 1em auto;
text-align: center;
padding:0.4em;
color: #999;
background-color: #ccc;
#include border-top-radius(5px);
#include border-bottom-radius(5px);
#include transition (all 0.3s ease-in-out);
}
h2.colour:hover, h2.color:hover{
color: #000;
background-color: #aaa;
}
p{
max-width: 400px;
margin: 1em auto;
margin-top: 5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="text">
Seasonal Colors: Some colors are more appropriate at certain times of year than others. Pastels are usually associated with spring/summer, while autumn colors are rust, <span style="color:brown">brown</span>, <span style="color:green">green</span>, and <span style="color:firebrick">burgundy</span>. Wearing rust in the summer, or light yellow in the fall looks out of place. That color's place in society. Second lower case color.
</p>
<h2 class="colour">Colour</h2>
2 problems I see when using .html() are
It will replace the dom which means any event handlers/jQuery data attached to those elements will be lost
It will replace attributes also which may not be what you want. Notice that I added some color to your text but it's not lost after replacing "color" with "colour"

find all and replace
$(this).html().split('color').join("colour");

Use this:
Global search in string
str = str.replace(/find/g,”replace”);
Or global and case-insensitive search in string
str = str.replace(/find/gi,”replace”);

Related

How to create a jQuery function to toggle dark mode?

I'm designing a dark mode for my website. Given I have a lot of written content, that would be especially helpful for evening reading. I have a toggle and have borrowed a function that seems to work so far:
$(function() {
$(".switch").click(function() {
$("#canvas-wrapper").css("background", "#222");
$("p").css("color", "#DDD");
});
});
I want the user to toggle these changes on and off as desired. However, when I attempt to add another line - defining a css change for another element - the function only applies the style to the first #canvas-wrapper element. Everything thereafter is ignored.
Is my syntax incorrect later in the function? Also, I need to write the function in a way that returns the CSS to its original state, should the user deactivate the toggle. How would I approach this?
I'm quite poor with jQuery and haven't had a ton of experience with the language.
Instead of changing every single element, you can define the dark mode styles in your CSS, and just use jQuery to toggle the dark-mode class.
I'm assuming clicking the .switch twice would change it back to light mode, and that your current CSS shows the light mode styles by default.
CSS:
#canvas-wrapper.dark-mode {
background: #222;
color: #DDD;
}
jQuery:
$(function() {
$(".switch").click(function() {
$("#canvas-wrapper").toggleClass("dark-mode");
});
});
If you like, you can use CSS variables as well. However, it would still involve class toggling/changing somewhere in your code. Using CSS variables but using vanilla JS: https://dev.to/ananyaneogi/create-a-dark-light-mode-switch-with-css-variables-34l8
you may have to write some css for each element whether its in light or dark mode. use javascript to toggle between the two. You can have a class for light mode (.light-mode) then one for dark mode. as long as class-wrapper is a div you should be ok.
I would use a js variable with global access for the mode and tie that into a function.
css
.light-mode{
some more css classes for light mode
}
.dark-mode{
some more css classes for dark mode
}
You need to use css with a target class. Jquery toggleClass() will do the job
.bgDark{background: #4a4a4a !important;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="myDiv" class="" style="background: #fff393; border: 1px solid black; width: 100px; height: 100px"></div>
<button onclick="$('#myDiv').toggleClass('bgDark')">toggle bg</button>
You can resolve this issue by doing some tricks, direct answer for your question is by implement toggleClass for dark/light theme.
for example you look to this demo
<div class="change-color">
<p>Hello World</p>
</div>
<div class="change-color">
<p>Hello World 2</p>
</div>
<button>Change color</button>
and our script:
// find elements
var anotherColor = $(".change-color")
var button = $("button")
// handle click and add class
button.on("click", function(){
anotherColor.toggleClass("another-color")
})
and our style:
body {
background: #000;
color: red;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
.another-color {
background: #ddd;
}
But you can resolve issue too by using root variable color, for example:
:root {
--color-bg: #000;
}
.default-color {
background-color: var(--color-bg);
}
.another-color {
--color-bg: #ddd;
}
You can look to this demo too

jQuery.insertBefore is not respecting the line break

I have a simple html with a div limited by width. Inside I have many span tags that are configured with nowrap. My css:
.content {
width: 50%;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.adder {
color: blue;
cursor: pointer;
}
.added {
position: relative;
white-space: nowrap;
}
And my html:
<div class="content">
<span class="added">A text just a little large 1.</span>
<span class="added">A text just a little large 2.</span>
<span class="added">A text just a little large 3.</span>
<span class="added">A text just a little large 4.</span>
<span class="added">A text just a little large 5.</span>
<span class="adder">Add</span>
</div>
As expected, the text is broken when there is no more space in the line to be placed. Then the entire span is rendered on the next line. Now I added some javascript code:
$(function() {
$(".adder").click(function() {
$(document.createElement("span"))
.addClass("added")
.html("A custom text to be add,")
.insertBefore(this);
});
});
So, now a new span is placed before the Add text for every time I click on Add.
But the problem is this, when I click a few more times in the Add, there comes a point where the end of the line size is reached, but rather to break the line as the other part of the text does, the new span is simply rendered in the same line overlapping the edge of the div.
Why this happen? How to avoid it?
I'm testing this page in Google Chrome 42.0.2311.135.
The whole html can be viewed in jsfinddle.
Your original list of "added" <span> elements have whitespace between them. The ones you add with the JavaScript code don't. Therefore, the browser can't insert line breaks between them — it will only do that at whitespace boundaries.
You can fix that in a few different ways; one simple way is to add this to your "click" handler:
$("<span/>", { text: " " }).insertBefore(this);
Another way to fix it is with pure CSS:
.added::after {
white-space: normal;
content: "\00200B";
}
No JavaScript changes would be necessary with that approach.
When you use insertBefore there is no space added between yoru elements. Simply add a space yourself and they will wrap as you expect:
$(function() {
$(".adder").click(function() {
$(document.createElement("span"))
.addClass("added")
.html("A custom text to be add,")
.insertBefore(this)
.after(" "); // add a single space
});
});
http://jsfiddle.net/gtoh8hzp/

How can I insert a whole css class before an HTML element that I find?

I need to insert an image before an element I am trying to find in this code (also I am trying to add the class in the same function).
The js:
insertSearchIcon: function(){
$(document).find('jstree-icon').prepend('<div class="oob-dropdown">test</div>');
}
And the css class I am trying to insert.
.oob-dropdown {
background-image: url("/apps/cdpe/img/search_444444.png");
background-color: transparent;
background-repeat: no-repeat;
height: 25px;
width: 25px;
border: none;
padding-top: 1cm;
position: relative;
}
Hopefully what I am trying to do is possible, but thanks for any help!
you probably missed the . in your selector find('jstree-icon') and secondly prepend() adds another item before the first child element of the matched selector.
To add another element right before another you might be interested in before:
$('.jstree-icon').before('<div class="oob-dropdown">test</div>');
Btw: $(document).find() is probably not best practice, rather use the selector directly!
.prepend() inserts an element as the first child of another; it sounds like you need .before(). Your selector also needs a dot (assuming jstree-icon is a class).
$('.jstree-icon').before('<div class="oob-dropdown">test</div>');

How to find all css classes and its css attributes inside a certain div?

i would like to find all classes and ids inside a certain div ! and these css attributes!
Example :
<div class="demo">
<div class="new_class">
<p id="para">This is Demo Paragraph</p>
<a style="background:#ccc">HyperLink</a>
</div>
</div>
<style>
.demo{
height:100px; width:100px; background:#FF0;
}
.new_class{height:40px; width:40px; background:#999;}
#para{color:#E1E1E1;}
</style>
Now The question is that: i would like to find all classes and ids which are used inside demo class ! and Their css values too(which style applying now. ).
I would like to find result as below :
<style>
.demo{
height:100px; width:100px; background:#FF0;
}
.new_class{height:40px; width:40px; background:#999;}
#para{color:#E1E1E1;}
a{background:#ccc;}
</style>
OP, not sure what your purpose is, but in general, this can be useful. I had a project where I needed to embed a fancy template from one site onto a page on a different site with a very different, and conflicting stylesheet. I used some code similar to the following to grab every applied style from the original content, via document.styleSheets, then reapplied them all as inline styles, so I could put it onto the "parent" site without the stylesheets conflicting.
Fiddle
JS
var selector,rule;
var result=[];
var sheets = document.styleSheets;
for (var i in sheets) {
//rules or cssRules, depending on the browser
var rules = sheets[i].rules || sheets[i].cssRules;
//iterate over every css rule in the document
for (var r in rules)
{
selector=rules[r].selectorText;
rule=rules[r].cssText;
//select demo itself, as well as all of its children
$('.demo, .demo *').each(function () {
//console.log($(this),selector);
//for each element, see if it matches the current rule. add if it does
if ($(this).is(selector))
{
result.push(rule);
}
});
}
}
console.log(result);
//result[0] .demo { height: 100px; width: 100px; background: none repeat scroll 0% 0% rgb(255, 255, 0); }
//result[1] .new_class { height: 40px; width: 40px; background: none repeat scroll 0% 0% rgb(153, 153, 153); }
//result[2] #para { color: rgb(225, 225, 225); }
Granted, you will have to tweak this on your own to do things like, removing duplicate styles that would occur if you were to apply this to a larger block of HTML, and for dealing with inline styles (which this does not attempt to do, but you can get them from the style attribute and work from there...), and possibly the computed style, which you can get with getComputedStyle, as indicated by the #Derek's answer. but this should get you started.
To find all existing id, try:
var ids = [];
$(".demo *").each(function(){ this.id && ids.push(this.id); });
console.log(ids);
Do the same thing for class or anything else.
However, to get your expected output, you must first acquire the defined CSS style for each element. Which one should be included? p by default gets margins and paddings. Do you include those too? You will also need to dig into all the CSS declarations just to find the style that are applied, which is almost impossible to do.
For example,
<div class="yellow"></div>
<style>
div.yellow:not(.blue){
background: yellow;
}
</style>
How do you get the background of the <div> tag? .style.background? Nah, it returns "". Well now you will have to reach into the CSS declaration with document.styleSheets to see which one applied. How do you even check if the rule div.yellow:not(.blue) matches your element? Good luck doing that. (There might be libraries that does this kind of thing, or maybe you can even utilize jQuery's internal selector engine with .is, though it will not be the same as in CSS) Another thing you can do is try getComputedStyle. It gives you every single computed styles that aren't even in your declaration. So what you are trying to do is not possible to do. (I don't even know what you are doing something like this.)

Jquery: Target part of a text node on a second line

I don't know if this is possible. I have an h2 tag with some text:
<div>
<h2>Here Goes a Big Sample Slider</h2>
</div>
It is a big font in a short width div.
h2{
font-size: 69px
}
div{
width: 600px;
}
So it breaks up into 2 lines. Here is a JSfiddle: http://jsfiddle.net/6Qypv/
I would like to always target the second line in the sentence, no matter what the sentence is(It will be user generated), so I can wrap it in a span and give it some properties. I cannot change the HTML directly, though.
Thank you
You could try using the :first-line pseudo-element to do something like:
h2:first-line { /* Normal style */
font-size: 69px
}
h2 { /* Second line */
font-size:13px;
}
Sample fiddle

Categories

Resources