I looked at the other solutions on SO for this problem and none of them seem to help my case. To give you some background, yesterday I was trying to select all DIVs by a class and store their IDs. See this Now that I have the IDs I want to create some new elements and incorporate the IDs and be able to click on these new elements. I went to JSFiddle to show you a demo but the crazy part is over there, my code works, yet in my app (Chrome extension) it doesn't. What's even crazier is that I'm already implementing jQuery click events in other parts of it without a problem so I'm really confused why it's not working in this particular case. Here's the JSFiddle that works but in my app it doesn't do anything on click. Thanks for any help! I'm sorry for posting so many (silly) questions.
HTML:
<div class="HA" id="k2348382383838382133"></div>
<div class="HA" id="k2344444444444444444"></div>
<div class="HA" id="k234543544545454454"></div>
<div class="HA" id="k2346787878778787878"></div>
JS:
var HAContainer = document.querySelectorAll('.HA');
var HALength = document.querySelectorAll('.HA').length;
var id = [];
var j = 0;
$('.HA').each(function(){
id[j++] = $(this).attr('id');
});
for (var i=0; i<HALength; i++) {
var HABtn, HABtnImg, HAImgContainer;
HABtnImg = document.createElement("img");
HABtnImg.src = ("http://www.freesmileys.org/smileys/smiley-laughing002.gif");
HABtnImg.className = "ha-icon";
HAImgContainer = document.createElement("div");
HAImgContainer.setAttribute("id", 'HA-'+id[i] + '-container');
HAImgContainer.appendChild(HABtnImg);
HABtn = document.createElement("div");
HABtn.className = 'ha-button';
HABtn.setAttribute("id", 'HA-container');
HABtn.appendChild(HAImgContainer);
HAContainer[i].appendChild(HABtn);
HAClick(id[i]);
}
function HAClick(id) {
$('#HA-'+id+'-container').click(function() {
alert("clicked on ID " + id);
});
}
You have to delegate your event in order to make it work with dinamically added elements:
$('body').on("click", '#HA-'+id+'-container', function() {
alert("clicked on ID " + id);
});
I've noticed something and will edit with a better approach:
Change:
HABtn.setAttribute("id", 'HA-container');
To:
HABtn.setAttribute("id", 'HA-'+id[i] + '-inner-container');
HABtn.setAttribute("class", 'HA-container');
And instead of:
function HAClick(id) {
$('#HA-'+id+'-container').click(function() {
alert("clicked on ID " + id);
});
}
simply attach once the event with delegation:
$('body').on("click", '.HA-container', function() {
alert("clicked on ID " + $(this).attr('id'));
});
jsFiddle implicitly selects the javascript you use to be placed inside of an onload event handler.
As a result your code is wrapped with the onload event handler and basically looks likes this
window.onload = function(){
//your code here
};
The reason it works in jsFiddle is because the script is executing once the DOM is loaded and thus can interact with the elements as they are in the DOM. It is possible that your chrome extension is not acting after the elements have been loaded.
It would be prudent to wrap your javascript in the document.ready shortcut
$(function(){
//your code here
});
Given that, there are still some issues which exist in your code. It is not clear why you need to have that nested div structure, perhaps as a result of css styling, but one issue is the duplication of ids. They could probably just be class names (I am referencing "HA-container").
jQuery offers a very easy way to create elements in the constructor that you can take advantage of here. It will allow your code to be more streamlined and readable.
Further, you can store the id you use inside of the container element's jquery object reference for data using .data('id',value). This will all you to also assign the click event handler immediately inside of using another function to assign it.
jsFiddle Demo
$('.HA').each(function(){
var btn = $('<div class="ha-button HA-container">');
var cont = $('<div id="'+this.id+'-container">').data('id',this.id);
cont.click(function(){ alert("clicked on ID " + $(this).data('id')); });
var img = $('<img src="http://www.freesmileys.org/smileys/smiley-laughing002.gif" class="ha-icon" />');
$(this).append(btn.append(cont.append(img)));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="HA" id="k2348382383838382133"></div>
<div class="HA" id="k2344444444444444444"></div>
<div class="HA" id="k234543544545454454"></div>
<div class="HA" id="k2346787878778787878"></div>
I'd re-write it a bit to take advantage of jQuery:
for (var i=0; i<HALength; i++) {
var HABtnImg = $('<img/>')
.attr('src', 'http://www.freesmileys.org/smileys/smiley-laughing002.gif')
.addClass('ha-icon');
var HAImgContainer = $('<div/>')
.attr('id', 'HA-'+id[i] + '-container')
.append(HABtnImg);
var HABtn = $('<div/>')
.addClass('ha-button')
.append(HAImgContainer);
//don't use duplicate ID's here
$(HAContainer[i]).append(HABtn);
}
And later attach the event like so:
$(document).on('click', '.ha-button', function(e){
//your click code here
var id = $(this).find('div').attr('id');
alert("clicked on ID " + id);
});
Related
I've viewed a couple of the posts in here regarding this topic but not quite working for my situation. I'm using Tampermonkey userscript manager. I want to hide a bunch of div's after the page is fully loaded. I've tested the code below on the console of the page and it works.
document.getElementsByClassName('promotions-personalized-offers-ui-single-offer')[0].style.display='none';
This alert also works with the Tampermonkey userscript manager.
window.addEventListener("load", function(){
// code goes below
alert("hello world");
});
However, the following code is not working. Neither the div or the alert is working in this situation.
window.addEventListener("load", function(){
// ....
document.getElementsByClassName('promotions-personalized-offers-ui-single-offer')[0].style.display='none';
alert("it's working");
});
By the way, I'm a newbie to Javascript so any help is much appreciated.
You currently only hide the first ([0]) div. You need to iterate over all elements to hide them.
I'd suggest using document.querySelectorAll because it's easily iterable:
window.addEventListener("load", function(){
document.querySelectorAll('promotions-personalized-offers-ui-single-offer')
.forEach(e => (e.style.display = 'none'));
});
If you must stick to getElementsByClassName, a spread should do the trick:
window.addEventListener("load", function(){
[...document.getElementsByClassName('promotions-personalized-offers-ui-single-offer')]
.forEach(e => (e.style.display = 'none'));
});
Try this:
var x = 3 //number of div elements to remove
window.onload = function() {
for (var i = 0; i < x; i++) {
var elementid = "div" + i.toString(); //ends up as "div1" or "div3"
var div = document.getElementById(elementid)
document.body.remove(div);
}
The divs would need to look like this:
<div id="div1">Content</div>
<div id="div2">Content</div>
<div id="div3">Content</div>
Alternatively, if you're putting the JavaScript code inside a function that's called after the page loads fully, you can just use this:
var x = 3 //number of div elements to remove
function removeDivs() {
for (var i = 0; i < x; i++) {
var elementid = "div" + i.toString(); //ends up as "div1" or "div3"
var div = document.getElementById(elementid)
document.body.remove(div);
}
Then call the function by using removeDivs().
Tampermonkey by default runs when the DOMContentLoaded event is dispatched. https://www.tampermonkey.net/documentation.php#_run_at Based on what you have posted it does not look like you need the event listener at all. Your script would only need one line.
document.getElementsByClassName('promotions-personalized-offers-ui-single-offer')[0].style.display='none';
What i'm trying to do
Bring in a selection of html elements from an external html (on the same domain) into a variable in jquery (working)
for each of the element items, wrap them (not working)
prepend that variable to a ul in my page (working)
I have the following code that at this point, works, however it just dumps the elements (el) onto the page in one large list item, not each line on its own
$(document).ready(function() {
var $div = $('<li>');
$div.load('pages.html .el', function(){
$("#my-menu ul.toc").prepend($div);
});
});
I've tried a weird selection of wrapall, etc, but can't seem to crack this.
Would really appreciate any help. Thanks
You need to loop through the elements once they've been loaded from the external html. Something like this (untested code) might work:
$(document).ready(function() {
var $div = $('<div></div>');
var $ul = $('#my-menu ul.toc');
$div.load('pages.html .el', function(){
$div.children().each(function() {
$ul.prepend($('<li>' + $(this) + '</li>'));
});
});
});
If the prepend to the ul doesn't work in one line, it might work if you separate it:
var $li = $('<li></li>');
$li.html(this);
$ul.prepend($li);
I could not say anything without seeing the code, but you can try this one,
$(document).ready(function() {
var $div = $('<li>');
$div.load('pages.html .el', function(){
$("#my-menu ul.toc").insertBefore($div);
});
});
Try and load the html in a hidden div..
$("<div id='pagesHtml' style='display: none;'></div>").appendTo("body");
$("#pagesHtml").load(pages.html);
..store the anchors in a variable..
var $anchors = $("#pagesHtml").find(".el");
..then make a LI for each anchor..
$.each($anchors, function(i, anchor){
$("<li>" + anchor + "</li>").prependTo("#my-menu ul.toc");
});
..and then add that to your container.
If the order is wrong, then you should use ".appendTo" instead.
Happy coding =)
I have got something like this in html
<div class="change"><div>
<div class="change"><div>
<div class="change"><div>
<div class="change"><div>
Now here we go for the java script
var base = document.getElementsByClassName("change");
base[0].setAttribute();
console.log(base[0]);
From the console I can see that I"m getting an object but I can't edit it this way, is there any other possibility to edit/add attributes( i need to add a onclick function to like 100 elements).
It's pretty difficult to get the higer object by document.getElementById,
so... anyone got a solution for this?^^
You can add attributes like this
var element = document.getElementByClassName('change')[0];
element.setAttribute(attributeName,attributeValue);
Just use jQuery. Then it's just a matter of doing something like the following:
$(document).ready(function () {
$('.change').click(function () {
$(this).attr('class', 'new-value');
});
});
JSFiddle demo here.
You can accomplish this using the code below:
var nodes = document.querySelectorAll('.change'),
length = nodes.length,
counter = 0;
for (; counter < length; counter += 1) {
// set an attribute.
nodes[counter].setAttribute('data-test', 'test' + counter);
// add a click event.
nodes[counter].addEventListener('click', function () {
alert('Yep, you clicked me');
}, false);
}
Demo here
Using jQuery:
$('.change').on('click', function() {
// Action
});
Syntax of setAttributte:
Object.setAttributte(attribute, value);
i have one question regarding creation of divs:
I have button, when user clicks on it, javascript (or jquery) needs to create a div. But when user clicks again, it should create another div, but with different id. So, every time user clicks should be created div with different id.
I partialy know how to create div, but i have no idea how to make divs with different id's.
var c = 0; // Counter
$('#add').on('click', function() {
c += 1;
$('#parent').append('<div id="child'+ c +'">'+ c +'</div>');
});
#child1{color:red;}
#child2{color:blue;}
#child3{color:orange;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="add">ADD</button>
<div id="parent"></div>
var divcount = 1;
$('button').click(function(){
$('<div/>', { id:'comment'+divcount++ })
});
Here's a random ID generator for you.
function createParanoidID() {
return 'id_' + Math.floor(Math.random() * 9e99).toString(36);
}
createParanoidID(); // id_1js7ogi93ixt6x29w9svozegzhal67opdt3l3cf1iqidvgazlyaeh1ha7a74bswsg
createParanoidID(); // id_1fleq6chguuyyljhy39x3g7mg661mg845oj8fphnxgvm0bdgz7t3w0q01jptogvls
createParanoidID(); // id_ajz1ft17ml4eyz08gd3thcvq3fx1ycr927i0h2zgyw8bzq9wurv1gdfogly8tbls
Using a variable as counter and the "attr" function to set the id attribute.
HTML
<button id="button">Create Div</button>
<div class="container"></div>
jQuery:
$('#button').on('click', function() {
var count = $('div.container div').length,
id = count + Math.floor(Math.random() * 100);
$('div.container').append('<div id="'+ id+'">ID of this div is: '+ id +' </div>');
});
DEMO
Here's the easy way to do this.
Firstly, you'll need a button:
<button id="onClickOfThisButtonAnewDivWithArandomIDwillBeInserted"></button>
Then the javascript:
$("#onClickOfThisButtonAnewDivWithArandomIDwillBeInserted").on('click', function() {
var myID = 'randomIDnumber_'+Math.random()+Math.random()+Math.random()+Math.random()+Math.random()+Math.random();
var MyNewElement = document.createElement('div');
MyNewElement.id = myID.replace(/\./g, '');
$(MyNewElement).appendTo('body');
});
Here's a FIDDLE
If you don't want to use global counter like in previous answers you can always get number of children and use that as relative value from which you will create another id.
Something like this (with jQuery):
function add_another_div() {
var wrap_div = document.getElementById("#id_of_div_who_contain_all_childrens");
var already_childs = $("#id_of_div_who_contain_all_childrens").children().length;
var div = document.createElement('div');
var divIdName = 'new_div-'+ (already_childs+1);
div.setAttribute('id', divIdName);
wrap_div.appendChild(div);
}
Of course, this requires for all of your children to have same parent (same wrapper). If that is not the case, and they are separated across multiple wrappers, then just use unique class name for all of them, and count them like that. I found this approach much better and easier instead of using global counters which I need to take care about.
How can I wrap every element belonging to a particular class with a link that is built from the text inside the div? What I mean is that I would like to turn:
<foo class="my-class>sometext</foo>
into
<a href="path/sometext" ><foo class="my-class>sometext</foo></a>
Url encoding characters would also be nice, but can be ignored for now if necessary.
EDIT: Just to clarify, the path depends on the text within the element
Use jQuery.wrap() for the simple case:
$(".my-class").wrap("<a href='path/sometext'></a>");
To process text inside:
$(".my-class").each(function() {
var txt = $(this).text();
var link = $("<a></a>").attr("href", "path/" + txt);
$(this).wrap(link[0]);
});
$(".my-class").each(function(){
var thisText = $(this).text();
$(this).wrap("<a></a>").attr("href","path/"+thisText);
});
you can wrap them inside anchor element like this:
$(document).ready(function(){
$(".my-class").each(function(){
var hr="path/"+$(this).text();
$(this).wrap("<a href='"+hr+"'></a>");
});
});
if you are opening links in same page itself then easier way than modifying dom to wrap elements inside anchor is to define css for the elements so that they look like links then handle click event:
$(".my-class").click(function(){
window.location.href="path/"+$(this).text();
});
$("foo.my-class").each(function(){
var foo = $(this);
foo.wrap("<a href='path/" + foo.Text() +"'>");
});
This ought to do it:
$('foo.my-class').each(function() {
var element = $(this);
var text = element.html(); // or .text() or .val()
element.wrap('');
});