.contains() return false in Internet Explorer - javascript

This code return false in Internet Explorer. Any alternative?
<!DOCTYPE html>
<html>
<head>
<style>
#myDIV {
border: 1px solid black;
}
</style>
</head>
<body>
<div id="myDIV">
<p>I am a p element inside div, and I have a <span id="mySPAN">span</span> element inside of me.</p>
</div>
<p>I am a p element inside div, and I have a <span id="mySPAN">span</span> element inside</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function myFunction() {
var span = document.getElementById("mySPAN");
var text = span.childNodes[0];
var div = document.getElementById("myDIV").contains(text);
document.getElementById("demo").innerHTML = div;
}
</script>
</body>
</html>
I want to check whether the div element contains the selected range:
function getRange(root): Range {
const sel = window.getSelection();
const range = sel.getRangeAt(0);
if (range && range.commonAncestorContainer !== root && root.contains(range.commonAncestorContainer)) {
return range.cloneRange();
}
return null;
}
I want to check whether the div element contains the selected range:
Current behavior in internet explorer:

You don't need child Node.
Because the DOM contains check the full DOM not the Node Child. Please try this below function instead of yours. And it is working!
<script>
function myFunction() {
var span = document.getElementById("mySPAN");
var div = document.getElementById("myDIV").contains(span);
document.getElementById("demo").innerHTML = div;
}
</script>
DEMO: https://www.w3schools.com/code/tryit.asp?filename=FQFMFOKPLHO3

Related

Highlight matched text

I want to implement highlight feature of Notepad++ in HTML, where notepad++ highlights selected words if found in the file. I have been able to mimic a bit only where the highlight happens only on a mouse click in the same div.
I want to change it so the highlight happens in div2 when text is selected in div1 and is found in div2, else div2 is same as div1. Also it should work except any mouse click and with multi words.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>highlight matching text</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
.found {
color: red;
}
</style>
<script>
function replaceText() {
$("#div1").find(".found").removeClass("found");
var searchword = $("#searchtxt").val();
var custfilter = new RegExp(searchword, "ig");
var repstr = "<span class='found'>" + searchword + "</span>";
if (searchword != "") {
$('#div1').each(function() {
$(this).html($(this).html().replace(custfilter, repstr));
})
}
}
</script>
</head>
<body>
<input type="text" id="searchtxt" placeholder="keyword" />
<input type="button" value="search" onClick="replaceText();" id="highlightButton" />
<p id="div1">I'm here but not here. Not here also. But I'm here too.</p>
<p id="div2"> </p>
</body>
</html>
Try this:
const div1 = document.getElementById("div1"),
div2 = document.getElementById("div2"),
isParent = (obj, parent) => !obj || obj === parent ? obj : isParent(obj.parentNode, parent);
/*
isParent is a short version of:
function isParent(obj, parent)
{
if (!obj || obj === parent)
{
return obj;
}
else
{
return isParent(obj.parentNode, parent);
}
}
*/
div1.addEventListener("click", e =>
{
const sel = document.getSelection();
/*
sel.anchorNode: element the selection started at
sel.focusNode: element the selection ended at
we only accept selection of div1 text
check if both of these elements are children of div1, otherwise exit
*/
if (!isParent(sel.anchorNode, div1) || !isParent(sel.focusNode, div1))
return;
const text = sel.toString() //get selected text
.trim() //trim trailing white spaces
//make it html friendly
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
//make it regex friendly
.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
if (text === "")
return;
div2.innerHTML = div2.innerHTML
//remove old highlightings
.replace(/<mark>([^<]*)?<\/mark>/g, "$1")
// convert selected text into regex,
// search and enclose found strings with <mark></mark>
.replace(new RegExp("(" + text + ")", "gi"), '<mark>$1</mark>'); //add new highlighting
});
/*
second paragraph marks
*/
p:first-child + p mark {
background-color: lightgreen;
}
#div1, #div2
{
border: 1px solid black;
padding: 1em;
}
#div2
{
background-color: #E0E0E0;
margin-top: -1px;
}
<div id="div1">
<p>I'm here but not here. Not here also. But I'm here too. <span>blah</span></p>
</div>
<div id="div2">
<p>But I'm here too. <span>blah</span> <span>blah</span></p>
<p>And also here.</p>
<p>Third paragraph, has "And also here."</p>
</div>

