How do I replace html elements using JavaScript? - javascript

I have spent around 3 hours today trying to replace an html element on a page using JavaScript.
I have tried many things and haven't had much success.
For example, if I wanted to replace code snippet 1 with the code snippet 2, how would that be done?
I have tried
document.getElementById('wide-left').innerHTML="(code snippet 1)";
but it just throws an error.
Sorry if I didn't explain this clear enough, I tried my best.
Any help would be greatly appreciated.
Code snippet 1
<h4 id="select-head">Select</h4>
<h4 id="summary-head">Summary</h4>
</div>
Code snippet 2
<div class="col9 single-product" id="wide-left">
<div class="product-name hidden-lg">
<h2><span>Reebok Ventilator x Mita</span> <em class="stockcode"><span>M48281</span></em></h2>
</div>
<!-- end of .product-name -->
<div class="row unexpanded" id="product-info">
<div class="col4 product-pic-width">

I'll try to illustrate the basics for modifying HTML using the snippet tool here:
var snip1 = document.getElementById("snip1"),
snip2 = document.getElementById("snip2");
setTimeout(function() {
snip1.innerHTML = snip2.innerHTML;
}, 1000); // This code copies the HTML from within snip2 to snip1.
setTimeout(function() {
snip2.innerHTML = "";
}, 2000); // This code clears snip2.
setTimeout(function() {
snip1.getElementsByTagName("span")[0].style.color = "blue";
}, 3000); // This code changes the CSS for <span> within snip1.
setTimeout(function() {
snip2.textContent = snip1.innerHTML
}, 4000); // This code copies the HTML from snip1 as text into snip2.
<div>
Here is some <span id="snip1"></span> content!
</div>
<div>
Here is some <span id="snip2"><span style="color:red">more</span></span>content!
</div>

Try to edit the elements after the document object model ("DOM") has loaded, otherwise you will encounter errors.
document.onload = function()
{
document.getElementById('wide-left').innerHTML = '<p>This is some HTML</p>';
}

Related

Getting Uncaught TypeError but link works fine

Although there are some questions similar, ive read it and cant solve my problem.
Hope someone direct some light on this in order to help not only me but others out there.
I have added JS file to my child theme (wordpress) via functions.php and then added Event listener to ID.
The problem inhabits on the :Uncaught TypeError: Cannot read property 'addEventListener' of null
at custom.js?ver=5.4:1
Although when i click the object it goes correctly to the link, the error shows on console.
on functions.php ive added:
function my_customm_scripts() {
wp_enqueue_script( 'custom-js', get_stylesheet_directory_uri() . '/custom.js', array( 'jquery' ),'',true );
}
add_action( 'wp_enqueue_scripts', 'my_customm_scripts' );
and in my custom.js ive added:
document.getElementById('hercule').addEventListener('click', function() {
location.href = 'https://somedomain.com'
}, false);
im shure its straightforward but ive checked so many solutions without success
Thx for your time
J.
<div class="hoverfora wpb_animate_when_almost_visible wpb_slideInUp slideInUp wpb_column vc_column_container vc_col-sm-4 wpb_start_animation animated" id="hercule">
<div class="vc_column-inner vc_custom_1587337223984">
<div class="wpb_wrapper">
<div class="service_table_holder">
<ul class="service_table_inner">
<li class="service_table_title_holder background_color_type" style="">
<div class="service_table_title_inner">
<div class="service_table_title_inner2">
<h3 class="service_title" style="">Web design</h3>
<i class="qode_icon_font_awesome fa fa-desktop fa-3x" style="color: #efcd21 !important;"></i>
</div>
</div>
</li>
<li class="service_table_content" style="">Development de websites .
<p></p>
</li>
</ul>
</div>
</div>
</div>
</div>
I think that is
window.location.href = 'https://somedomain.com'
Try this instead,
If you are sure that your html source contains the element with id="hercule". Then you can try
window.onload = function () {
document.getElementById('hercule').addEventListener('click', function() {
location.href = 'https://somedomain.com'
// alert("clicked div");
}, false);
};
Make sure that all your onload processes are written in a single place. Otherwise the browser will keep and execute only last found window.onload function.
This code of yours:
document.getElementById('hercule')
is looking for a DOM element with id="hercule". Apparently, your page does not contain such an element at the time the custom.js is being run, so document.getElementById('hercule') is returning null, then a TypeError is thrown when addEventListener method is called on a null object.
Look for an element on your HTML page that contains id="hercule". If you can't find it, your problem has been identified.
Edit:
Subsequent information reveals that the custom.js JavaScript is trying to access a div with id="hercule" before it exists. The solution is to delay the start of the custom function until the div exists.
Normally, waiting for the window's load event is sufficient, but it is unclear in this case that will work, as "hercule" may be generated by another JavaScript function that won't complete by the time of the load event.
One solution is simply to continue to look for "hercule" until it's found:
// USE THIS SECTION IN YOUR CODE:
// keep looking for "hercule"
function lookForHercule() {
const hercule = document.getElementById('hercule');
if (hercule) {
// add the 'click' listener to 'hercule'
hercule.addEventListener('click', function() {
hercule.innerHTML = "You clicked hercule, redirecting to somedomain.com";
location.href = 'https://somedomain.com'
}, false);
return;
}
console.log('"hercule" not found');
setTimeout(lookForHercule, 2000);
}
// start looking
lookForHercule();
// END OF SECTION TO USE IN YOUR CODE
// THE CODE BELOW IS FOR THIS DEMO ONLY, DO NOT USE IN YOUR CODE:
// FOR DEMO ONLY:
// add 'hercule' after 10 seconds to simulate delay
setTimeout(() => {
const wrapper = document.getElementById('wrapper');
const hercule = document.createElement('div');
hercule.id = 'hercule';
hercule.innerHTML = "I am hercule. Clicking me will redirect to somedomain.com";
wrapper.appendChild(hercule);
}, 10000);
/* this will change cursor to finger when hovering over hercule */
#hercule:hover {
cursor: pointer;
}
<div id="wrapper">
<h4>Search for 'hercule'</h4>
</div>

