I am trying to modify an existing web page which looks like this
<script type="text/javascript" src="s1.js"></script>
s1.js has something like this
window.onDomReady = DomReady;
function DomReady(fn)
{
if(document.addEventListener)
{
document.addEventListener("DOMContentLoaded", fn, false);
}
else
{
document.onreadystatechange = function(){chState(fn);};
}
}
function chState(fn)
{
if(document.readyState == "interactive" || document.readyState == "complete")
fn();
}
window.onDomReady(addHndlrs);
function addHndlrs()
{
var forms = document.getElementsByTagName("form");
for(var i = 0; i < forms.length; i++)
{
var form = forms[i];
if(form.addEventListener)
{
form.addEventListener("submit", DoValidate, false);
}
else if (form.attachEvent)
{
form.attachEvent("onsubmit", DoValidate);
}
Other stuff.
}
When I click Submit on the form, DoValidate does called.
I am trying to modify this page to add another submit handler which is called after the first one.
I copied the above code, changed function names & put into s2.js.
window.onDomReady = DReady;
function DReady(fn)
{
if(document.addEventListener)
{
document.addEventListener("DOMContentLoaded", fn, false);
}
else
{
document.onreadystatechange = function(){Chk1State(fn);};
}
}
function Chk1State(fn)
{
if(document.readyState == "interactive" || document.readyState == "complete")
fn();
}
window.onDomReady(myready);
function myready()
{
var forms = document.getElementsByTagName("form");
for(var i = 0; i < forms.length; i++)
{
var form = forms[i];
if(form.addEventListener)
{
form.addEventListener("submit", mynewhandler, false);
}
else if (form.attachEvent)
{
form.attachEvent("onsubmit", mynewhandler);
}
}
}
In the form html, I added a reference to it
<script type="text/javascript" src="s1.js"></script>
<script type="text/javascript" src="s2.js"></script>
My new submit handler never gets called. I debugged it through firebug - I see DReady being called and my DOM Ready handler being registered. However myready never gets called, so my submit handler never gets registered.
What am I missing here? I tried changing order of inclusion of s1.js and s2.js but that doesn't seem to help. I want to do this without modifying s1.js
The code you provided seems to be fine! Have checked in Chrome 25, FireFox 19 and IE 10!
Normally I find it easier to just modify the code at runtime (not the source file), thanks to JavaScript being dynamic typed, you could overwrite the DoValidate function with your own, passing it the original DoValidate through closure in the s2.js:
var originalValidate = DoValidate;
DoValidate = function () {
originalValidate();
alert("my handler");
};
Related
I have a problem with undefined property
I added the first part of my js I have a document.readystate witch suppose to help with the Dom not reading fills but I still get undefined
if (document.readyState == `loading`) {
document.addEventListener(`DOMContentLoaded`, ready);
} else {
ready
}
function ready() {
var hiddentwo = document.getElementById(`sectiontop`)
var hidden = document.getElementById(`sectionone`)
var hiddentwo = document.getElementById(`sectiontop`)
console.log(hiddentwo)
const openModal = function() {
hidden.classList.remove(`hidesection`);
};
const closeModal = function() {
hidden.classList.add('hidden');
};
const closeModal1 = function() {
hiddentwo.classlist.remove(`hidesection1`)
};
const closeModal11 = function() {
hiddentwo.classlist.add(`hidesection1`)
};
window.onload = function() {
hiddentwo.classlist.remove('hidesection1')
};
};
.hidesection1 {
display: none;
}
<section id="sectiontop" class="hidesection1">
Remove this block in your code:
if (document.readyState == `loading`)
{document.addEventListener(`DOMContentLoaded`,ready);}
else{ready}
and replace it with either
document.addEventListener(`DOMContentLoaded`, ready);
or use the ready state change event (which requires checking the state inside your ready function):
document.addEventListener(`readystatechange`, ready);
// and in ready():
function ready() {
if (document.readyState === 'interactive') {
// your code from ready function body here
}
};
You always use either method, never both.
as #Sebastian Simon and # conexo pointed out hiddentwo.classlist.remove must be hiddentwo.classList.remove. Case matters in Javascript.
I am trying to change href attributes of specific classes onclick. However, the original href never changes.
<a class="vendor" href="https://jsfiddle.net">JSFiddle.net</a>
window.addEventListener("load", fixlinks);
function fixlinks() {
var link_class = document.getElementsByClassName("vendor")
for (var i = 0; i < link_class.length; i++) {
link_class[i].addEventListener("click", makeLinks(link_class[i]));
}
}
function makeLinks(expr) {
//RickRoll 'em
expr.setAttribute("href", "https://www.youtube.com/embed/dQw4w9WgXcQ");
}
//jsfiddle.net/qm9bnvon/5/
The solution is simply to not invoke the function but pass it instead, and use this to reference the bound element in the handler.
Updated DEMO: http://jsfiddle.net/qm9bnvon/11/
window.addEventListener("load",fixlinks);
function fixlinks() {
var link_class = document.getElementsByClassName("vendor")
for(var i = 0; i < link_class.length; i++) { // v----pass it, don't invoke it
link_class[i].addEventListener("click", makeLinks);
}
}
function makeLinks(event) {
// v---`this` refers to the bound element
this.setAttribute("href","https://www.youtube.com/embed/dQw4w9WgXcQ");
}
If the document.readyState property is complete then the onload handler will not fire. (This at least is the case for jsfiddle, which you linked in your question).
So you need to check for both cases:
if(document.readyState === "complete") {
fixlinks();
} else {
window.addEventListener("load",fixlinks);
}
The next issue is that you are not setting a callback in your click listener.
Because makeLinks doesn't return a function for the click handler to invoke:
function fixlinks() {
var link_class = document.getElementsByClassName("vendor")
for(var i = 0; i < link_class.length; i++) {
link_class[i].addEventListener("click",makeLinks(link_class[i]));
}
}
// here we return the callback
function makeLinks(expr) {
//RickRoll 'em
return function() {
expr.setAttribute("href","https://www.youtube.com/embed/dQw4w9WgXcQ");
};
}
I'm trying to allow code highlighting using SyntaxHighlighter on a sharepoint 2013 blog site (office365 portal).
Here is the code I have put in the head of the masterpage (js and css ressources are loaded before) :
<script type="text/javascript">
function sh(){
SyntaxHighlighter.highlight();
};
// executed when SP load completes
_spBodyOnLoadFunctionNames.push("sh");
</script>
The _spBodyOnLoadFunctionNames should provide a mechanism to run functions after the load page event, but it seems it's never executed.
Running my sh function from the developper tool (console) is working as expected.
Does anybody have a clue, am I using the right event ?
_spBodyOnLoadFunctionNames array declared in init.js (it is a part of SharePoint JavaScript Library)
According to init.js:
AttachEvent("DOMContentLoaded", _spBodyOnLoadWrapper, document);
window.onload = _spBodyOnLoadWrapper;
where
function _spBodyOnLoadWrapper() {
ExecuteOrDelayUntilScriptLoaded(ProcessDefaultOnLoad, "core.js");
//the remaining code is omitted for clarity..
}
function ProcessDefaultOnLoad() {
ProcessOnLoadFunctionNames(_spBodyOnLoadFunctionNames);
//the remaining code is omitted for clarity..
}
function ProcessOnLoadFunctionNames(onLoadFunctionNames) {
if (onLoadFunctionNames != null) {
for (var i = 0; i < onLoadFunctionNames.length; i++) {
var expr = "if(typeof(" + onLoadFunctionNames[i] + ")=='function'){" + onLoadFunctionNames[i] + "();}";
eval(expr);
}
onLoadFunctionNames = [];
}
}
To summarize, the specified approach is a proper mechanism to run functions after the load page event.
In fact it works for me just fine (see the picture below)
Make sure init.js library is loaded before _spBodyOnLoadFunctionNames is initialized.
Alternatively you could try the following approach:
<script type="text/javascript">
function sh(){
SyntaxHighlighter.highlight();
};
ExecuteOrDelayUntilScriptLoaded(sh, "core.js");
</script>
Results
+Vadim Gremyachev's answer is valid with IE, but doesnt work with chrome, here is the workaround I've used (inspirated from https://stackoverflow.com/a/2956980/381149 ):
function sh(){
SyntaxHighlighter.highlight();
};
function setIntervalX(callback, delay, repetitions) {
var x = 0;
var intervalID = window.setInterval(function () {
callback();
if (++x === repetitions) {
window.clearInterval(intervalID);
}
}, delay);
}
$(document).ready(function () {
if( $('.syntaxhighlighter').length == 0 ){
setIntervalX(function() { sh() }, 1000,5);
}
$("a").on("click",function () {
if( $('.syntaxhighlighter').length == 0 ){
setIntervalX(function() {
sh()
}, 1000,5);
}
return true;
});
});
I use a Greasemonkey script in Firefox to intercept a submit process in order to modify a certain post variable. I save the old submit routine to call it later and overwrite HTMLFormElement.prototype.submit with my interception (modification) function.
The problem I am currently facing is that something drops the post variable post=Submit and calling the (old) submit function after the modification takes me back to the current page.
var intercept_complete = false;
window.addEventListener('submit', function (e) {
e.stopPropagation();
e.preventDefault();
interceptor(e);
}, true);
function interceptor_setup() {
HTMLFormElement.prototype.real_submit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = interceptor;
}
function interceptor(e) {
var frm = e ? e.target : this;
if (!interceptor_onsubmit(frm)) {
return false;
}
if (!intercept_complete) {
ModifyAndPost(frm);
return false;
} else {
HTMLFormElement.prototype.real_submit.apply(frm);
return true;
}
}
function interceptor_onsubmit(f) {
return !f.onsubmit || f.onsubmit();
}
function ModifyAndPost(f) {
var attrs = new Array('name', 'type', 'value');
for (var i = 0; i < f.elements.length; i++) {
for (var a = 0; a < attrs.length; a++) {
if (attrs[a] == 'name') {
if (f.elements[i][attrs[a]] == "message") {
var current_message = f.elements[i][attrs[a + 2]];
if (current_message.indexOf("hello") != -1) {
var do_replace = confirm("Detected hello, would you like to replace that with bye?");
if (do_replace) {
f.elements[i][attrs[a + 2]] = current_message.replace("hello", "bye");
}
}
}
}
}
}
PerformSubmit(f);
}
function PerformSubmit(f) {
HTMLFormElement.prototype.real_submit.apply(f);
}
interceptor_setup();
Basically the script works and modifies the post variables successfully but when calling HTMLFormElement.prototype.real_submit.apply(f); to submit the modified form the request is missing the Post=Submit variable and the submit fails.
I tried removing e.stopPropagation() and e.preventDefault() and then it worked sometimes, but still dropped that post variable once in a while.
Would be great if anyone could point me in the right direction on this one. ;)
I am trying to write a onbeforeunload event that triggers a window.open(url) etc. I want it to be triggered if the user trys to leave the page or if they close their browser, but not when they click any of the buttons on the page. The buttons on the page post data to the same page via a javascript.
javascript:
window.onbeforeunload = doSync;
function doSync(){
if(doSync == true){
//do sync via popup
window.open("http://mydomain.com/page.php?var=<?php=sync_var?>", "Synchronizing cluster....", "location=0,menubar=0,statusbar=1,width=10,height=10");
}
else {
//somehow do nothing and allow user to leave
}
}
-->
</script>
The buttons calls a javascript function that creates a form and submits it. In that javascript function I set the global variable of doSync = false. I'll include the basic code of this function just to illustrate it.
function buttonPush(){
var form = document.createElement('form');
form.setAttribute('method' bla bla
//before submit set dosync to false
doSync = false;
form.submit();
}
right now I am getting a Not Implemented error on the window.onbeforeunload = doSync; statement.
Any help would be appreciated.
Thanks,
Jim
Is there something wrong with my window.open? if i do a window.open('','','height=100,width=100');
it opens fine but this below does not.
window.open('https://mydomain.com/support/sync_cluster.php?sync_cluster=mycluster','Synchronizing...', 'toolbar=0,scrollbars=0,location=0,statusbar=1,menubar=0,resizable=0,width=100,height=100');
doSync is a function, not a boolean; just create a variable and set it appropriately:
var sync = true;
window.onbeforeunload = doSync;
function doSync() {
if (sync == true) {
//do sync via popup
window.open("http://mydomain.com/page.php?var=<?php=sync_var?>", "Synchronizing cluster....", "location=0,menubar=0,statusbar=1,width=10,height=10");
}
else {
//somehow do nothing and allow user to leave
return;
}
}
function buttonPush(){
var form = document.createElement('form');
// form.setAttribute('method' bla bla
//before submit set dosync to false
sync = false;
form.submit();
}
Try this:
var vals = 0;
function displayMsg() {
window.onbeforeunload = null;
window.location = "https://www.google.com";
}
window.onbeforeunload = function evens(evt) {
var message = 'Please Stay on this page and we will show you a secret text.';
if (typeof evt == 'undefined') {
evt = window.event;
}
timedCount();
vals++;
if (evt) {
evt.returnValue = message;
return message;
}
trace(evt);
}
function timedCount() {
t = setTimeout("timedCount()", 500);
if (vals > 0) {
displayMsg();
clearTimeout(t);
}
}
$(document).ready(function() {
$('a,input,button').attr('onClick', 'window.onbeforeunload = null;')
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Leave