【发布时间】:2020-12-07 18:50:57
【问题描述】:
我有这个我称之为 cookiebar.js 的 javascript,它显示了一个 cookie 的粘性栏消息,(source code)
(function (context) {
"use strict";
var win = context,
doc = win.document;
var global_instance_name = "cbinstance";
function contentLoaded(win, fn) {
var done = false,
top = true,
doc = win.document,
root = doc.documentElement,
add = doc.addEventListener ? "addEventListener" : "attachEvent",
rem = doc.addEventListener ? "removeEventListener" : "detachEvent",
pre = doc.addEventListener ? "" : "on",
init = function (e) {
if (e.type == "readystatechange" && doc.readyState != "complete") return;
(e.type == "load" ? win : doc)[rem](pre + e.type, init, false);
if (!done && (done = true)) fn.call(win, e.type || e);
},
poll = function () {
try {
root.doScroll("left");
} catch (e) {
setTimeout(poll, 50);
return;
}
init("poll");
};
if (doc.readyState == "complete") fn.call(win, "lazy");
else {
if (doc.createEventObject && root.doScroll) {
try {
top = !win.frameElement;
} catch (e) {}
if (top) poll();
}
doc[add](pre + "DOMContentLoaded", init, false);
doc[add](pre + "readystatechange", init, false);
win[add](pre + "load", init, false);
}
}
var Cookies = {
get: function (key) {
return decodeURIComponent(doc.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
},
set: function (key, val, end, path, domain, secure) {
if (!key || /^(?:expires|max\-age|path|domain|secure)$/i.test(key)) {
return false;
}
var expires = "";
if (end) {
switch (end.constructor) {
case Number:
expires = end === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + end;
break;
case String:
expires = "; expires=" + end;
break;
case Date:
expires = "; expires=" + end.toUTCString();
break;
}
}
doc.cookie = encodeURIComponent(key) + "=" + encodeURIComponent(val) + expires + (domain ? "; domain=" + domain : "") + (path ? "; path=" + path : "") + (secure ? "; secure" : "");
return true;
},
has: function (key) {
return new RegExp("(?:^|;\\s*)" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=").test(doc.cookie);
},
remove: function (key, path, domain) {
if (!key || !this.has(key)) {
return false;
}
doc.cookie = encodeURIComponent(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (domain ? "; domain=" + domain : "") + (path ? "; path=" + path : "");
return true;
},
};
var Utils = {
merge: function () {
var obj = {},
i = 0,
al = arguments.length,
key;
if (0 === al) {
return obj;
}
for (; i < al; i++) {
for (key in arguments[i]) {
if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
obj[key] = arguments[i][key];
}
}
}
return obj;
},
str2bool: function (str) {
str = "" + str;
switch (str.toLowerCase()) {
case "false":
case "no":
case "0":
case "":
return false;
default:
return true;
}
},
fade_in: function (el) {
if (el.style.opacity < 1) {
el.style.opacity = (parseFloat(el.style.opacity) + 0.05).toFixed(2);
win.setTimeout(function () {
Utils.fade_in(el);
}, 50);
}
},
get_data_attribs: function (script) {
var data = {};
if (Object.prototype.hasOwnProperty.call(script, "dataset")) {
data = script.dataset;
} else {
var attribs = script.attributes;
var key;
for (key in attribs) {
if (Object.prototype.hasOwnProperty.call(attribs, key)) {
var attr = attribs[key];
if (/^data-/.test(attr.name)) {
var camelized = Utils.camelize(attr.name.substr(5));
data[camelized] = attr.value;
}
}
}
}
return data;
},
normalize_keys: function (options_object) {
var camelized = {};
for (var key in options_object) {
if (Object.prototype.hasOwnProperty.call(options_object, key)) {
var camelized_key = Utils.camelize(key);
camelized[camelized_key] = options_object[camelized_key] ? options_object[camelized_key] : options_object[key];
}
}
return camelized;
},
camelize: function (str) {
var separator = "-",
match = str.indexOf(separator);
while (match != -1) {
var last = match === str.length - 1,
next = last ? "" : str[match + 1],
upnext = next.toUpperCase(),
sep_substr = last ? separator : separator + next;
str = str.replace(sep_substr, upnext);
match = str.indexOf(separator);
}
return str;
},
find_script_by_id: function (id) {
var scripts = doc.getElementsByTagName("script");
for (var i = 0, l = scripts.length; i < l; i++) {
if (id === scripts[i].id) {
return scripts[i];
}
}
return null;
},
};
var script_el_invoker = Utils.find_script_by_id("cookiebanner");
var Cookiebanner = (context.Cookiebanner = function (opts) {
this.init(opts);
});
Cookiebanner.prototype = {
cookiejar: Cookies,
init: function (opts) {
this.inserted = false;
this.closed = false;
this.test_mode = false;
var default_text = "This site uses cookies.";
var default_link = "Detail";
this.default_options = {
cookie: "cookiebanner-accepted",
closeText: "✖",
cookiePath: "/",
debug: false,
expires: Infinity,
zindex: 255,
mask: false,
maskOpacity: 0.5,
maskBackground: "#000",
height: "auto",
minHeight: "21px",
bg: "#000",
fg: "#ddd",
link: "#aaa",
position: "bottom",
message: default_text,
linkmsg: default_link,
moreinfo: "http://www.examplesite123.com/cookie-policy/",
effect: null,
fontSize: "14px",
fontFamily: "arial, sans-serif",
instance: global_instance_name,
textAlign: "center",
acceptOnScroll: true,
};
this.options = this.default_options;
this.script_el = script_el_invoker;
if (this.script_el) {
var data_options = Utils.get_data_attribs(this.script_el);
this.options = Utils.merge(this.options, data_options);
}
if (opts) {
opts = Utils.normalize_keys(opts);
this.options = Utils.merge(this.options, opts);
}
global_instance_name = this.options.instance;
this.options.zindex = parseInt(this.options.zindex, 10);
this.options.mask = Utils.str2bool(this.options.mask);
if ("string" === typeof this.options.expires) {
if ("function" === typeof context[this.options.expires]) {
this.options.expires = context[this.options.expires];
}
}
if ("function" === typeof this.options.expires) {
this.options.expires = this.options.expires();
}
if (this.script_el) {
this.run();
}
},
log: function () {
if ("undefined" !== typeof console) {
console.log.apply(console, arguments);
}
},
run: function () {
if (!this.agreed()) {
var self = this;
contentLoaded(win, function () {
self.insert();
});
}
},
build_viewport_mask: function () {
var mask = null;
if (true === this.options.mask) {
var mask_opacity = this.options.maskOpacity;
var bg = this.options.maskBackground;
var mask_markup =
'<div id="cookiebanner-mask" style="' +
"position:fixed;top:0;left:0;width:100%;height:100%;" +
"background:" +
bg +
";zoom:1;filter:alpha(opacity=" +
mask_opacity * 100 +
");opacity:" +
mask_opacity +
";" +
"z-index:" +
this.options.zindex +
';"></div>';
var el = doc.createElement("div");
el.innerHTML = mask_markup;
mask = el.firstChild;
}
return mask;
},
agree: function () {
this.cookiejar.set(this.options.cookie, 1, this.options.expires, this.options.cookiePath);
return true;
},
agreed: function () {
return this.cookiejar.has(this.options.cookie);
},
close: function () {
if (this.inserted) {
if (!this.closed) {
if (this.element) {
this.element.parentNode.removeChild(this.element);
}
if (this.element_mask) {
this.element_mask.parentNode.removeChild(this.element_mask);
}
this.closed = true;
}
}
return this.closed;
},
agree_and_close: function () {
this.agree();
return this.close();
},
cleanup: function () {
this.close();
return this.unload();
},
unload: function () {
if (this.script_el) {
this.script_el.parentNode.removeChild(this.script_el);
}
context[global_instance_name] = undefined;
return true;
},
insert: function () {
this.element_mask = this.build_viewport_mask();
var zidx = this.options.zindex;
if (this.element_mask) {
zidx += 1;
}
var el = doc.createElement("div");
el.className = "cookiebanner";
el.style.position = "fixed";
el.style.left = 0;
el.style.right = 0;
el.style.height = this.options.height;
el.style.minHeight = this.options.minHeight;
el.style.zIndex = zidx;
el.style.background = this.options.bg;
el.style.color = this.options.fg;
el.style.lineHeight = el.style.minHeight;
el.style.padding = "5px 16px";
el.style.fontFamily = this.options.fontFamily;
el.style.fontSize = this.options.fontSize;
el.style.textAlign = this.options.textAlign;
if ("top" === this.options.position) {
el.style.top = 0;
} else {
el.style.bottom = 0;
}
el.innerHTML = '<div class="cookiebanner-close" style="float:right;padding-left:5px;">' + this.options.closeText + "</div>" + "<span>" + this.options.message + " <a>" + this.options.linkmsg + "</a></span>";
this.element = el;
var el_a = el.getElementsByTagName("a")[0];
el_a.href = this.options.moreinfo;
el_a.target = "_blank";
el_a.style.textDecoration = "none";
el_a.style.color = this.options.link;
var el_x = el.getElementsByTagName("div")[0];
el_x.style.cursor = "pointer";
function on(el, ev, fn) {
var add = el.addEventListener ? "addEventListener" : "attachEvent",
pre = el.addEventListener ? "" : "on";
el[add](pre + ev, fn, false);
}
var self = this;
on(el_x, "click", function () {
self.agree_and_close();
});
if (this.element_mask) {
on(this.element_mask, "click", function () {
self.agree_and_close();
});
doc.body.appendChild(this.element_mask);
}
if (this.options.acceptOnScroll) {
on(window, "scroll", function () {
self.agree_and_close();
});
}
doc.body.appendChild(this.element);
this.inserted = true;
if ("fade" === this.options.effect) {
this.element.style.opacity = 0;
Utils.fade_in(this.element);
} else {
this.element.style.opacity = 1;
}
},
};
if (script_el_invoker) {
if (!context[global_instance_name]) {
context[global_instance_name] = new Cookiebanner();
}
}
})(window);
我在Wordpress的functions.php中以这种方式加载它:
function wpb_hook_javascript() {
?>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/cookiebar.js"></script>
<?php
}
add_action('wp_head', 'wpb_hook_javascript');
效果很好。
现在我复制了相同的 javascript 代码并将其命名为 stickybar.js。我添加了一些修改,还将 class 更改为名称“stickybar”:
stickybar.js的代码是here(我把它粘贴到jsfiddle因为stackoverflow的文本太多了)
然后我只在移动设备上显示第二个栏 (stickybar.js),并在 8 秒后使用这个 CSS:
.stickybar { display: none; }
@media only screen and (max-device-width:480px) {
.stickybar {
display: block;
animation: cssAnimation 0s 8s forwards;
visibility: hidden;
}
@keyframes cssAnimation {
to { visibility: visible; }
}
}
我用functions.php中的代码将它加载到Wordpress中:
function wpb_hook_javascript() {
?>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/stickybar.js"></script>
<?php
}
add_action('wp_head', 'wpb_hook_javascript');
效果很好。
如果我一一加载这些代码,它们就可以正常工作。
问题是当我在functions.php中以这种方式加载两个脚本时,只有第一个有效:
function wpb_hook_javascript() {
?>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/cookiebar.js"></script>
<script defer type="text/javascript" id="cookiebanner" src="https://www.examplesite123.com/stickybar.js"></script>
<?php
}
add_action('wp_head', 'wpb_hook_javascript');
如何将两个脚本一起加载?
【问题讨论】:
-
每个脚本都需要一个不同的“全局实例名称”。
-
HTML 中的 ID 属性应该是唯一的 - 只允许出现一次。
-
查看
find_script_by_id在这两个函数中寻找相同的ID。但是,您不能在同一页面上重复使用 ID。因此,将stickybar 中的那个更改为stickybar 然后在wpb_hook_javascript中将stickybar 文件的ID 更改为stickybar。同样在stickbar文件中将global_instance_name中的实例名称更改为独特的名称,可能是sbinstance -
谢谢!有用!我遵循@imvain2 的说明。我也尝试将两个脚本放在一个脚本中,但是我应该如何更改functions.php中的代码?在这种情况下,我“需要调用” id="cookiebanner" 和 id="stickybar" 从一个 js 文件中。我该怎么做?
标签: javascript wordpress sticky