lazy loading images on scroll and "come into view"

I am using Lazy as a lazy image loading plugin. I have a div where I load divs like this:
<div class="nano-content" id="lScroll">
/*... MORE LIKE THIS ... */
<div class="card">
<div class="city-selected city-medium clickChampion pointer"
data-champ-id="1">
<article>
<div class="info">
<div class="city">
CHAMPNAME
</div>
</div>
</article>
<figure class="cFigure lazy" data-src="images/champions/CHAMPNAME_0.png"></figure>
</div>
</div>
/*... MORE LIKE THIS ... */
</div>
So I initiate the plugin and it works for the first ones visible and when I scroll:
var $lazy = $('#lScroll .lazy');
if ($lazy.length) {
$lazy.Lazy({
appendScroll: $('#lScroll')
});
}
But now I have a function that "filters" the divs by their attributes when I enter sth in my search input and it fails to load the image when the according div is shown:
$(document).on("keyup", "#searchVod", function () {
var $search = $(this);
var $sVal = $search.val().toLowerCase();
if ($sVal !== "") {
$(".vodCard").hide();
$('[data-champ*="' + $sVal + '"]').show();
$('[data-role*="' + $sVal + '"]').show();
} else {
$(".vodCard").show();
}
});
I tried bind: "event" /w and w/out delay: 0 (loading the plugin in the search function) but when I searched it would load ALL images immediately in the background.
Any hint highly appreciated
UPDATE: I just noticed in Chrome DevTab after entering one letter in my searchbox it loads ALL the images and eventually the one I am searching for (if its the last it takes some time (30MB sth)
There is an excellent library called Lozad.js which can help you to make it easier to load your images like lazy load do but in easier way.
You can download it here from Github.
Demo page here.
Explanation:
This library will load your images one by one on scrolling to each image anchor by class name.
Example
HTML:
At the header ->
<script src="https://cdn.jsdelivr.net/npm/lozad"></script>
Image element should looks like this:
<img class="lozad" data-src="image.png">
Javascript
// Initialize library
lozad('.lozad', {
load: function(el) {
el.src = el.dataset.src;
el.onload = function() {
el.classList.add('fade')
}
}
}).observe()
Hope it will help you.
Best,
Ido.

.replaceWith messes up the script

For learning reasons, I build my own link shortener and yeah...
After 5 Seconds this code
<div class="skip-container">
<p class="five">SKIP IN 5 SECONDS</p>
</div>
should be replaced with
<div class="skip-button">
SKIP THIS AD
<div class="skip-arrow"></div>
</div>
to do that I tried
$( document ).ready(function test() {
setTimeout(function test() {
$("p.five").replaceWith('<div class="skip-button">
SKIP THIS AD
<div class="skip-arrow"></div> </div> ');
}, 5000);
});
It changed the script, but it looks broken and not like how it should... I read something about it keeps it in DOM and such stuff, but I am new in all that and yeah... https://viid.su/bBwgN is the problem page!
You either need to concatenate the string down, or escape the new lines:
$(function() {
setTimeout(function() {
$("p.five").replaceWith('<div class="skip-button">\
SKIP THIS AD\
<div class="skip-arrow"></div>\
</div> ');
}, 5000);
});

Polymer autogrow textarea focus() not working

I am using polymer's iron-autogrow-textarea. I was able to set the autofocus attribute and its working perfectly fine.
But when I try to set the focus back to textarea it doesn't seem to work.
I have tried
autoTextArea.focus();
It didn't work
setTimeout(function() {
$('#autoTextArea')[0].focus();
}, 1000);
This didn't work
setTimeout(function() {
$('#autoTextArea')[0].setAttribute('autofocus', true);
}, 1000);
This obviously didn't work as autofocus only works on ready().
I have also tried to access the textArea inside the autogrow-textarea and even that didn't seem to be working.
Is there a way this can be done?
Thanks in advance.
Here is the code snippet where I am using it.
'click #chatEnter': function(e, template) {
var chatArea = $('#chatArea')[0];
var chatTextArea = $('#chatTextArea')[0];
if(chatTextArea.bindValue)
{
var chatNode = document.createElement('chat-message');
chatNode.setAttribute('color', '#ff00ff');
chatNode.setAttribute('avatar', '/src/someimage.jpg');
chatNode.setAttribute('username', 'SomeName1');
chatNode.setAttribute('text', chatTextArea.bindValue);
chatNode.setAttribute('status',"MyStatus");
chatNode.setAttribute('timestamp',"2015-07-12 12:00:00 AM");
chatArea.appendChild(chatNode);
chatTextArea.bindValue = "";
setTimeout(function() {
$('#chatTextArea')[0].setAttribute('autofocus', true);//.focus();
}, 1000);
}
Here is the HTML where I am using it.
<section main layout vertical id="chat">
<paper-material id="chatArea" elevation="1" animated style="overflow-y:scroll">
</paper-material>
<span layout horizontal>
<paper-toolbar class="medium">
<div>
<iron-autogrow-textarea label="Enter message here" autocomplete="true" autofocus="true" maxRows=5 name="Text Area" id="chatTextArea">
<textarea id="chatText" max-rows="5" ></textarea>
</iron-autogrow-textarea>
</div>
<paper-icon-button raised icon="send" id="chatEnter"></paper-icon-button>
<iron-a11y-keys keys="ctrl+enter" on-keys-pressed="[[enterKeyHandler]]"></iron-a11y-keys>
</paper-toolbar>
</span>
</section>
You don't need to put a textarea tag inside iron-autogrow-textarea. The iron component is providing one. You can then access that inner textarea via .textarea and call focus on it.
Here's a small working example.
<body>
<iron-autogrow-textarea rows="5"></iron-autogrow-textarea>
<button>Focus!</button>
<script>
var button = document.querySelector('button');
button.addEventListener("click", function(){
console.log(document.querySelector('iron-autogrow-textarea'));
var area = document.querySelector('iron-autogrow-textarea');
area.textarea.focus();
});
</script>
</body>
Had a very similar problem - when I navigated the page, the focus didn't return to the paper-textarea the second time I visited. After some looking at the DOM I came to the following solution:
//focus textarea
setTimeout(() => {
//first working solution, line after that a bit more general
// this.$.idOfPaperTextarea.shadowRoot.querySelector('paper-input-container').querySelector('#input-1').shadowRoot.querySelector('#textarea').focus();
this.$.idOfPaperTextarea.shadowRoot.querySelector('iron-autogrow-textarea').shadowRoot.querySelector('textarea').focus();
}, 0);
I guess the problem is that you have to get through the shadowRoots to access the textarea.

Get part of CSS class as string?

Say I had the following 4 divs:
<div class="mine-banana"></div>
<div class="mine-grape"></div>
<div class="mine-apple"></div>
<div class="orange"></div>
I've discovered I can use the following JQuery selector to get the 3 "mine" divs, but I can't quite figure out how to return all the fruits that are "mine" :)
$('[class*=" mine-"]').each(function() {
var fruit = $(this).????
});
DEMO
The best way to accomplish that is to refactor your html, as #Ian pointed it out, for example :
<div class="mine" data-mine-fruit="banana"></div>
<div class="mine" data-mine-fruit="grape"></div>
<div class="mine" data-mine-fruit="apple"></div>
<div class="orange"></div>
The JS code is straightforward now :
var fruits = $('.mine').map(function () {
return $(this).attr('data-mine-fruit')
});
If you still want to use your current code, here is a regex-based code
var fruits = []
$('[class*=" mine-"], [class^="mine-"]').each(function() {
fruits.push( this.className.match(/[^a-z0-9_-]?mine-([0-9a-z_-]+)/i)[1] );
})
which really works

Categories

Resources