how to avoid rewriting java script code?

I am looking for a way to avoid rewriting the same code again and again.
I am making a web page that has divs with hide and show option, with the help of a button you toggle between hide and show. I found an easy way to achieve the effect with this code:
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<p>Click the "Try it" button to toggle between hiding and showing the DIV element:</p>
<button onclick="myFunction()">Try it</button>
<div id="myDIV">
This is my DIV element.
</div>
<p><b>Note:</b> The element will not take up any space when the display property set to "none".</p>
This works perfectly but gets a bit tedious when you have a dozen or more divs with said effect. Is there a way to avoid having to rewrite the function for each and every div?
Thank you! :)
Easy, parameterize the id:
function myFunction(divId) {
var x = document.getElementById(divId);
and in the HTML pass the id to the function:
<button onclick="myFunction('myDIV')">Try it</button>
<div id="myDIV"> ...</div>
<button onclick="myFunction('myOtherDIV')">Try it</button>
<div id="myOtherDIV"> ...</div>
... and so on ...
You can keep one single function and handle as many divs as you want.
You could run the javascript function with a parameter. So you only have one function and then you only need to change the parameter name. See the example below.
function myFunction(div) {
var x = document.getElementById(div);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<body>
<p>Click the "Try it" button to toggle between hiding and showing the DIV element:</p>
<button onclick="myFunction('myDIV')">Try it</button>
<button onclick="myFunction('myDIV2')">Try it2</button>
<div id="myDIV">
This is my DIV element.
</div>
<div id="myDIV2">
This is my DIV2 element.
</div>
<p><b>Note:</b> The element will not take up any space when the display property set to "none".</p>
</body>
Just pass the div id to a function
function toggleDiv(divId) {
var x = document.getElementById(divId);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
This works perfectly but gets a bit tedious when you have a dozen or
more divs with said effect
Create an array of such div ids to be toggled and iterate the same, for example
var divIds = ["myDIV1", "myDIV2", "myDIV3"];
divIds.forEach( s => toggleDiv(s) );
Pass a parameter into the function.
function myFunction(divName) {
var x = document.getElementById(divName);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<body>
<p>Click the "Try it" button to toggle between hiding and showing the DIV element:</p>
<button onclick="myFunction('myDIV')">Try it</button>
<div id="myDIV">
This is my DIV element.
</div>
<button onclick="myFunction('myDIV2')">Try it</button>
<div id="myDIV2">
This is my DIV2 element.
</div>
<p><b>Note:</b> The element will not take up any space when the display property set to "none".</p>
</body>
using event target and operating relatively on elements, can do the task.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<p>Click the "Try it" button to toggle between hiding and showing the DIV element:</p>
<hr>
<div class="wrapper">
<button onclick="myFunction(event)">Try first</button>
<div class="content">
This is my DIV element.
</div>
</div>
<hr>
<div class="wrapper">
<button onclick="myFunction(event)">Try second</button>
<div class="content">
This is my DIV element.
</div>
</div>
<hr>
<p><b>Note:</b> The element will not take up any space when the display property set to "none".</p>
<script>
function myFunction(event) {
var wrapper = event.target.parentElement;
var content = wrapper.querySelector('.content');
if (content.style.display === "none") {
content.style.display = "block";
} else {
content.style.display = "none";
}
}
</script>
</body>
</html>
function myFunction() {
var x = document.getElementsByClassName("myDIV");
for (let i = 0; i < x.length; i++){
x[i].style.display = x[i].style.display == "none" ? "block" : "none";
}
}
<body>
<p>Click the "Try it" button to toggle between hiding and showing the DIV element:</p>
<button onclick="myFunction()">Try it</button>
<div class="myDIV">
This is my DIV element.
</div>
<div class="myDIV">
This is my DIV element.
</div>
<div class="myDIV">
This is my DIV element.
</div>
<p><b>Note:</b> The element will not take up any space when the display property set to "none".</p>
</body>
function toggleVisibility(selector) {
const elements = document.querySelectorAll(selector);
elements.forEach( element => {
const isVisible = element.offsetHeight;
if (isVisible) {
element.setAttribute('hidden', '');
} else {
element.removeAttribute('hidden');
}
});
}
<button onclick="toggleVisibility('#myDIV')">Try it</button>
<button onclick="toggleVisibility('.toggle')">Try it with className</button>
<div id="myDIV">
This is my DIV element.
</div>
<div class="toggle">
This is my DIV element.
</div>
<div class="toggle">
This is my DIV element.
</div>

Broken Javascript Code

I'm trying to create a website where three things happen, but I am stuck.
(1) When the button “ADD” button is clicked it will create a new paragraph
and add it to the output. The contents of the paragraph should come from the text area that is below the [ADD] button.
(2) If the “delete” button is pressed I need to delete the first paragraph in the div.
(3) If the user tries to delete when there are no paragraphs, create an “alert" that says:"No Paragraphs to delete".
I got my JS to put each paragraph into the div, but I'm not really sure how to delete it... Any help would be much appreciated.
window.onload = function() {
var button = document.getElementById("add");
button.onclick = insertItem;
}
function insertItem() {
var added = document.getElementById("output");
var textToAdd = document.getElementById("input");
if (textToAdd.value != "") {
var newp = document.createElement("p");
newp.innerHTML = textToAdd.value;
added.appendChild(newp);
}
}
var deletebutton = document.getElementsByTagName("delete");
deletebutton.onclick = deleteItem;
function deleteItem() {
var output = document.getElementById("output");
var pars = output.getElementsByTagName("p");
if (pars.length > 0) {
output.removeChild(pars[0]);
}
}
#output {
border: blue 5px solid;
padding: 10px;
margin-bottom: 10px;
margin-top: 10px;
width: 50%;
}
#output p {
padding: 10px;
border: black 1px dashed;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js" type="text/javascript"></script>
<script src="task3.js"></script>
</head>
<body>
<h2> TASK 3 - Creating, Appending and Deleting Nodes in the DOM Tree </h2>
<p> Type in text below, click add to add as paragraph. <button id="add"> Add </button> </p>
<textarea id="input" rows="10" cols="60">
</textarea><br>
<button id="delete">Delete Last Paragraph</button>
<br><br>
<h2> Added Paragraphs </h2>
<div id="output">
</div>
</body>
</html>
You're fetching the delete button wrong. You're using getElementsByTagName instead of by id.
When deleting, you will probably delete the first <p> you have in your markup that doesnt belong to your output. To fix this you could simply fetch all children of your output div and remove the first one:
function deleteItem() {
let output = document.getElementById('output')
if (output.hasChildNodes()) {
let outputs = output.childNodes
outputs[0].remove()
}
}

How to apply css to overflow:hidden elements?

here i want to apply some css to those divs are not visible because if its height. So i want to apply some css dynamically which are not showing here(sanjana, giri, santhosh divs)
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div style="height:100px;overflow:hidden;background:red;border:2px dashed #000;">
<div>Ganesh</div>
<div>Om shankar</div>
<div>Sai</div>
<div>venkat</div>
<div>Sireesha</div>
<div>Sanjana</div>
<div>Giri</div>
<div>Santhosh</div>
</div>
</body>
</html>
If it's inline defined, you can use this:
[style*="overflow:hidden;"],[style*="overflow: hidden;"]
What it does is looking for ANY type of tag,
that has a style attribute set
and that style attribute contains: overflow:hidden; or overflow: hidden;
then applies relevant styles.
var value = 'initial';
var old = 'hidden';
function toggle() {
$('div[style]').css({'overflow':value});
var tmp = value;
value = old;
old = tmp;
}
[style*="overflow:hidden;"],[style*="overflow: hidden;"] {
color:white;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<input type="button" onclick="toggle()" value="toggle values">
<div style="height:100px;overflow:hidden;background:red;border:2px dashed #000;">
<div>Ganesh</div>
<div>Om shankar</div>
<div>Sai</div>
<div>venkat</div>
<div>Sireesha</div>
<div>Sanjana</div>
<div>Giri</div>
<div>Santhosh</div>
</div>
</body>
</html>
Now if you only wish to do something to the NOT visible divs, you need to use javascript, and you can use Bounding boxes to test if something is visible:
Also see How to check if an element is overlapping other elements?
$('[style*="overflow:hidden"],[style*="overflow: hidden;"]').children().each(function(index, element) {
var $el = $(element);
var $parent = $el.parent();
// get the bounding boxes.
var rect1 = $parent.get(0).getBoundingClientRect();
var rect2 = element.getBoundingClientRect();
// check for overlap(if it's visible)
if(!(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)) {
$el.removeClass('hidden');
}
else {
// it's hidden!
console.log('found hidden div '+$el.text());
$el.addClass("hidden");
}
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div style="height:100px;overflow:hidden;background:red;border:2px dashed #000;">
<div>Ganesh</div>
<div>Om shankar</div>
<div>Sai</div>
<div>venkat</div>
<div>Sireesha</div>
<div>Sanjana</div>
<div>Giri</div>
<div>Santhosh</div>
</div>
</body>
</html>
You can check the height from the wrapper via javascript and then add a class to all the elements which are not fully visible inside the wrapper. Added a class wrap to the wrapper to make it more obvious.
var wrap = document.querySelector('.wrap');
var wrapHeight = wrap.offsetHeight; // just in case it's not known and set by CSS
wrap.querySelectorAll('div').forEach(function(element){
var elementBottomPosition = element.offsetTop + element.offsetHeight;
if(elementBottomPosition >= wrapHeight) {
element.classList.add('some-class');
}
});
.wrap {
height:100px;
overflow:hidden;
background:red;
border:2px dashed #000;
}
.some-class {
color: lime;
}
<div class="wrap">
<div>Ganesh</div>
<div>Om shankar</div>
<div>Sai</div>
<div>venkat</div>
<div>Sireesha</div>
<div>Sanjana</div>
<div>Giri</div>
<div>Santhosh</div>
</div>

trigger onmouseup element correctly

I have following html structure:
<div id="grandparent">
<div id="parent">
<p>
high light me with mouse!! highlight me with mouse!!highlight me with mouse!!
</p>
</div>
</div>
And I have this js code:
$(document).mouseup(function (event) {
var target=event.target;
target=$(target);
var parent = target.parent();
console.log(parent.parent().attr("id"));
if (window.getSelection) {
var selection = window.getSelection();
selectedText = selection.toString();
console.log(selectedText);
}
});
So this piece of code just console logs selected text.
But I have a problem - when I click not on my <p> element and just on document - and then I move mouse to select text holding left button I can't get the id of parent div because
var target=event.target;
target becomes document element
Change $(document).mouseup( for $("#parent").mouseup( .
Code:
$("#parent").mouseup(function (event) {
var target=event.target;
target=$(target);
var parent = target.parent();
console.log(parent.parent().attr("id"));
if (window.getSelection) {
var selection = window.getSelection();
selectedText = selection.toString();
console.log(selectedText);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="grandparent">
<div id="parent">
<p>
high light me with mouse!! highlight me with mouse!!highlight me with mouse!!
</p>
</div>
</div>

Categories